Reputation: 71580
I recently installed moviepy
and wanted to edit videos with it.
I saw that people recommend using the moviepy
ffmpeg_tools
for better performance.
So I tried this code:
moviepy.ffmpeg_tools.ffmpeg_extract_audio('before.mp4', 'audio.wav')
moviepy.ffmpeg_tools.ffmpeg_merge_video_audio('after.mp4', 'audio.wav', 'new.mp4')
But it gave this error:
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
I saw that it successfully saved the audio into a separate file audio.wav
, but the problem is that it doesn't merge the video with the audio.
I searched and found some similar questions, like this one, but I can't figure out how to implement this into my code.
Upvotes: 1
Views: 1035
Reputation: 32094
The default codec arguments of ffmpeg_merge_video_audio
are vcodec='copy'
and acodec='copy'
.
There are many cases when copying the codec is not going to work.
For example:
MP4 container with pcm_s16le audio codec and H.264 video codec is not supported.
Try specifying audio codec and video codec:
from moviepy.video.io import ffmpeg_tools
ffmpeg_tools.ffmpeg_extract_audio('before.mp4', 'audio.wav')
ffmpeg_tools.ffmpeg_merge_video_audio('after.mp4', 'audio.wav', 'new.mp4', vcodec='libx264', acodec='aac')
I tried reproducing the error, using synthetic patterns.
I used FFmpeg command line tool, for building the patterns (used as input):
ffmpeg -y -r 25 -f lavfi -i testsrc=size=192x108:rate=30 -f lavfi -i sine=frequency=400 -f lavfi -i sine=frequency=1000 -filter_complex amerge -vcodec libx264 -crf 17 -pix_fmt yuv420p -acodec aac -ar 22050 -t 30 before.mp4
ffmpeg -y -r 25 -f lavfi -i testsrc=size=192x108:rate=30 -vcodec libx264 -crf 17 -pix_fmt yuv420p -t 30 after.mp4
Executing your original code with the patterns as input gives me an error:
Moviepy - Command returned an error
Traceback (most recent call last):
...
OSError: ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9.2.1 (GCC) 20200122 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, wav, from 'audio.wav': Metadata: encoder : Lavf58.29.100 Duration: 00:00:30.00, bitrate: 1411 kb/s Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'after.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.45.100 Duration: 00:00:30.00, start: 0.000000, bitrate: 42 kb/s Stream #1:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 192x108 [SAR 1:1 DAR 16:9], 41 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: handler_name : VideoHandler [mp4 @ 0000018d8b0a33c0] Could not find tag for codec pcm_s16le in stream #1, codec not currently supported in container Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument Stream mapping: Stream #1:0 -> #0:0 (copy) Stream #0:0 -> #0:1 (copy) Last message repeated 1 times
codec not currently supported in container
is not the same as your error, but it's almost the same...
I don't know what audio and video codes you are using.
In case you are using AAC and H.264 codecs, and you want to copy the codecs (avoid transcoding), you can try the following code sample:
from moviepy.video.io import ffmpeg_tools
ffmpeg_tools.ffmpeg_extract_audio('before.mp4', 'audio.mp4') # Extract the audio to mp4 container
ffmpeg_tools.ffmpeg_merge_video_audio('after.mp4', 'audio.mp4', 'new.mp4')
Extracting the audio to audio.mp4
copies the AAC audio stream (without transcoding the audio to PCM codec).
Upvotes: 1