Page 1 of 1

Losslessly split and merge AVI videos.

Posted: Sat Feb 27, 2010 4:13 pm
by ^rooker
I know that there are plenty ways of splitting AVI files, but I needed it with a bit more reliability and precision than most others require for home use. The video was encoded using Huffyuv (so it's lossless and only keyframes), and the audio was PCM 16bit 48kHz.

So it should be possible to exactly cut the video at a given frame/sample and merge it back together later on, without a single bit getting lost.
Well, it seems that ffmpeg/mencoder/etc are not really optimized for this, but rather for handling lossy formats (like XviD, mpeg, etc..) - so I had to fiddle around with their options a bit.

Here's what I've managed so far:
1) Split the video every minute, at exactly the last frame of each minute (e.g. 00:00:00.00 - 00:00:59.24):

Code: Select all

ffmpeg -ss $OFFSET.000 -t (($INTERVAL - 1)).999 -i $INPUT -an -vcodec copy $OUTPUT.avi
About the variables (bash-style):
  • $OFFSET: time offset where to start the video sequence. You'll need a loop around the above line to get multiple segments.
    $INTERVAL: time interval (in seconds) of each segment to extract.
    $INPUT: (full length) input video filename (e.g. "long_video.avi")
    $OUTPUT: output video filename of current video segment (e.g. "long_video-003.avi" for the 3rd segment)
About the parameters:
  • -ss: Start at a given timestamp. Format: "sec.msec"
    -t: Only "play" (=extract) a certain interval. Format: "sec.msec"
    -i: The input video filename (full length)
    -vcodec copy: Copy the video data as-is. Don't transcode or touch it.
    -an: Do *not* copy any audio. Yes. that's right: No audio - just the video. You'll see later on, why.
2) Extract the full length audio in one piece out of the original video and split it separately:
This is necessary in order to *make sure* we don't lose a single audio sample during split/merge due to muxing-synchronization oddities, depending on the tools used.
First of all, extract the audio out of the AVI file:

Code: Select all

ffmpeg -i $VIDEO.avi -vn -acodec copy $AUDIO.wav
Now I'm using the awesome "swiss army knife of audio processing" tool "SoX" to split/merge the audio:

Code: Select all

sox $AUDIO.wav $SEGMENT_X.wav trim $OFFSET $INTERVAL
The variables are similar to the ones used for the video. I suppose you'll get the idea how it works.

Now, in order to merge everything back, you simply concatenate the audio files like this:

Code: Select all

sox $SEGMENT1 $SEGMENT2 ... $SEGMENT_N $OUTPUT_MERGED.wav
It's bit-proof. I've checked this, by inverting the original audio and mix it together with the merged copy. The outcome was a perfect flat-line audio.

I wish it was that easy with video with ffmpeg, but it seems that mencoder is easier for that:

Code: Select all

mencoder -oac copy -ovc copy $SEGMENT1 $SEGMENT2 ... $SEGMENT_N -o $OUTPUT_MERGED.avi
The parameters "-oac copy" and "ovc copy" are again: "copy audio/video as-is. Don't transcode. Don't touch"
Again, I've verified that this method does not drop or multiply frames, by embedding a visual timecode (min:sec.frame) into the original video before splitting it (I've used kdenlive's embed-timecode-option for this).