App-MHFS

 view release on metacpan or  search on metacpan

lib/MHFS/Plugin/GetVideo.pm  view on Meta::CPAN

            $request->Send404;
            return undef;
        }

        $video{'out_base'} = $video{'src_file'}{'name'};

        # soon https://github.com/video-dev/hls.js/pull/1899
        $video{'out_base'} = space2us($video{'out_base'}) if ($video{'out_fmt'} eq 'hls');
    }
    elsif($videoformats->{$video{'out_fmt'}}{'plugin'}) {
        $video{'plugin'} = $videoformats->{$video{'out_fmt'}}{'plugin'};
        if(!($video{'out_base'} = $video{'plugin'}->getOutBase($qs))) {
            $request->Send404;
            return undef;
        }
    }
    else {
        $request->Send404;
        return undef;
    }

    # Determine the full path to the desired file
    my $fmt = $video{'out_fmt'};
    $video{'out_location'} = $settings->{'VIDEO_TMPDIR'} . '/' . $video{'out_base'};
    $video{'out_filepath'} = $video{'out_location'} . '/' . $video{'out_base'} . '.' . $videoformats->{$video{'out_fmt'}}{'ext'};
    $video{'out_location_url'} = 'get_video?'.$settings->{VIDEO_TMPDIR_QS}.'&fmt=noconv&name='.$video{'out_base'}.'%2F';

    # Serve it up if it has been created
    if(-e $video{'out_filepath'}) {
        say $video{'out_filepath'} . " already exists";
        $request->SendFile($video{'out_filepath'});
        return 1;
    }
    # otherwise create it
    mkdir($video{'out_location'});
    if(($videoformats->{$fmt}{'lock'} == 1) && (LOCK_WRITE($video{'out_filepath'}) != 1)) {
        say "FAILED to LOCK";
        # we should do something here
    }
    if($video{'plugin'}) {
        $video{'plugin'}->downloadAndServe($request, \%video);
        return 1;
    }
    elsif(defined($videoformats->{$fmt}{'create_cmd'})) {
        my @cmd = @{$videoformats->{$fmt}{'create_cmd'}->(\%video)};
        print "$_ " foreach @cmd;
        print "\n";

        video_on_streams(\%video, $request, sub {
        #say "there should be no pids around";
        #$request->Send404;
        #return undef;

        if($fmt eq 'hls') {
            $video{'on_exists'} = \&video_hls_write_master_playlist;
        }

        # deprecated
        $video{'pid'} = ASYNC(\&shellcmd_unlock, \@cmd, $video{'out_filepath'});

        # our file isn't ready yet, so create a timer to check the progress and act
        weaken($request); # the only one who should be keeping $request alive is the client
        $request->{'client'}{'server'}{'evp'}->add_timer(0, 0, sub {
            if(! defined $request) {
                say "\$request undef, ignoring CB";
                return undef;
            }
            # test if its ready to send
            while(1) {
                    my $filename = $video{'out_filepath'};
                    if(! -e $filename) {
                        last;
                    }
                    my $minsize = $videoformats->{$fmt}{'minsize'};
                    if(defined($minsize) && ((-s $filename) < $minsize)) {
                        last;
                    }
                    if(defined $video{'on_exists'}) {
                        last if (! $video{'on_exists'}->($settings, \%video));
                    }
                    say "get_video_timer is destructing";
                    $request->SendLocalFile($filename);
                    return undef;
            }
            # 404, if we didn't send yet the process is not running
            if(pid_running($video{'pid'})) {
                return 1;
            }
            say "pid not running: " . $video{'pid'} . " get_video_timer done with 404";
            $request->Send404;
            return undef;
        });
        say "get_video: added timer " . $video{'out_filepath'};
        });
    }
    else {
        say "out_fmt: " . $video{'out_fmt'};
        $request->Send404;
        return undef;
    }
    return 1;
}

sub video_get_format {
    my ($self, $fmt) = @_;

    if(defined($fmt)) {
        # hack for jsmpeg corrupting the url
        $fmt =~ s/\?.+$//;
        if(defined $self->{VIDEOFORMATS}{$fmt}) {
            return $fmt;
        }
    }

    return 'noconv';
}
sub video_hls_write_master_playlist {
    # Rebuilt the master playlist because reasons; YOU ARE TEARING ME APART, FFMPEG!
    my ($settings, $video) = @_;
    my $requestfile = $video->{'out_filepath'};

    # fix the path to the video playlist to be correct
    my $m3ucontent = do {
        try { read_text_file($requestfile) }
        catch ($e) {
            say "$requestfile does not exist or is not UTF-8";
            ''
        }
    };
    my $subm3u;
    my $newm3ucontent = '';
    foreach my $line (split("\n", $m3ucontent)) {
        # master playlist doesn't get written with base url ...
        if($line =~ /^(.+)\.m3u8_v$/) {
            $subm3u = "get_video?".$settings->{VIDEO_TMPDIR_QS}."&fmt=noconv&name=" . uri_escape("$1/$1");
            $line = $subm3u . '.m3u8_v';
        }
        $newm3ucontent .= $line . "\n";
    }

    # Always start at 0, even if we encoded half of the movie
    #$newm3ucontent .= '#EXT-X-START:TIME-OFFSET=0,PRECISE=YES' . "\n";

    # if ffmpeg created a sub include it in the playlist
    ($requestfile =~ /^(.+)\.m3u8$/);
    my $reqsub = "$1_vtt.m3u8";
    if($subm3u && -e $reqsub) {
        $subm3u .= "_vtt.m3u8";
        say "subm3u $subm3u";
        my $default = 'NO';
        my $forced =  'NO';
        foreach my $sub (@{$video->{'subtitle'}}) {
            $default = 'YES' if($sub->{'is_default'});



( run in 0.344 second using v1.01-cache-2.11-cpan-39bf76dae61 )