I am trying to combine a .mp4 file with a .wav file. I am rendering my mp4 with cv2 videowriter, and I don't think it has anyway of incorporating audio with it. I have tried moviepy.editor, and ffmpeg. moviepy.editor kept messing up the video file and ffmpeg repeatedly kept giving me an error that it couldn't edit existing files in-place. Combining .mp4 with another audio file type is also fine, but if so it would be nice to also answer how to convert midi files to the file type you answered with. Thanks for the help!
moviepy.editor workflow:
video = mpe.VideoFileClip(mp4_path)
os.system(f"timidity {midi_path} -Ow -o {wav_path)}") # Convert .mid to .wav
video = video.set_audio(mpe.AudioFileClip(wav_path))
video.write_videofile(mp4_path, fps=fps)
ffmpeg workflow:
video = ffmpeg.input(mp4_path)
os.system(f"timidity {midi_path} -Ow -o {wav_path)}") # Convert .mid to .wav
audio = ffmpeg.input(wav_path)
video = ffmpeg.output(video, audio, path, vcodec='copy', acodec='aac', strict='experimental')
ffmpeg.run(video)
I tested both modules and for moviepy
I get correct output video with audio even if I use the same name as output. So I don't know what can mess with output.
For ffmpeg
I had to use different name for output file to resolve problem with couldn't edit existing files in-place
I had to also use object.video
and object.audio
to replace audio in output file.
video = ffmpeg.input(video_path).video # get only video channel
audio = ffmpeg.input(audio_path).audio # get only audio channel
My testing code
def test_moviepy(video_path, audio_path, output_path='output-moviepy.mp4', fps=24):
import moviepy.editor as mpe
print('--- moviepy ---')
video = mpe.VideoFileClip(video_path)
video = video.set_audio(mpe.AudioFileClip(audio_path))
video.write_videofile(output_path, fps=fps)
def test_ffmpeg(video_path, audio_path, output_path='output-ffmpeg.mp4', fps=24):
import ffmpeg
print('--- ffmpeg ---')
video = ffmpeg.input(video_path).video # get only video channel
audio = ffmpeg.input(audio_path).audio # get only audio channel
output = ffmpeg.output(video, audio, output_path, vcodec='copy', acodec='aac', strict='experimental')
ffmpeg.run(output)
# --- main ---
video_path = 'movie.mp4'
audio_path = 'sound.wav'
output_path = 'output.mp4'
test_moviepy(video_path, audio_path)#, output_path)
test_ffmpeg(video_path, audio_path)#, output_path)
EDIT:
After installing python module graphviz
and program graphviz I could run
ffmpeg.view(output, filename='output-ffmpeg.png')
to get image