Monday, June 27, 2011

Video Cutter: Video Cutting using Mencoder

I have written a perl script, then can split/cut parts from a video file.

#!/usr/bin/perl -w
#===============================================================================
#
# FILE: video_cutter.pl
#
# USAGE: ./video_cutter.pl [options] <input_video_file>
#
# DESCRIPTION:
#
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: ---
# AUTHOR: Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
# VERSION: 1.0
# CREATED: 06/26/2011 03:57:55 PM IST
# REVISION: ---
#===============================================================================

use strict;
use warnings;

use Getopt::Std;

sub usage()
{
print STDERR "USAGE: $0 [options] <input_video_file>\n";
print STDERR " -c <conf_file> default /base_dir/input_video_file/video_cutter.conf\n";
print STDERR " Start_time(hh:mm:ss),End_time(hh:mm:ss)\n\n";
print STDERR " -o <out_dir> default /base_dir/input_video_file/\n";
}

sub hms_to_seconds()
{
my $end_sec = 0;
my ($h, $m, $s) = split(/:/, $_[0]);
$s = defined($s) ? $s : 0;
$end_sec += $s;
$m = defined($m) ? $m : 0;
$end_sec += (60 * $m);
$h = defined($h) ? $h : 0;
$end_sec += (3600 * $h);
return($end_sec);
}

my %opts;
getopt('o:c:', \%opts);

foreach my $opt (sort keys %opts)
{
if (!defined($opts{$opt}))
{
print STDERR "$0: Requires value for option '$opt'\n";
&usage();
exit(-1);
}
}

if (@ARGV != 1)
{
&usage();
exit(-1);
}

my $input_video_file = "$ARGV[0]";
my $out_dir = `dirname $input_video_file`;
chomp($out_dir);
my $conf_file = "$out_dir/video_cutter.conf";

if (defined($opts{"c"}))
{
$conf_file = $opts{"c"};
}
if (defined($opts{"o"}))
{
$out_dir = $opts{"o"};
}

unless (-f "$input_video_file")
{
print STDERR "$0: Input video file '$input_video_file' is not present\n";
exit(-1);
}
unless (-f "$conf_file")
{
print STDERR "$0: split conf file '$conf_file' is not present\n";
exit(-1);
}
unless (-d "$out_dir")
{
print STDERR "$0: out dir '$out_dir' is not present\n";
exit(-1);
}
unless (-w "$out_dir")
{
print STDERR "$0: out dir '$out_dir' is not writable\n";
exit(-1);
}

my $mencoder = "/usr/local/bin/mencoder";
unless (-x $mencoder)
{
$mencoder = "/usr/bin/mencoder";
}
unless (-x $mencoder)
{
print STDERR "$0: please install mencoder\n";
print STDERR "sudo apt-get install mencoder\n";
exit(-1);
}

