ffmpeg使用GPU加速
前言
因为我想要将视频文件和弹幕合并成一个文件,视频和弹幕分别放在testMp4和testDanmu文件夹下。于是就想着在实验室的服务器上用FFmpeg合并,但是文件有好几百个,一行一行的执行太麻烦,就想到写个脚本来处理。
原理分析
FFmpeg默认合并命令使用 CPU 编解码,不使用GPU加速,如ffmpeg -i input.mp4 -vf "ass=subtitle.ass" -c:a copy output.mp4
,而转码速度非常慢,并且期间CPU 使用率非常高,那么就不能干其他事了。
如果要使用GPU加速,只需要通过添加参数-vcodec
和 -hwaccel cuda
指定视频编码器和cuda加速就行了,而所使用的编码器必须支持 cuda。
通过命令ffmpeg -codecs | grep cuvid
查看支持cuda的编码器。
copy
DEV.L. av1 Alliance for Open Media AV1 (decoders: libdav1d libaom-av1 av1 av1_cuvid av1_qsv) (encoders: libaom-av1 libr av1e libsvtav1 av1_nvenc av1_qsv av1_vaapi) DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_qsv h264_cuvid) (encoders: libx2 64 libx264rgb h264_nvenc h264_qsv h264_v4l2m2m h264_vaapi) DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_qsv hevc_v4l2m2m hevc_cuvid) (encoders: lib x265 hevc_nvenc hevc_qsv hevc_v4l2m2m hevc_vaapi) DEVIL. mjpeg Motion JPEG (decoders: mjpeg mjpeg_cuvid mjpeg_qsv) (encoders: mjpeg mjpeg_qsv mjpeg_vaapi) DEV.L. mpeg1video MPEG-1 video (decoders: mpeg1video mpeg1_v4l2m2m mpeg1_cuvid) DEV.L. mpeg2video MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_v4l2m2m mpeg2_qsv mpeg2_cuvid) (encoders: mpeg2video mpeg 2_qsv mpeg2_vaapi) DEV.L. mpeg4 MPEG-4 part 2 (decoders: mpeg4 mpeg4_v4l2m2m mpeg4_cuvid) (encoders: mpeg4 libxvid mpeg4_v4l2m2m) D.V.L. vc1 SMPTE VC-1 (decoders: vc1 vc1_qsv vc1_v4l2m2m vc1_cuvid) DEV.L. vp8 On2 VP8 (decoders: vp8 vp8_v4l2m2m libvpx vp8_cuvid vp8_qsv) (encoders: libvpx vp8_v4l2m2m vp8_vaapi) DEV.L. vp9 Google VP9 (decoders: vp9 vp9_v4l2m2m libvpx-vp9 vp9_cuvid vp9_qsv) (encoders: libvpx-vp9 vp9_vaapi vp9_qsv)
因此可以使用命令ffmpeg -hwaccel cuda -i "input.mp4" ass=input.ass" -c:v h264_nvenc -c:a copy "output.mp4"
来合并,如果你要使用FFmpeg的其它命令,只需加上-hwaccel cuda
和-c:v h264_nvenc
即可
实践
编写脚本
在testMp4父目录内执行vim process_videos.sh
将下面这段脚本粘贴进去。
copy
# 设置输入和输出目录 VIDEO_DIR="testMp4" DANMU_DIR="testDanmu" OUTPUT_DIR="processed_videos" mkdir -p "$OUTPUT_DIR" # 获取所有视频文件 for video in "$VIDEO_DIR"/*.mp4; do base_name=$(basename "${video%.mp4}") subtitle="$DANMU_DIR/${base_name}.ass" output="${OUTPUT_DIR}/processed_${base_name}.mp4" # 检查弹幕文件是否存在 if [ -f "$subtitle" ]; then # 使用 FFmpeg 合并视频和弹幕 ffmpeg -hwaccel cuda -i "$video" -vf "ass=$subtitle" -c:v h264_nvenc -c:a copy "$output" echo "$video 已经合并好了,合并后文件为 $output" else echo "没找到 $video对应的弹幕文件" fi done echo "所有视频均已合并完毕"
修改脚本权限
copy
chmod +x process_videos.sh
运行脚本
copy
./process_videos.sh
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步