#!/usr/bin/perl # # $Id$ # Subversion repository: http://svn.stellman-greene.com/mencoder_tivo/ # Home page: http://www.stellman-greene.com/astellman/mencoder_tivo/ # # This software is released under the GNU General Public License (GPL). # http://www.gnu.org/copyleft/gpl.html # # (c) 2005 Andrew Stellman use strict; my $version = "1.0.1"; my $version_date = "03-Oct-2005"; =head1 mencoder_tivo.pl perl script to help you use MEncoder to create files that you can transfer to your TiVo =head2 Usage mencoder_tivo.pl filename [filename [filename [...]]] --output=filename arguments =head1 Description When TiVo released version 7.2 of the TiVo software and version 2.2 of the TiVo desktop software, they added a feature which allows the TiVo to retrieve video from a home network. Unfortunately, the TiVo can't play all formats. mencoder_tivo.pl will read any video file and convert it into a format which the TiVo can play. mencoder_tivo.pl requires MEncoder to be in the path. MEncoder is part of the MPlayer system which can be downloaded from http://www.mplayerhq.hu/. =head2 Arguments =head3 filename A list of one or more input files must be specified on the command line. The input files will be stitched together into one output file. =head3 --output=filename One output filename must be specified. =head3 --low-quality (optional) Create a smaller, low-quality file. By default, mencoder_tivo.pl produces a 480x480 file with video bitrate of 4000 (maximum 12000). The low-quality option will reduce the resolution to 352x480 and set the bitrate to 1000. This option will override the --resolution and --bitrate options. =head3 --very-low-quality (optional) Create an even smaller, lower-quality file. This reduces the bitrate even further (to 750), the framerate to 24000/1001 (default is 30000/1001) and the audio sample rate to 64 (default is 96). This option overrides the --low-quality option. =head3 --widescreen (optional) Set the aspect to 16/9. (The default aspect is 4/3.) =head3 --resolution=[720:480|704:480|544:480|480:480|352:480] (optional) The default resolution is 480x480, but one of the other TiVo-supported resolutions can be used instead. =head3 --bitrate=4000/12000 (optional) By default, files are encoded with a bitrate of 4000 and maximum bitrate of 12000. This option will override that default. =head3 --omit-lavcresample (optional) Omit the '-af lavcresample=48000' option, which will cause some versions of MEncoder to crash. =head3 --print (optional) This option tells mencoder_tivo.pl to print the MEncoder command instead of executing it. =head3 --help (optional) Display a help message. =cut # read the arguments my $argument; my %arguments = (); my @input_files = (); my $reading_filenames = 1; while( $argument = shift ) { # check for --help argument print_usage("") if $argument =~ "--help"; # read the filenames first, then the --* arguments if ($reading_filenames) { if ($argument =~ /^--/) { if ($#input_files == -1) { print_usage("At least one input file must be specified"); } else { $reading_filenames = 0; } } else { $input_files[$#input_files + 1] = $argument; } } if (!$reading_filenames) { # read the --* arguments if ($argument =~ /^(.*)=(.*)$/) { check_argument ( $1, $2 ); $arguments{ $1 } = $2; } else { check_argument ( $argument, "" ); $arguments{ $argument } = "1"; } } } # make sure input and output filenames were specified if ( $#input_files == -1 ) { print_usage("One or more input files must be specified."); } if ( $arguments{ "--output" } eq "" ) { print_usage("An output file must be specified."); } # set defaults my $bitrate = 4000; my $max_bitrate = 12000; my $min_bitrate = 1000; my $resolution = "480:480"; my $lavcresample = "-af lavcresample=48000"; my $aspect = "4/3"; my $audiorate = "96"; my $framerate = "30000/1001"; # set video bitrate # (note that --low-quality will override this) if ( $arguments{ "--bitrate" } ne "" ) { print $arguments{ "--bitrate" } . "\n"; $arguments{ "--bitrate" } =~ /^(\d+)\/(\d+)$/; $bitrate = $1; $max_bitrate = $2; } # set resolution # (note that --low-quality will override this) if ( $arguments{ "--resolution" } ne "" ) { $resolution = $arguments{ "--resolution" }; } # set low-quality parameters if ( $arguments{ "--low-quality" } ne "" ) { $bitrate = 1000; $max_bitrate = 1000; $resolution = "352:480"; } # set very-low-quality parameters if ( $arguments{ "--very-low-quality" } ne "" ) { $bitrate = 750; $max_bitrate = 750; $min_bitrate = 750; $audiorate = "64"; $framerate = "24000/1001"; $resolution = "352:480"; } # set widescreen parameters if ( $arguments{ "--widescreen" } ne "" ) { $aspect = "16/9"; } # check for --omit-lavcresample if ( $arguments { "--omit-lavcresample" } ne "" ) { $lavcresample = ""; } # build command line my $command = "mencoder -of mpeg -oac lavc -ovc lavc -ofps $framerate -srate 48000 " . "$lavcresample -vf scale=$resolution -lavcopts aspect=$aspect:acodec=mp2:abitrate=$audiorate:" . "vcodec=mpeg2video:vmax_b_frames=2:vbitrate=$bitrate:vrc_maxrate=$max_bitrate:" . "vrc_minrate=$min_bitrate:vrc_buf_size=1835 -o \"$arguments{ '--output' }\" "; for ( my $i = 0; $i <= $#input_files; $i++ ) { $command .= "$input_files[$i] "; } # execute MEncoder if ( $arguments{ "--print" } ne "" ) { print "$command\n"; } else { # Open the output of the command, use sysread() to do an unbuffered read # so we get real-time output open(CMD,"$command 2>&1 |"); my $char; while(sysread(CMD,$char,1)) { print $char; } close(CMD); } # verify that an argument is allowed sub check_argument { my ($argument, $parameter) = @_; if ( $argument eq "--resolution" ) { return if $parameter eq "720:480"; return if $parameter eq "704:480"; return if $parameter eq "544:480"; return if $parameter eq "480:480"; return if $parameter eq "352:480"; print_usage("Invalid parameter '$parameter' for --resolution argument\nResolution can be either 720:480, 704:480, 544:480, 480:480 or 352:480"); } if ( $argument eq "--bitrate" ) { return if $parameter =~ /^\d+\/\d+$/; print_usage("Invalid parameter '$parameter' for --bitrate argument"); } if ( $argument eq "--output" ) { print_usage("A filename must be specified with --output") if ( $parameter eq "" ); return; } return if ( $argument eq "--low-quality" ) && ( $parameter eq "" ); return if ( $argument eq "--very-low-quality" ) && ( $parameter eq "" ); return if ( $argument eq "--widescreen" ) && ( $parameter eq "" ); return if ( $argument eq "--omit-lavcresample" ) && ( $parameter eq "" ); return if ( $argument eq "--print" ) && ( $parameter eq "" ); print_usage("Invalid argument '$argument=$parameter'") if $parameter ne ""; print_usage("Invalid argument '$argument'"); } # print the usage sub print_usage { my ($message) = @_; print "$message\n\n" if $message ne ""; print <