How to join together several Flash video (flv) files

YouTube users will be familiar with the 10-minute limit on videos uploaded to the site. People get around the restriction by splitting longer videos into several clips. Recently I wanted to watch a video that had been split into nine clips on YouTube, but I wanted to join them together to avoid interruptions. However, it turns out that, if video clips do not all have the same resolution, bit rate and frame rate, concatenating them is more complicated than I was expecting. Below I describe the things I tried and what worked for me.

I downloaded the clips by using the script youtube-dl, which is an easy way of downloading YouTube videos without having to watch them first. For example:

youtube-dl -o brodyworld_dreamer.flv http://www.youtube.com/watch?v=ue-0UUVzUbM

The nine clips have the following characteristics:

clip1.flv 35.7 MiB (480×360, 362 average kbps, 25-26 fps according to YouTube)
clip2.flv 43.2 MiB (480×360, 460 average kbps, 25-26 fps according to YouTube)
clip3.flv 46.3 MiB (480×360, 418 average kbps, 25-26 fps according to YouTube)
clip4.flv 27.8 MiB (320×240, 238 average kbps, 25-26 fps according to YouTube)
clip5.flv 20.0 MiB (320×240, 203 average kbps, 25-26 fps according to YouTube)
clip6.flv 45.5 MiB (480×360, 414 average kbps, 25-26 fps according to YouTube)
clip7.flv 43.0 MiB (480×360, 460 average kbps, 25-26 fps according to YouTube)
clip8.flv 45.4 MiB (480×360, 495 average kbps, 25-27 fps according to YouTube)
clip9.flv 28.0 MiB (480×360, 400 average kbps, 25-26 fps according to YouTube)

Google found several sites with instructions on how to concatenate flv files. Below are a few of the suggested solutions, and my experience using them to try and concatenate these nine video clips.

GUI APPLICATIONS

Pitivi

This could import all the clips but, when I dragged them to the timeline pane at the bottom of the window, Pitivi would only recognise them as audio clips. Also, if I tried to play one of the clips in the right pane of the window, Pitivi would play only the audio track. I have found this happens with some flv files that I download from YouTube.

So, I tried another application…

Avidemux

A pop-up window appeared when I tried to open the first clip:

“H.264 detected.
If the file is using B-frames as reference it can lead to a crash or stuttering.
Avidemux can use another mode which is safe but YOU WILL LOSE FRAME ACCURACY.
Do you want to use that mode?”

I clicked on ‘Use safe mode’ and Avidemux loaded the clip successfully and could play it. A different pop-up window appeared when I then tried to open the second clip:

“Video dimensions don’t match. You cannot mix different video dimensions yet. Using partial video filter later will not work around this problem. The workaround is: 1) “Resize” /”Add Border” / “Crop” each stream to the same resolution; 2) Concatenate them together.”

Too much hassle, so on to the next applicatiion…

Kino

This looked like it might work, as it converts each flv clip to a DV file first:

“/home/fitzcarraldo/Downloads/clip1.flv” is not a DV file. Do you want to import it? Importing… (this might take a while).”

It certainly does take a while, and each clip’s .dv file was 2 GiB. I gave up after the second clip. Too long and too manual for my liking.

Time to try the command line, then…

THE COMMAND LINE

Google finds several forum threads and blogs offering command line solutions for joining several flv files together (and for joining together several avi files, or several mpeg files, and so on). I tried several of the different command strings recommended, none of which worked with the nine clips I had downloaded. Some of the commands resulted in a concatenated file that would only play the first 10 minutes (i.e. the first clip), others only the first 20 minutes (i.e. the first two clips), and others resulted in a zero-length file.

My biggest hope were the three alternatives given in the FFmpeg FAQ section 3.15 How can I join video files?, but the error messages “Estimating duration from bitrate, this may be inaccurate” and “VBV buffer size not set, muxing may fail” during processing worried me. And they are hardly quick and easy commands to enter.

FFmpeg Method 1

ffmpeg -i clip1.flv -sameq intermediate1.mpg
ffmpeg -i clip2.flv -sameq intermediate2.mpg
ffmpeg -i clip3.flv -sameq intermediate3.mpg
ffmpeg -i clip4.flv -sameq intermediate4.mpg
ffmpeg -i clip5.flv -sameq intermediate5.mpg
ffmpeg -i clip6.flv -sameq intermediate6.mpg
ffmpeg -i clip7.flv -sameq intermediate7.mpg
ffmpeg -i clip8.flv -sameq intermediate8.mpg
ffmpeg -i clip9.flv -sameq intermediate9.mpg
cat intermediate1.mpg intermediate2.mpg intermediate3.mpg intermediate4.mpg intermediate5.mpg intermediate6.mpg intermediate7.mpg intermediate8.mpg intermediate9.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -sameq film.avi

The resulting file was 124 MiB and consisted of only the first twenty minutes, i.e. the first two clips. Both VLC and SMPlayer could play it.

FFmpeg Method 2

