I want to merge mp4 files via the concat demuxer and cannot get it to work with a script.
I am using the script from another AskUbuntu answer, called concatmp4
here:
#!/usr/bin/env bash
if [ $# -lt 1 ]; then
echo "Usage: `basename $0` input_1.mp4 input_2.mp4 ... output.mp4"
exit 0
fi
ARGS=("$@") # determine all arguments
output=${ARGS[${#ARGS[@]}-1]} # get the last argument (output file)
unset ARGS[${#ARGS[@]}-1] # drop it from the array
(for f in "${ARGS[@]}"; do echo "file '$f'"; done) | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy $output
However, when I run it on mp4 files, I always get
$ concatmp4 Itazuraguma_no_Gloomy_01.mp4 Itazuraguma_no_Gloomy_02.mp4 test.mp4
ffmpeg version 4.4-6ubuntu5 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 11 (Ubuntu 11.2.0-7ubuntu1)
configuration: --prefix=/usr --extra-version=6ubuntu5 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55f2ed650200] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55f2ed650200] moov atom not found
[concat @ 0x55f2ed63e440] Impossible to open 'pipe:Itazuraguma_no_Gloomy_01.mp4'
pipe:: Invalid data found when processing input
When I modify the script's last line to (for f in "${ARGS[@]}"; do echo "file '$f'"; done) > input.text
, and then run ffmpeg -f concat -i input.text -c copy output.mp4
from the command line, it works (!). Just to clarify, when I use -c copy
in the script, the error is the same.
It also works when the script goes via a temp file:
... # lines after the 'unset' line in the original:
tmpfile="${output%.mp4}.tmp"
(for f in "${ARGS[@]}"; do echo "file '$f'"; done) > "$tmpfile"
ffmpeg -f concat -safe 0 -i "$tmpfile" -c copy "$output"
rm "$tmpfile"
What is needed to make the script work?
According to the bug tracker of
ffmpeg
, there were changes in the newer versions. Since the release between 4.2.2 and 4.3.2, the handling of relative URLs have been fixed to make it compatible with the official recommendations.If there are bare file names in the concat script, the files are supposed to reside in the same directory (and of course protocol) as the script. Which, of course, is not possible for pipe:, but still applies. If the script is saved in a temp file, its protocol changes to 'file' and the old way works because of that change.
The piped input needs to specify both the concat
file
and the protocolfile:
in the concat code.Example for now necessary input via
pipe
protocol:file file:'input_01.mp4'
instead of the oldfile 'input_01.mp4'
.The new version of the script needs to be changed to
to work.