open(CFH, "$conf_file") or die("$0: Cannot open '$conf_file'\n");
my $line;
my $nline = 0;
my $nsplit = 0;
my $split_name = `basename $input_video_file`;
chomp($split_name);
$split_name =~ s/\.[^.]*$//;
my $split_ext = $input_video_file;
$split_ext =~ s/.*\.([^.]*)$/$1/;
my $success = 0;
while ($line = <CFH>)
{
chomp($line);
$nline++;
next if ($line =~ m/^#/);
my ($start_time, $end_time) = split(/,/, $line);
next if (!defined($end_time));
my $start_sec = &hms_to_seconds($start_time);
my $end_sec = &hms_to_seconds($end_time);
if ($start_sec >= $end_sec)
{
print STDERR "$0: $start_sec >= $end_sec\n";
print STDERR " $start_time >= $end_time ... skipping for line no $nline ...\n";
next;
}
$end_sec -= $start_sec;
my $cmd = sprintf("%s -ss %d -endpos %d -ovc copy -oac copy -o %s/%s_%03d.%s %s",
$mencoder, $start_sec, $end_sec, $out_dir, $split_name, $nsplit,
$split_ext, $input_video_file);
print "\n\n";
print "-" x 80 . "\n";;
print "$cmd\n";
system("$cmd");
if ($? != 0)
{
print STDERR "$0: failed to create $nsplit split for line no $nline\n";
print STDERR "\t$cmd\n";
}
else
{
print STDOUT "Created $nsplit split for line $nline\n";
$success++;
}
print "-" x 80 . "\n";;
$nsplit++;
}

close(CFH);

print "\n";
print "=" x 80 . "\n";;
printf("Total lines = %d, Success = %d/%d, Failure = %d/%d\n",
$nline, $success, $nsplit,
$nsplit - $success, $nsplit);
print "=" x 80 . "\n";;

exit(0);



Please place the above perl script (video_cutter.pl) in any directory present in $PATH.


Sample Run:


Usage of the above script.
$ video_cutter.pl 
USAGE: /home/mitesh/Programming/Perl/WCS/video_cutter.pl [options]
-c default /base_dir/input_video_file/video_cutter.conf
Start_time(hh:mm:ss),End_time(hh:mm:ss)

-o default /base_dir/input_video_file/

Content of a sample config file, specifying the split timings.
This will create 3 splits, of 0s-90s, 140s-210s, and 240s-End.
$ cat test_video.conf 
00:00:00,00:01:30
00:02:20,00:03:30
00:04:00,59:59:00


Now, it will create the three split files in ~/Video/test/ directory.
$ video_cutter.pl -c test_video.conf -o ~/Video/test test_video.vob 


--------------------------------------------------------------------------------
/usr/local/bin/mencoder -ss 0 -endpos 90 -ovc copy -oac copy -o /home/mitesh/Video/test/test_video_000.vob test_video.vob
MEncoder 1.0rc4-4.4.5 (C) 2000-2010 MPlayer Team
...
...
...
Created 2 split for line 3
--------------------------------------------------------------------------------

================================================================================
Total lines = 3, Success = 3/3, Failure = 0/3
================================================================================
$ ls -l ~/Video/test/*.vob
-rw-r--r-- 1 mitesh mitesh 7519672 Jun 27 00:31 /home/mitesh/Video/test/test_video_000.vob
-rw-r--r-- 1 mitesh mitesh 5844598 Jun 27 00:31 /home/mitesh/Video/test/test_video_001.vob
-rw-r--r-- 1 mitesh mitesh 570855360 Jun 27 00:30 /home/mitesh/Video/test/test_video_002.vob

6 comments:

kacor said...

Thanks, just what I was looking for. Works nicely.

Any tips RE how to merge the splitted parts back into one file again? (E.g. after cotting out ads from a movie.)

kacor said...

OK just found the answer to my own question:

mencoder -oac copy -ovc copy -idx -o outputfile inputfile1 inputfile2

puneet vyas said...

Namastey Mitesh,
Thanks for yur service.
I would like to add one thing,if you comment each section of your code just like we have in any book,this would be very good for learning from a naive user perspective like me.

puneet vyas said...

Hi,
for .mts file format which is the file format introduced by sony &panasonic for AVCHD(Advanced Video Coding High Definition) in year 2006.
When you try to get video out of sony camcorders,it usually comes in big file size.
I found for windows/Linux/MacOS this software for converting .mts file to .mp4 format maintaining the quality of video intact with very small size in my case i converted 80 MB file to 27MB.
Although we can use mencoder and other things well here.
this software is also usefull.

http://handbrake.fr/

@Mitesh-Thanks For Your Experimental Analysis and Usability inside code!!

Thanks,
Puneet vyas

mitesh.singh.jat said...

Thanks! Puneet, that you find the code useful :)

puneet vyas said...

For users like me who are naive for understanding parameters for video editing this chart explains various attributes for choosing software as per your need!!.
http://en.wikipedia.org/wiki/Comparison_of_video_editing_software.

Thanks,
Puneet