Ticket #8206: stream_flv.pl.diff
File stream_flv.pl.diff, 5.8 KB (added by , 13 years ago) |
---|
-
/var/www/mythweb/modules/stream/stream_flv.pl
old new 2 2 # 3 3 # MythWeb Streaming/Download module 4 4 # 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 $ 9 9 # 10 10 11 11 use Math::Round qw(round_even); … … 38 38 # Load some conversion settings from the database 39 39 $sh = $dbh->prepare('SELECT data FROM settings WHERE value=? AND hostname IS NULL'); 40 40 $sh->execute('WebFLV_w'); 41 my ($width) = $sh->fetchrow_array;41 my ($width) = $sh->fetchrow_array; 42 42 $sh->execute('WebFLV_vb'); 43 43 my ($vbitrate) = $sh->fetchrow_array; 44 44 $sh->execute('WebFLV_ab'); 45 45 my ($abitrate) = $sh->fetchrow_array; 46 46 $sh->finish(); 47 47 48 # auto-detect height based on aspect ratio 48 49 $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? AND starttime=FROM_UNIXTIME(?) AND data IS NOT NULL ORDER BY data DESC'); 49 50 $sh->execute($chanid,$starttime); … … 57 58 } 58 59 $sh->finish(); 59 60 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); 62 63 $vbitrate = 256 unless ($vbitrate && $vbitrate > 1); 63 $abitrate = 64 unless ($abitrate && $abitrate > 1); 64 $abitrate = 64 unless ($abitrate && $abitrate > 1); 65 64 66 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 66 109 .' -y' 67 .' -i '.shell_escape($filename)110 .' -i pipe:0' 68 111 .' -s '.shell_escape("${width}x${height}") 69 112 .' -g 30' 70 .' -r 24' 113 .' -r 15' 114 .' -qmin 8' 115 .' -qmax 15' 71 116 .' -f flv' 72 117 .' -deinterlace' 73 118 .' -ac 2' 74 .' -ar 11025'119 .' -ar 22050' 75 120 .' -ab '.shell_escape("${abitrate}k") 76 121 .' -b '.shell_escape("${vbitrate}k") 77 122 .' /dev/stdout 2>/dev/null |'; 78 123 124 warn("Command to be used is: ".$ffmpeg_command); 125 79 126 # Print the movie 80 127 $ffmpeg_pid = open(DATA, $ffmpeg_command); 128 warn("PID is: ".$ffmpeg_pid); 81 129 unless ($ffmpeg_pid) { 82 130 print header(), 83 131 "Can't do ffmpeg: $!\n${ffmpeg_command}"; 84 132 exit; 85 133 } 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 87 159 my $buffer; 88 while (read DATA, $buffer, 262144) {160 if (read DATA, $buffer, 53) { 89 161 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 90 169 } 91 170 close DATA; 92 171