15

I'm on Arch Linux 4.13.10 and I'd like to combine multiple .MOV files shot with a Canon EOS camera.

I tried to convert the files to transport streams (.ts files) using FFmpeg, as shown here, but sound was missing from the resulting file.

I'd prefer if the resulting file would be .mp4, but this is not strictly required.

How do I do this?

3 Answers3

25

I succeeded merging the files using FFmpeg's demuxing feature. For .mp4 conversion, I had to explicitly convert the audio stream to avoid this error:

Could not find tag for codec pcm_s16le in stream #1, codec not currently supported in container

This is the command combining the files to merged.mp4:

ffmpeg -f concat -i files_to_combine.txt -vcodec copy -acodec aac -strict -2 -b:a 384k merged.mp4

If the output file can be also a .MOV file, the command is:

ffmpeg -f concat -i files_to_combine.txt -vcodec copy -acodec copy merged.MOV

Here's the content of the text file files_to_combine.txt:

file ./first_file.MOV
file ./second_file.MOV

If you get the error

Unsafe file name 'file with spaces.mov' files_to_combine.txt: Operation not permitted

and trust the file names, you can add -safe 0 to get around this error. See FFmpeg's man page:

ffmpeg -safe 0 -f concat ...

Shorter commands

Trying the same task five years later, I also had success with

ffmpeg -f concat -i files_to_combine.txt merged.mov

and

ffmpeg -f concat -i files_to_combine.txt -f mp4 merged.mp4
3
find *.MOV | sed 's:\ :\\\ :g'| sed 's/^/file /' > fl.txt; ffmpeg -f concat -i fl.txt -c copy output.mp4; rm fl.txt
Danil
  • 131
2

If you're looking for how to concatenate .mp4 files instead, see my other answer here: Stack Overflow: How to concatenate two MP4 files using FFmpeg?

To combine many .mov or .MOV files into one

...here's what you need to do:

# 0. Copy all .mov files that (you'd like to combine) into a single directory. 
# Then `cd` into that directory.

1. Create a "files.txt" file containing a list of files to combine

find . -type f -iname "*.mov" | sort -V
| awk '{print "file \x27" $0 "\x27"}' > files.txt

[WHAT I USUALLY USE: FAST]

2. If all of your .mov files have the same encoding (ex: they were

all recorded on the same video camera and with the same settings), you can

specify to use the "copy" codec via -c copy, which means it will NOT

have to re-encode the video. This just concatenates all the files together.

THIS TAKES SECONDS.

time ffmpeg -f concat -safe 0 -i files.txt -c copy merged.mov

[SLOW; SOMETIMES NECESSARY]

OR 2. If each of your .mov files has a different encoding, you'll need to

re-encode them all into a single stream.

- This uses the "files.txt" file created above, and outputs the merged

file into "merged.mov".

THIS COULD TAKE HOURS.

time ffmpeg -f concat -safe 0 -i files.txt merged.mov

I am generally in a situation where I can use the first option, which takes seconds instead of hours, which is great!

Extra details and explanation

  • If ls -1 shows you have these files:

    REC_0009.MOV
    REC_0010.MOV
    REC_0011.MOV
    

    Then the find command will produce this files.txt file:

    file './REC_0009.MOV'
    file './REC_0010.MOV'
    file './REC_0011.MOV'
    
  • The -iname "*.mov" part does a case-insenstive* match for all files ending in .mov or .MOV, or any other combination of capital letters.

  • If you forget -safe 0 in the ffmpeg command, and any of your filenames have a "directory" in them in the form of ./ even, you'll get an error like this:

    [concat @ 0x555a24968700] Unsafe file name './REC_0009.MOV'
    files.txt: Operation not permitted
    

    The -safe 0 option tells ffmpeg to ignore this error and accept "unsafe" directories in filepaths.

    @Matthias Braun mentions that here.

    From the ffmpeg man page online only (not in the man ffmpeg man page locally on my Linux Ubuntu 20.04 computer): https://manpages.org/ffmpeg:

    safe

    If set to 1, reject unsafe file paths. A file path is considered safe if it does not contain a protocol specification and is relative and all components only contain characters from the portable character set (letters, digits, period, underscore and hyphen) and have no period at the beginning of a component.

    If set to 0, any file name is accepted.

    The default is 1.

    -1 is equivalent to 1 if the format was automatically probed and 0 otherwise.

  • The -c copy option tells ffmpeg to use the "copy" codec, which means it will not re-encode the video. This is what makes it so fast.

References

  1. I studied @Matthias Braun's answer too.
  2. My answer here where I use \x27 to produce the ' character: Stack Overflow: How to escape single quotes within single quoted strings
  3. I had a lot of talks with the GitHub Copilot AI in my VSCode text editor while figuring out the nuances of the commands above.
  4. My answer for MP4 files: Stack Overflow: How to concatenate two MP4 files using FFmpeg?