视频音频处理与图片合成完整教程
在日常多媒体制作中,我们经常需要从视频中提取音频,分离人声与背景音乐,并在纯背景音乐上叠加图片生成新视频。本教程将通过 Python 脚本实现整个流程,实现音频提取、音源分离和视频合成的工程化处理。
所用工具:
- Python 3.10:用于编写视频处理脚本,兼顾稳定性和库兼容性
- FFmpeg:音视频处理开源工具,由法国天才程序员 Fabrice Bellard 开发
- MoviePy 1.0.3:Python 视频编辑库,底层调用 FFmpeg
- Demucs:Meta(原 Facebook AI Research)开源的 AI 音源分离工具
工具介绍
Python
- 灵活易用,适合小团队快速开发
- 由于第三方库兼容性问题,稳定版本多集中在 3.7–3.10,因此选择 Python 3.10
FFmpeg
- 功能强大的音视频处理库,可以处理几乎所有音视频格式
- 作者 Fabrice Bellard 还开发了 QEMU(虚拟机模拟器)和 TinyCC(小巧的 C 编译器)等项目
MoviePy
- 基于 Python 的视频编辑库,底层调用 FFmpeg
- 简单易用,适合快速脚本化处理视频
- 可实现视频剪辑、拼接、特效、字幕、音视频合成及逐帧操作
Demucs
- AI 音源分离工具,可将音乐文件分离成人声、鼓、贝斯、伴奏等轨道
- 基于深度学习(卷积 + 循环神经网络 / Transformer),分离效果优于传统滤波器
- 可提取纯背景音乐,去除人声,用于后续视频合成
操作步骤
第 1 步:提取视频音频
假设视频文件名为 video.mp4,使用 FFmpeg 提取音频:
ffmpeg -i video.mp4 -vn -acodec copy video.aac
说明:
-vn:忽略视频流,只处理音频-acodec copy:保持原始音频格式,无损拷贝
💡 提示:快速获得视频原始音轨,方便后续处理
第 2 步:分离人声
使用 Demucs 分离人声和伴奏:
demucs video.aac --two-stems=vocals
输出目录通常为 separated/audio/,文件包括:
vocals.wav:人声novocals.wav:伴奏/背景音乐
只需要背景音乐时,将 novocals.wav 重命名为 bgm.wav 即可。
💡 小技巧:
- 若需要完整多轨分离(鼓、贝斯、其他乐器),可直接运行
demucs video.aac- 输出会包含所有轨道,方便高级音频处理
第 3 步:叠加图片生成视频(固定尺寸版本)
from moviepy.editor import ImageClip, concatenate_videoclips, AudioFileClip
# 批量读取图片
image_files = [
"img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg",
"img6.jpg", "img7.jpg", "img8.jpg", "img9.jpg", "img10.jpg",
"img11.jpg", "img12.jpg", "img13.jpg", "img14.jpg", "img15.jpg",
"img16.jpg", "img17.jpg"
]
# 背景音乐
audio_file = "bgm.wav"
audio = AudioFileClip(audio_file)
num_images = len(image_files)
fade_duration = 1.0 # 图片切换淡入淡出时长(秒)
# 修正每张图片显示时长(包含过渡)
duration_per_image = (audio.duration + (num_images - 1) * fade_duration) / num_images
# 生成图片片段
clips = [ImageClip(img).set_duration(duration_per_image) for img in image_files]
# 拼接视频片段并添加过渡效果
video = concatenate_videoclips(clips, method="compose", padding=-fade_duration)
# 添加背景音乐,并确保视频总时长与音频一致
final_video = video.set_audio(audio).set_duration(audio.duration)
# 输出最终视频
final_video.write_videofile("output.mp4", fps=24, codec="libx264", audio_codec="aac")
- 批量读取图片并按顺序生成视频
- 两张图片切换时有淡入淡出效果
- 视频长度与背景音乐一致
⚠️ 注意:如果图片尺寸不统一,可能会出现黑边或拉伸
第 4 步:叠加图片生成视频(自动适配大小版本)
from moviepy.editor import ImageClip, concatenate_videoclips, AudioFileClip
image_files = [
"img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg",
"img6.jpg", "img7.jpg", "img8.jpg", "img9.jpg", "img10.jpg",
"img11.jpg", "img12.jpg", "img13.jpg", "img14.jpg", "img15.jpg",
"img16.jpg", "img17.jpg"
]
audio_file = "bgm.wav"
audio = AudioFileClip(audio_file)
num_images = len(image_files)
fade_duration = 1.0
video_size = (1920, 1080) # 视频输出分辨率,可修改
# 修正每张图片显示时长
duration_per_image = (audio.duration + (num_images - 1) * fade_duration) / num_images
clips = []
for img_path in image_files:
clip = ImageClip(img_path).set_duration(duration_per_image)
# 按高度缩放,同时保持宽高比
clip = clip.resize(height=video_size[1])
# 获取缩放后的尺寸
w, h = clip.size
x_offset = (video_size[0] - w) // 2
y_offset = (video_size[1] - h) // 2
# 添加黑色边框填充,使图片居中
clip = clip.margin(left=x_offset, right=x_offset, top=y_offset, bottom=y_offset, color=(0, 0, 0))
clips.append(clip)
# 拼接视频片段并添加过渡
video = concatenate_videoclips(clips, method="compose", padding=-fade_duration)
# 添加背景音乐,并确保视频总时长与音频一致
final_video = video.set_audio(audio).set_duration(audio.duration)
# 输出最终视频
final_video.write_videofile("output.mp4", fps=24, codec="libx264", audio_codec="aac")
✅ 特点:
- 自动适配所有图片大小
- 保持图片比例,黑边填充避免拉伸
- 视频总时长与背景音乐一致
- 图片切换时有淡入淡出效果
总结
通过以上步骤,我们实现了:
- 提取音频:FFmpeg 无损提取视频原始音轨
- 分离人声:Demucs 得到纯背景音乐
- 生成视频:MoviePy 拼接图片并叠加背景音乐
- 自动适配图片大小:保证视频中每张图片完整显示
⚡ 小技巧:
- 可脚本化批量处理大量图片
- 调整
fade_duration可以控制淡入淡出效果- 可结合字幕、特效等进一步丰富视频