| 1 | #!/usr/bin/perl
|
|---|
| 2 | #
|
|---|
| 3 | # MythWeb Streaming/Download module
|
|---|
| 4 | #
|
|---|
| 5 | # @url $URL: http://svn.mythtv.org/svn/tags/release-0-23/mythplugins/mythweb/modules/stream/stream_flv.pl $
|
|---|
| 6 | # @date $Date: 2009-10-29 17:58:53 -0700 (Thu, 29 Oct 2009) $
|
|---|
| 7 | # @version $Revision: 22646 $
|
|---|
| 8 | # @author $Author: kormoc $
|
|---|
| 9 | #
|
|---|
| 10 |
|
|---|
| 11 | use Math::Round qw(nearest_floor);
|
|---|
| 12 |
|
|---|
| 13 | our $ffmpeg_pid;
|
|---|
| 14 |
|
|---|
| 15 | # Shutdown cleanup, of various types
|
|---|
| 16 | $SIG{'TERM'} = \&shutdown_handler;
|
|---|
| 17 | $SIG{'PIPE'} = \&shutdown_handler;
|
|---|
| 18 | END {
|
|---|
| 19 | shutdown_handler();
|
|---|
| 20 | }
|
|---|
| 21 | sub shutdown_handler {
|
|---|
| 22 | kill(1, $ffmpeg_pid) if ($ffmpeg_pid);
|
|---|
| 23 | }
|
|---|
| 24 |
|
|---|
| 25 | # Find ffmpeg
|
|---|
| 26 | $ffmpeg = '';
|
|---|
| 27 | foreach my $path (split(/:/, $ENV{'PATH'}.':/usr/local/bin:/usr/bin'), '.') {
|
|---|
| 28 | if (-e "$path/ffmpeg") {
|
|---|
| 29 | $ffmpeg = "$path/ffmpeg";
|
|---|
| 30 | last;
|
|---|
| 31 | }
|
|---|
| 32 | elsif ($^O eq 'darwin' && -e "$path/ffmpeg.app") {
|
|---|
| 33 | $ffmpeg = "$path/ffmpeg.app";
|
|---|
| 34 | last;
|
|---|
| 35 | }
|
|---|
| 36 | }
|
|---|
| 37 |
|
|---|
| 38 | # Load some conversion settings from the database
|
|---|
| 39 | $sh = $dbh->prepare('SELECT data FROM settings WHERE value=? AND hostname IS NULL');
|
|---|
| 40 | $sh->execute('WebFLV_w');
|
|---|
| 41 | my ($width) = $sh->fetchrow_array;
|
|---|
| 42 | $sh->execute('WebFLV_vb');
|
|---|
| 43 | my ($vbitrate) = $sh->fetchrow_array;
|
|---|
| 44 | $sh->execute('WebFLV_ab');
|
|---|
| 45 | my ($abitrate) = $sh->fetchrow_array;
|
|---|
| 46 | $sh->finish();
|
|---|
| 47 | # auto-detect height based on aspect ratio
|
|---|
| 48 | $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? AND starttime=FROM_UNIXTIME(?) AND data IS NOT NULL ORDER BY data DESC');
|
|---|
| 49 | $sh->execute($chanid,$starttime);
|
|---|
| 50 | $x = $sh->fetchrow_array;
|
|---|
| 51 | $y = $sh->fetchrow_array if ($x);
|
|---|
| 52 | $width = nearest_floor(2,$width);
|
|---|
| 53 |
|
|---|
| 54 | $height1=$height;
|
|---|
| 55 | if ($x && $y) {
|
|---|
| 56 | $height = nearest_floor(2,$width * ($y/$x));
|
|---|
| 57 | } else {
|
|---|
| 58 | $height = nearest_floor(2,$width * 3/4);
|
|---|
| 59 | }
|
|---|
| 60 | $sh->finish();
|
|---|
| 61 | $height2=$height;
|
|---|
| 62 | $width = 320 unless ($width && $width > 1);
|
|---|
| 63 | $height = 240 unless ($height && $height > 1);
|
|---|
| 64 | $vbitrate = 256 unless ($vbitrate && $vbitrate > 1);
|
|---|
| 65 | $abitrate = 64 unless ($abitrate && $abitrate > 1);
|
|---|
| 66 | $height3=$height;
|
|---|
| 67 | my $ffmpeg_command = $ffmpeg
|
|---|
| 68 | .' -y'
|
|---|
| 69 | .' -i '.shell_escape($filename)
|
|---|
| 70 | .' -s '.shell_escape("${width}x${height}")
|
|---|
| 71 | .' -g 30'
|
|---|
| 72 | .' -r 24'
|
|---|
| 73 | .' -f flv'
|
|---|
| 74 | .' -deinterlace'
|
|---|
| 75 | .' -ac 2'
|
|---|
| 76 | .' -ar 11025'
|
|---|
| 77 | .' -ab '.shell_escape("${abitrate}k")
|
|---|
| 78 | .' -b '.shell_escape("${vbitrate}k")
|
|---|
| 79 | .' /dev/stdout 2>/dev/null |';
|
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 | # Print the movie
|
|---|
| 83 | $ffmpeg_pid = open(DATA, $ffmpeg_command);
|
|---|
| 84 | unless ($ffmpeg_pid) {
|
|---|
| 85 | print header(),
|
|---|
| 86 | "Can't do ffmpeg: $!\n${ffmpeg_command}";
|
|---|
| 87 | exit;
|
|---|
| 88 | }
|
|---|
| 89 | print header(-type => 'video/x-flv');
|
|---|
| 90 | my $buffer;
|
|---|
| 91 | while (read DATA, $buffer, 262144) {
|
|---|
| 92 | print $buffer;
|
|---|
| 93 | }
|
|---|
| 94 | close DATA;
|
|---|
| 95 |
|
|---|
| 96 | 1;
|
|---|