我一直在尝试创建一个Python应用程序,它需要一个mp4文件、一个mp3文件和一个字幕字典来生成一个输出mp4文件。
我让它工作得很好,但我发现
libx264
编解码器调用
write_videofile()
时会非常慢,尤其是使用
CompositeVideoClip
对象时。我想使用我的 GPU 来加速编码过程,因此在做了大量研究后,我做了以下操作:
- 安装 CUDA 12.5 并更新我的 1080 Ti 的驱动程序
-
安装 Gyan 的 ffmpeg 版本,该版本已经具有 nvenc 支持(使用
ffmpeg -codecs
) -
在我的Python代码中将
FFMPEG_BINARY
设置为我的路径上的内容
验证了这一点
write_videofile()
我正在使用Windows 10并且
libx264
与
FFMPEG_BINARY
编解码器一起工作得很好,甚至更改
codec='h264_nvenc'
后。但是,当我设置
moviepy
时,即使
成功完成,生成的mp4文件似乎已损坏。
它完全是黑色的,我无法播放它。
GPU_ACCELERATION = True
if GPU_ACCELERATION:
os.environ["FFMPEG_BINARY"] = FFMPEG_BINARY
这是我的代码:
# save the file
if GPU_ACCELERATION:
print("using GPU to accelerate video write")
video.write_videofile(output_path,
codec='h264_nvenc', # use NVENC for encoding
audio_codec='aac',
verbose=True)
else:
print("no GPU acceleration. expect longer times.")
video.write_videofile(output_path,
codec='libx264',
audio_codec='aac',
preset='fast',
ffmpeg_params=['-crf', '18'])
...
ffmpeg_params
我花了很长时间在
change_settings()
中传递不同的值但无济于事。我还尝试使用
moviepy.config
from
FFMPEG_BINARY
来更改
ffmpeg -i input.mp4 -c:v h264_nvenc -preset fast -b:v 1M -c:a aac output.mp4
我阅读了 ffmpeg 和 moviepy 的文档,但我找不到我的代码的问题。我还使用以下命令在 PowerShell 中直接使用 ffmpeg 进行了测试,效果很好:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\path\to\final.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.1.100
Duration: 00:00:59.50, start: 0.000000, bitrate: 4011 kb/s
Stream #0:0[0x1](und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), gbrp(pc, gbr/unknown/unknown, progressive), 606x1080 [SAR 1:1 DAR 101:180], 3870 kb/s, 60 fps, 60 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc61.3.100 h264_nvenc
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
我还在损坏的输出 mp4 上运行了 ffprobe,并且从元数据中看不到任何问题:
很高兴提供帮助!看来在使用
h264_nvenc
编解码器和 MoviePy 时遇到了问题,导致生成损坏的 MP4 文件。做的测试和研究表明问题可能与 MoviePy 与 NVENC 的特定交互方式有关,而不是与的 FFmpeg 设置有关。
让我们来解决这个问题。以下是一些需要检查和尝试的调试步骤:
1. 验证像素格式:
- NVENC 编码器通常需要 YUV444p 或 YUV420p 像素格式的输入。确认 MoviePy 传递给 FFmpeg 的视频帧符合这些格式。
-
可以在 FFmpeg 命令中添加
-pix_fmt yuv420p
来强制进行像素格式转换。这可以通过ffmpeg_params
在 MoviePy 中完成。
2. 调整比特率和预设:
-
尝试了不同的
ffmpeg_params
,但这值得再次尝试。较低的比特率或更快的预设可能会导致 NVENC 出现问题,尤其是在较旧的 GPU 上。 -
尝试增加比特率 (
-b:v
) 并使用更慢的预设(例如-preset medium
或-preset slow
)。
3. 更新 MoviePy:
- 确保使用的是最新版本的 MoviePy。有时,旧版本可能存在与硬件加速相关的兼容性问题。
-
可以使用
pip install --upgrade moviepy
更新 MoviePy。
4. 测试简化示例:
-
为了隔离问题,尝试使用
h264_nvenc
编解码器和 MoviePy 创建一个非常简单的视频(例如,具有纯色背景和一些文本)。如果此操作有效,则问题可能在于主项目中更复杂的视频合成。
5. 检查 GPU 驱动程序和 CUDA 版本:
- 虽然已经更新了驱动程序,但有时较新的驱动程序版本可能引入新的问题。尝试安装较旧但稳定的驱动程序版本,看看是否能解决问题。
- 此外,请确保的 CUDA 版本与的 GPU 和 FFmpeg 版本兼容。
示例代码(使用像素格式转换):
import os
from moviepy.editor import *
GPU_ACCELERATION = True
if GPU_ACCELERATION:
os.environ["FFMPEG_BINARY"] = FFMPEG_BINARY
# ... your video creation code ...
if GPU_ACCELERATION:
print("使用 GPU 加速视频写入")
video.write_videofile(
output_path,
codec='h264_nvenc',
audio_codec='aac',
ffmpeg_params=['-pix_fmt', 'yuv420p', '-b:v', '5M', '-preset', 'medium'], # 添加像素格式和比特率
verbose=True
)
else:
# ... your existing CPU encoding code ...
如果在尝试了这些步骤后问题仍然存在,请提供以下附加信息,以便我进一步帮助:
- 的 GPU 型号
- 正在使用的 MoviePy、FFmpeg 和 CUDA 驱动程序的确切版本
-
FFmpeg 命令的完整输出(包含在
verbose=True
中) - 如果可能,请提供一个小的代码示例,以便重现该问题。
祝编码顺利!
标签:python,video,ffmpeg,moviepy,nvenc From: 78781458