#!/usr/bin/perl # AVI2MPEG written by Stanislaw Polak # http://www.icsr.agh.edu.pl/~polak/ # 5 Oct 2004 # # Copyright (c) 2004 Stanislaw Polak # Unpublished work. # Permission granted to use and modify this script so long as the # copyright above is maintained, modifications are documented, and # credit is given for any use of the script. # # For more information, see: # http://www.icsr.agh.edu.pl/~polak/skrypty/avi2mpeg.html.var # #Version 1.01 (12 Oct 2004) # Errors handling has been fixed #Version 1.0 (5 Oct 2004) # The first public version ################################ #Variables ################################ use strict; use vars qw($opt_v $opt_h $opt_o $opt_n $opt_r @opt_t); use Getopt::Long; my($tmp,$outputFilename,$transitionLength,$defaultTransition,%transitions,$DEBUG,@tmpFiles); $tmp="/tmp"; # a place where temporary files will be stored $outputFilename=setOutputFilename(); #if option '-o' is not specified, output file name is "day-month-year_hour:minute.mpg" $transitionLength=25; #length of transition in frames (it must be multiple of 25) #predefined transitions %transitions = ( "blend" => "transist.flt -o 0 -O 255 -d $transitionLength", "overlay1" => "overlay.flt -l $transitionLength", "overlay2" => "overlay.flt -l $transitionLength -i", "wipe1" => "wipe.flt -l $transitionLength -d 1", "wipe2" => "wipe.flt -l $transitionLength -d 2", "wipe3" => "wipe.flt -l $transitionLength -d 3", "wipe4" => "wipe.flt -l $transitionLength -d 4", ); $defaultTransition="blend"; $DEBUG=0; ################################### # Command line options processing ################################### sub init() { &GetOptions("t|transition:s@", "h|help","r|reposition=i","n|number=i","o|output:s","v|version") or usage(); if($opt_v){ #option '-v' or '--version' was used print << "EOF"; avi2mpeg converter, version 1.01 Written by Stanislaw Polak (http://www.icsr.agh.edu.pl/~polak/). This is free software. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. EOF exit; }# if($opt_v) usage() if $opt_h; #option '-h' or '--help' was used usage() if $#ARGV == -1; #script was run without arguments $outputFilename=$opt_o if $opt_o; #option '-o' or '--output' was used } ################################### # Set output file name as: # day-month-year_hour:minute.mpg ################################### sub setOutputFilename() { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year = 1900 + $year; return "$mday-$mon-$year\_$hour:$min.mpg"; } ################################### # how many frames has the video file ################################### sub movieLength() { my(@result); open PROG, "lavinfo $_[0] |" or die("I can't execute 'lavinfo $_[0]'\n") ; while(){ #find "video_frames=..." last if /^video_frames/ } close PROG or die("I can't execute 'lavinfo $_[0]'\n") ; @result=split /=/; return $result[1]; } ################################### # execute UNIX command ################################### sub execCmd() { if(! $DEBUG){ system($_[0]); if ($? == -1) { die "Failed to execute: \"$_[0]\"\nMaybe you didn't install the \"MJPEGTOOLS\" library or \"wipe.flt\" and \"overlay.flt\" programs\n$!, stopped"; } elsif ($? & 127) { printf STDERR "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; exit $? ; } } else{ print "$_[0]\n"; } } ################################### # Message about this program and how to use it ################################### # sub usage() { print STDERR << "EOF"; usage: $0 [OPTION] FILE ...[OPTION]... [FILE] -h --help This (help) message -v --version Output version information and exit -o name --output=name Use 'name' as the name for the file produced by this script -t TRANS --transition=TRANS When files are joined the TRANS transition will be used. TRANS may be: 'random', 'blend', 'overlay1', 'overlay2', 'wipe1', 'wipe2', 'wipe3' or 'wipe4'. When TRANS is 'wipe1', 'wipe2', 'wipe3' or 'wipe4' you can use the following 2 options: -n NUM --number=NUM number of wipe columns/rows (default: 1) -r NUM --reposition=NUM disable/enable reposition. 0: disable 1: only scene 1 2: only scene 2 3: both example: $0 -n=3 first.avi -t=wipe1 second.avi -o a.mpg EOF exit; } ################################### # cut the selected part of a movie # and return the name of a new movie ################################### # sub cut() { my($beginOffset,$endOffset,$file,$length); #start cutting the 'file' movie from 'beginOffset' to 'length-endOffset' $beginOffset=$_[0]; $endOffset=$_[1]; $file=$_[2]; $length=&movieLength("$file")-($beginOffset+$endOffset); &execCmd("lav2yuv -o $beginOffset -f $length $file|yuv2lav -f a -q 80 -o ${tmp}/$beginOffset-$endOffset-$file"); push(@tmpFiles,"${tmp}/$beginOffset-$endOffset-$file"); return "${tmp}/$beginOffset-$endOffset-$file"; } ################################### # creates a movie with selected transition # and returns the name of the movie ################################### # sub createTransition() { my($transitionName,$file1,$file2,$transition,$i,$key,$value); $transitionName=$_[0]; #the name of transition specified with '-t' or '--transition' option $file1=$_[1]; #the name of the first movie $file2=$_[2]; #the name of the second movie if($transitionName=~/random/){ #the 'random' transition my($howManyTransitions,$transitionNumber); $howManyTransitions= scalar keys %transitions; #number of predefined transition = number of elements in the 'transitions' hash $transitionNumber=int(rand $howManyTransitions)+1; #draw a transition number for($i=0;$i<$transitionNumber;$i++){ ($key,$value)=each %transitions; #get 'transitionNumber'-nth transition } if($key=~/^wipe/){ #the 'wipe' transition was choosed my($r,$n); $r=int(rand 3); #draw a value of the 'reposition' parameter $n=int(rand 4)+1; #draw a value of the ' number of wipe columns/rows' parameter $value = $r ? "$value -r $r" : $value; #append the above parameter $value = $n ? "$value -n $n" : $value; #append the above parameter }# if($key=~/^wipe/) $transition=$value; }# if($transitionName=~/random/ else{ $transition=$transitions{"$transitionName"}; } if(!$transition){ print STDERR "Unknown transition \"$transitionName\". Instead of them I'm using \"$defaultTransition\"\n"; $transition=$transitions{$defaultTransition}; } if($transitionName=~ /^wipe/){ #if the 'wipe' transition was specified in '-t' or '--transition' option $transition = $opt_r ? "$transition -r $opt_r" : $transition; #append the value of the 'reposition' parameter $transition = $opt_n ? "$transition -n $opt_n" : $transition; #append the value of the ' number of wipe columns/rows' parameter } if($transition){ &execCmd("ypipe \"lav2yuv -o -25 $file1\" \"lav2yuv -f 25 $file2\" | $transition | yuv2lav -f a -q 80 -o ${tmp}/$file1-transition-$file2"); push(@tmpFiles,"${tmp}/$file1-transition-$file2"); } return "${tmp}/$file1-transition-$file2"; } ################################### srand(time()^($$+($$<<15))); init(); my(@files); @files=@ARGV; @tmpFiles=(); print "\033[35mI'm separating an audio stream\033[0m\n"; &execCmd("lavtrans -o ${tmp}/audio.wav -f w @files"); &execCmd("cat ${tmp}/audio.wav | mp2enc -v 2 -V -o ${tmp}/audio.mp2"); unlink "${tmp}/audio.wav" if ! $DEBUG; print "\033[35mI'm separating a video stream\033[0m\n"; if($#opt_t != -1){ #option "--transition" or "-t" was used $#files=-1; #cut the first movie from beginning possition ('0') to the 'length Of The Movie - transitionLength' position push(@files,&cut(0,$transitionLength,$ARGV[0])); while($#opt_t > -1){ #table of '-t' or '--transiotion' arguments is not empty if(! $#ARGV ) {last;} #list of arguments is empty, leave this loop #create the 'opt_t[0]' transition for the 'ARGV[0]' and 'ARGV[1]' movie push(@files,&createTransition($opt_t[0],$ARGV[0],$ARGV[1])); if($#ARGV>=2 && $#opt_t){ #cut the second movie from 'transitionLength' to 'length Of The Movie - transitionLength' position push(@files,&cut($transitionLength,$transitionLength,$ARGV[1])); } shift @opt_t; shift @ARGV; }#while($#opt_t > -1 #cut the first movie from 'transitionLength' position to the end of this movie push(@files,&cut($transitionLength,0,$ARGV[0])); while($ARGV[1]){ #if the list of '-t' or '--transition' is empty #join the other movies without transition push(@files,$ARGV[1]); shift @ARGV; } } &execCmd("lav2yuv @files | mpeg2enc -o ${tmp}/video.mpg"); print "\033[35mI'm putting together both streams\033[0m\n"; &execCmd("mplex -o $outputFilename ${tmp}/video.mpg ${tmp}/audio.mp2"); END{ if(!$DEBUG){ unlink @tmpFiles if @tmpFiles; unlink "${tmp}/video.mpg" if -e "${tmp}/video.mpg"; unlink "${tmp}/audio.mp2" if -e "${tmp}/audio.mp2"; unlink "${tmp}/audio.wav" if -e "${tmp}/audio.wav"; } else{ print "@files\n"; } }