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
- $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)
- -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.
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
Code: Select all
sox $AUDIO.wav $SEGMENT_X.wav trim $OFFSET $INTERVAL
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
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
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).