mkfifo intermediate1.mpg
mkfifo intermediate2.mpg
mkfifo intermediate3.mpg
mkfifo intermediate4.mpg
mkfifo intermediate5.mpg
mkfifo intermediate6.mpg
mkfifo intermediate7.mpg
mkfifo intermediate8.mpg
mkfifo intermediate9.mpg
ffmpeg -i clip1.flv -sameq -y intermediate1.mpg < /dev/null &
ffmpeg -i clip2.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip3.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip4.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip5.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip6.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip7.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip8.flv -sameq -y intermediate2.mpg < /dev/null &
ffmpeg -i clip9.flv -sameq -y intermediate2.mpg < /dev/null &
cat intermediate1.mpg intermediate2.mpg intermediate3.mpg intermediate4.mpg intermediate5.mpg intermediate6.mpg intermediate7.mpg intermediate8.mpg intermediate9.mpg |\
ffmpeg -f mpeg -i - -sameq -vcodec mpeg4 -acodec libmp3lame film.avi

The resulting file was 124 MiB and again only consisted of the first twenty minutes. SMPlayer could play it (although the film’s duration was shown as 00:00:00), but VLC could not.

FFmpeg Method 3

mkfifo temp1.a
mkfifo temp1.v
mkfifo temp2.a
mkfifo temp2.v
mkfifo temp3.a
mkfifo temp3.v
mkfifo temp4.a
mkfifo temp4.v
mkfifo temp5.a
mkfifo temp5.v
mkfifo temp6.a
mkfifo temp6.v
mkfifo temp7.a
mkfifo temp7.v
mkfifo temp8.a
mkfifo temp8.v
mkfifo temp9.a
mkfifo temp9.v
mkfifo all.a
mkfifo all.v
ffmpeg -i clip1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
ffmpeg -i clip2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
ffmpeg -i clip3.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp3.a < /dev/null &
ffmpeg -i clip4.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp4.a < /dev/null &
ffmpeg -i clip5.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp5.a < /dev/null &
ffmpeg -i clip6.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp6.a < /dev/null &
ffmpeg -i clip7.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp7.a < /dev/null &
ffmpeg -i clip8.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp8.a < /dev/null &
ffmpeg -i clip9.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp9.a < /dev/null &
ffmpeg -i clip1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
{ ffmpeg -i clip2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; } &
{ ffmpeg -i clip3.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp3.v ; } &
{ ffmpeg -i clip4.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp4.v ; } &
{ ffmpeg -i clip5.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp5.v ; } &
{ ffmpeg -i clip6.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp6.v ; } &
{ ffmpeg -i clip7.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp7.v ; } &
{ ffmpeg -i clip8.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp8.v ; } &
{ ffmpeg -i clip9.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp9.v ; } &
cat temp1.a temp2.a temp3.a temp4.a temp5.a temp6.a temp7.a temp8.a temp9.a > all.a &
cat temp1.v temp2.v temp3.v temp4.v temp5.v temp6.v temp7.v temp8.v temp9.v > all.v &
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
-f yuv4mpegpipe -i all.v \
-sameq -y film.flv
rm temp[123456789].[av] all.[av]

The resulting file was 175.4 MiB. Both VLC and SMPlayer showed the correct duration of 1:27:22 but could not play further than twenty minutes.

Mencoder Method 1

A Linux forum thread suggested the following mencoder command string would do the job:

mencoder -forceidx -of lavf -oac copy -ovc copy -o film.flv clip1.flv clip2.flv clip3.flv clip4.flv clip5.flv clip6.flv clip7.flv clip8.flv clip9.flv

This failed with the error message “Audio format 0x4134504d is incompatible with ‘-oac copy’, please try ‘-oac pcm’ instead or use ‘-fafmttag’ to override it.” so I changed it to:

mencoder -forceidx -of lavf -oac copy -ovc pcm -o film.flv clip1.flv clip2.flv clip3.flv clip4.flv clip5.flv clip6.flv clip7.flv clip8.flv clip9.flv

This produced the error message “All video files must have identical fps, resolution, and codec for -ovc copy.” and the resulting film.flv was 261.2 MiB. Both VLC and SMPlayer showed the film duration as 20 minutes, and played those 20 minutes.

Mencoder Method 2

Finally I found a command that worked successfully and without hassle:

mencoder -oac pcm -ovc xvid -vf scale -zoom -xy 480 -xvidencopts bitrate=460 -o film.avi clip1.flv clip2.flv clip3.flv clip4.flv clip5.flv clip6.flv clip7.flv clip8.flv clip9.flv

I chose a bitrate of 460 kbps, as it is near the top of the range of bitrates of the nine clips, and an X-axis resolution of 480 pixels (the Y-axis resolution is scaled automatically) even though some of the clips have a smaller resolution. The resulting file is a 1.1 GiB AVI file. The image is a bit less distinct than the original clips but SMPlayer and VLC show the film’s correct duration and play it to the end. There are slight hiccups at some of the joins, but these are hardly noticeable. SMPlayer lists the following information about the video:

General
File
/home/fitzcarraldo/Downloads/film.avi
Size
1182950 KB (1155 MB)
Length
01:27:21
Demuxer
avi

Clip info
Software
MEncoder SVN-r30554-4.4.2

Video
Resolution
480 x 360
Aspect ratio
1.3333
Format
XVID
Bitrate
430 kbps
Frames per second
25.000
Selected codec
ffodivx

Initial Audio Stream
Format
1
Bitrate
1411 kbps
Rate
44100 Hz
Channels
2
Selected codec
pcm

Audio Streams
#
Language
Name
ID
0

1

So there we have it. Not perfect, but at least something that actually works, and with little effort.

If you have successfully stitched together video files each having a different resolution and/or frame rate and/or bit rate and/or codec, do add a comment and let us know the command string or GUI application that you used, and whether or not the resulting video quality was good.

Follow

Get every new post delivered to your Inbox.

Join 49 other followers