I have created an artificial test case where I want to have red + middle C, green + middle D, and blue + middle E each for 2.5 seconds, cut down to each for 1.5 seconds. This is a simplification of my real video file, which I am unable to share.
ffmpeg version info:
ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
built with Apple clang version 15.0.0 (clang-1500.1.0.2.5)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/6.1.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopenvino --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
libavutil 58. 29.100 / 58. 29.100
libavcodec 60. 31.102 / 60. 31.102
libavformat 60. 16.100 / 60. 16.100
libavdevice 60. 3.100 / 60. 3.100
libavfilter 9. 12.100 / 9. 12.100
libswscale 7. 5.100 / 7. 5.100
libswresample 4. 12.100 / 4. 12.100
libpostproc 57. 3.100 / 57. 3.100
This bash script performs all necessary steps on MacOS:
#!/bin/bash
# generate red, green, blue video
rm -f r.mkv g.mkv b.mkv colors.mkv
ffmpeg -f lavfi -i "color=red:1920x1080:duration=2.5,format=rgb24" r.mkv
ffmpeg -f lavfi -i "color=green:1920x1080:duration=2.5,format=rgb24" g.mkv
ffmpeg -f lavfi -i "color=blue:1920x1080:duration=2.5,format=rgb24" b.mkv
ffmpeg -i r.mkv -i g.mkv -i b.mkv -filter_complex '[0:0][1:0][2:0]concat=n=3:v=1:a=0[out]' -map '[out]' colors.mkv
# re-encode with h264
rm -f video.mkv
ffmpeg -i colors.mkv -framerate 24 -c:v libx264 -profile:v high -pix_fmt yuv420p -crf 22 -an video.mkv
# generate C, D, E audio
rm -f c.wav d.wav e.wav audio.wav
ffmpeg -f lavfi -i "sine=frequency=261.63:sample_rate=48000:duration=2.5" -c:a pcm_s16le c.wav
ffmpeg -f lavfi -i "sine=frequency=293.66:sample_rate=48000:duration=2.5" -c:a pcm_s16le d.wav
ffmpeg -f lavfi -i "sine=frequency=329.63:sample_rate=48000:duration=2.5" -c:a pcm_s16le e.wav
ffmpeg -i c.wav -i d.wav -i e.wav -filter_complex '[0:0][1:0][2:0]concat=n=3:v=0:a=1[out]' -map '[out]' audio.wav
# re-encode to AAC
rm -f audio.mkv
ffmpeg -i audio.wav -c:a aac -b:a 384k audio.mkv
# combine audio + video
rm -f rgb.mkv
ffmpeg -i video.mkv -i audio.mkv -map 0:v:0 -map 1:a:0 -c copy rgb.mkv
# cut each segment to 1.5 seconds
rm -f concat.txt
echo "file rgb.mkv" >> concat.txt
echo "inpoint 00:00:00.000" >> concat.txt
echo "outpoint 00:00:01.500" >> concat.txt
echo "file rgb.mkv" >> concat.txt
echo "inpoint 00:00:02.500" >> concat.txt
echo "outpoint 00:00:04.000" >> concat.txt
echo "file rgb.mkv" >> concat.txt
echo "inpoint 00:00:05.000" >> concat.txt
echo "outpoint 00:00:06.500" >> concat.txt
rm -f rgb_cut.mkv
ffmpeg -f concat -safe 0 -i concat.txt -c copy rgb_cut.mkv
# try re-encoding while cutting
rm -f rgb_cut_re-encode.mkv
ffmpeg -f concat -safe 0 -i concat.txt -c:v libx264 -profile:v high -pix_fmt yuv420p -crf 22 -c:a aac -b:a 384k rgb_cut_re-encode.mkv
rgb.mkv is generate as expected, but rgb_cut.mkv and rgb_cut_re-encode.mkv have out-of-sync and glitchy audio, even before the first cut. How can I concatenate various cuts from an existing video using ffmpeg without these issues?