Ticket #8206: stream_flv.pl.diff

File stream_flv.pl.diff, 5.8 KB (added by David.Whyte@…, 9 years ago)

changes to stream_flv.pl as patch.5

  • /var/www/mythweb/modules/stream/stream_flv.pl

    old new  
    22#
    33# MythWeb Streaming/Download module
    44#
    5 # @url $URL$
    6 # @date $Date$
    7 # @version $Revision$
    8 # @author $Author$
     5# @url       $URL: http://svn.mythtv.org/svn/branches/release-0-23-fixes/mythplugins/mythweb/modules/stream/stream_flv.pl $
     6# @date      $Date: 2009-10-30 00:58:53 +0000 (Fri, 30 Oct 2009) $
     7# @version   $Revision: 22646 $
     8# @author    $Author: kormoc $
    99#
    1010
    1111    use Math::Round qw(round_even);
     
    3838# Load some conversion settings from the database
    3939    $sh = $dbh->prepare('SELECT data FROM settings WHERE value=? AND hostname IS NULL');
    4040    $sh->execute('WebFLV_w');
    41     my ($width) = $sh->fetchrow_array;
     41    my ($width)    = $sh->fetchrow_array;
    4242    $sh->execute('WebFLV_vb');
    4343    my ($vbitrate) = $sh->fetchrow_array;
    4444    $sh->execute('WebFLV_ab');
    4545    my ($abitrate) = $sh->fetchrow_array;
    4646    $sh->finish();
     47
    4748# auto-detect height based on aspect ratio
    4849    $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? AND starttime=FROM_UNIXTIME(?) AND data IS NOT NULL ORDER BY data DESC');
    4950    $sh->execute($chanid,$starttime);
     
    5758    }
    5859    $sh->finish();
    5960
    60     $width = 320 unless ($width && $width > 1);
    61     $height = 240 unless ($height && $height > 1);
     61    $width    = 320 unless ($width    && $width    > 1);
     62    $height   = 240 unless ($height   && $height  > 1);
    6263    $vbitrate = 256 unless ($vbitrate && $vbitrate > 1);
    63     $abitrate = 64 unless ($abitrate && $abitrate > 1);
     64    $abitrate = 64  unless ($abitrate && $abitrate > 1);
     65
    6466
    65     my $ffmpeg_command = $ffmpeg
     67    if ("$ENV{'REQUEST_URI'}" =~ /start\=(\d+)$/i) {
     68            $start = $1; }
     69    else {
     70            $start = 0; }
     71    warn("Specified start time: ".$start);
     72
     73# Are we still recording, and how long should the program be?
     74    $sh = $dbh->prepare('SELECT UNIX_TIMESTAMP(endtime) - UNIX_TIMESTAMP(starttime), endtime-now()
     75                             FROM recorded
     76                             WHERE starttime=FROM_UNIXTIME(?)
     77                               AND recorded.chanid   = ?');
     78    $sh->execute($starttime, $chanid);
     79    our ($lengthSec, $inprogress) = $sh->fetchrow_array();
     80    $sh->finish;
     81
     82# Calculate the offset given the start time
     83    $frameNum = $start * 24;
     84    warn("Looking for frame number: ".$frameNum);
     85    $sh = $dbh->prepare('SELECT count(*), offset
     86                             FROM recordedseek
     87                             WHERE chanid=?
     88                               AND starttime=FROM_UNIXTIME(?)
     89                               AND mark >= ?
     90                               AND mark < ?');
     91    $sh->execute($chanid,$starttime, $frameNum, $frameNum + 12);
     92    our($numRows, $byteOffset) = $sh->fetchrow_array();
     93    $sh->finish();
     94    if ($numRows < 1) {
     95        warn("Got no rows, need to wait for recording to catchup to offset, sleeping");
     96        print header(), "Seeked beyond the file";
     97        exit;
     98    }
     99
     100    warn("Looked up a byte offset of: ".$byteOffset);
     101
     102
     103    my $ffmpeg_command = 'tail -fc +'
     104                        .$byteOffset
     105                        .' '
     106                        .shell_escape($filename)
     107                        .' | '
     108                        .$ffmpeg
    66109                        .' -y'
    67                         .' -i '.shell_escape($filename)
     110                        .' -i pipe:0'
    68111                        .' -s '.shell_escape("${width}x${height}")
    69112                        .' -g 30'
    70                         .' -r 24'
     113                        .' -r 15'
     114                        .' -qmin 8'
     115                        .' -qmax 15'
    71116                        .' -f flv'
    72117                        .' -deinterlace'
    73118                        .' -ac 2'
    74                         .' -ar 11025'
     119                        .' -ar 22050'
    75120                        .' -ab '.shell_escape("${abitrate}k")
    76121                        .' -b '.shell_escape("${vbitrate}k")
    77122                        .' /dev/stdout 2>/dev/null |';
    78123
     124    warn("Command to be used is: ".$ffmpeg_command);
     125
    79126# Print the movie
    80127    $ffmpeg_pid = open(DATA, $ffmpeg_command);
     128    warn("PID is: ".$ffmpeg_pid);
    81129    unless ($ffmpeg_pid) {
    82130        print header(),
    83131                "Can't do ffmpeg: $!\n${ffmpeg_command}";
    84132        exit;
    85133    }
    86     print header(-type => 'video/x-flv');
     134
     135# Guess the filesize based on duration and bitrate. This allows for progressive download behavior
     136    warn("Length in seconds from DB is: ".$lengthSec);
     137    if ($inprogress > 0) {
     138        warn("Recording is in progress");
     139    } else {
     140        warn("Recording is finished");
     141        $dur = `ffmpeg -i $filename 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,//`;   
     142        if ($dur && $dur =~ /\d*:\d*:.*/) {
     143            warn("Accurate duration from ffmpeg is: ".$dur);
     144            @times = split(':',$dur);
     145            $lengthSec = $times[0]*3600+$times[1]*60+$times[2] - $start;
     146        }
     147    }
     148
     149    warn("Using a duration of: ".$lengthSec." seconds");
     150    if ($lengthSec > 0) { #This should always be true since we use the DB runtime.
     151        #Get the content size as a whole interger.
     152        $size = int(1.05*$lengthSec*($vbitrate*1024+$abitrate*1024)/8);
     153        warn("Determined content size is: ".$size);
     154        print header(-type => 'video/x-flv','Content-Length' => $size);
     155    } else {
     156        print header(-type => 'video/x-flv');
     157    }
     158
    87159    my $buffer;
    88     while (read DATA, $buffer, 262144) {
     160    if (read DATA, $buffer, 53) {
    89161        print $buffer;
     162        read DATA, $buffer, 8;
     163        $durPrint = reverse pack("d",$lengthSec);
     164        print $durPrint;
     165        while (read DATA, $buffer, 262144) {
     166            print $buffer;
     167        }
     168
    90169    }
    91170    close DATA;
    92171