Thursday 5 January 2012

Split a Media Video File (AVI, FLV,...) using Mencoder and Mplayer

Mencoder is a movie encoder program that allows us to split a media video(e.g AVI) file into several AVI files.

We are going to split a media video file maintaining same video and audio codecs.

As mencoder accepts other file formats than avi files, we will be able to split them too, but result will be avi files.


SPLIT ONE FILE INTO TWO


E.g: We are going to split foo.avi file into foo1.avi(600 seconds long) and remaining length in foo2.avi.

Following mencoder man page advice, we could try these options:
$ mencoder foo.avi -o foo1.avi -oac copy -ovc copy -endpos 600
$ mencoder foo.avi -o foo3.avi -oac copy -ovc copy -ss 600


mencoder options:

foo.avi is the input file

-o foo1.avi indicates the output file

-oac copy means use same audio codec
-ovc copy means use same video codec

-endpos <[[hh:]mm:]ss[.ms]|size[b|kb|mb]>
Stop at given time or byte position.

Examples:
-endpos 56 # Stop at 56 seconds.
-endpos 01:10:00 # Stop at 1 hour 10 minutes.
-ss 10 -endpos 56 # Stop at 1 minute 6 seconds.
$ mplayer -endpos 100mb # Stop playback after reading 100MB of the input file.
$ mencoder -endpos 100mb # Encode only 100 MB.

So -endpos 600 indicates encode first 600 seconds of video stream.


-ss <time>
Seek to given time position.

Examples:
-ss 56 # Seeks to 56 seconds.
-ss 01:10:00 # Seeks to 1 hour 10 min.


We could use frames instead of time or size:
-frames <number>
Play/:convert only first <number> frames, then quit.


SPLIT ONE FILE INTO THREE OR MORE


If we want to split the file into more than two files, we use -ss along -endpos.

E.g: Split foo.avi into foo1.avi(300 seconds in length), foo2.avi(100 seconds) and remaining in foo3.avi
$ mencoder foo.avi -o foo1.avi -oac copy -ovc copy -endpos 300
$ mencoder foo.avi -o foo2.avi -oac copy -ovc copy -ss 300 -endpos 100
$ mencoder foo.avi -o foo3.avi -oac copy -ovc copy -ss 400


*** HOWEVER IT IS NOT GOING TO WORK!!! ***

If we simply split an avi media file specifying seconds or number of frames, we get a non accurate split. Result is not split at the exact point we told mencoder to do so, and parts do not match well again.

That happens because mencoder splits have to use keyframes as reference.
A keyframe or I-frame is a frame which can be decoded on its own, independently of its adjacent frames.

Fortunately mplayer enables us to detect I-frames. Let's read mplayer man page for framestep video filter.
$ man mplayer


framestep=I|[i]step
Renders only every nth frame or every intra frame
(keyframe).

If you call the filter with I (uppercase) as the
parameter, then only keyframes are rendered. For DVDs
it generally means one in every 15/12 frames
(IBBPBBPBBPBBPBB), for AVI it means every scene change
or every keyint value (see -lavcopts keyint= value if
you use MEncoder to encode the video).

When a keyframe is found, an 'I!' string followed by a
newline character is printed, leaving the current line
of MPlayer/:MEncoder output on the screen, because it
contains the time (in seconds) and frame number of the
keyframe (You can use this information to split the
AVI.).



We try framestep video filter:
$ mplayer -vf framestep=I foo.avi
Movie-Aspect is 1.88:1 - prescaling to correct movie aspect.
VO: [xv] 512x272 => 512x272 Planar YV12
I!
A: 12.0 V: 12.0 A-V: 0.000 ct: 0.008 301/301 1% 0% 0.4% 1 0 $
I!
A: 15.0 V: 15.0 A-V: 0.000 ct: 0.008 377/377 1% 0% 0.4% 1 0 $
I!
A: 27.0 V: 27.0 A-V: 0.000 ct: 0.008 677/677 2% 0% 0.5% 1 0

It shows after V:, useful video time in seconds.


SPLIT INTO TWO PARTS BASED ON SIZE AND GET I-FRAMES RIGHT.


E.g: We want to split an avi file into two parts, one part 300MByte in size.

Run mplayer to know where I-frames are located:
$ mplayer -framedrop -endpos 300mb -vf framestep=I foo.avi

We advance it until near the end and get:
I!
A:2360.0 V:2360.0 A-V: 0.000 ct: 0.042 59000/59000 3% 0% 0.8% 0 0
I!
A:2362.8 V:2362.8 A-V: 0.000 ct: 0.042 59072/59072 3% 0% 0.8% 0 0

IMPORTANT: I-frame data comes before I!.
So last I-frame comes at 2360.0 seconds.
We will use video time in seconds of last I-frame: 2360.0

$ mencoder foo.avi -o foo1.avi -endpos 2360.0 -ovc copy -oac copy
$ mencoder foo.avi -o foo2.avi -ss 2360.0 -ovc copy -oac copy


NOTE:
Sometimes I get this error when encoding a video file:
1 duplicate frame(s)!
Changing audio codec solved this problem: -oac mp3lame
(Note that this changes media file size)
http://darkmind2007.blogspot.com/2011/04/mencoder-1-duplicate-frames.html


REFERENCE


$ man mencoder


YOU MAY ALSO BE INTERESTED IN


Joining two AVI files with MENCODER

0 comentarios: