在使用 ffmpeg 处理视频时,只要没有使用 -c:v copy
, 就涉及到视频的重新编码,默认将使用软解,在处理大视频时,非常耗时,而要启用硬解,涉及到4个硬件 3个操作系统 及各种不同视频编码格式,不同操作系统不同硬件平台,可用的编码解码器又各不相同,想想就头大,处理兼容性就够喝一壶的。
下方图表是ffmpeg官方提供的硬件兼容表格,各种刺眼的 "N"
四大硬件:Intel AMD apple Nvidia
三大操作系统:Windows Linux MacOS
各种编码格式: H.264 / H.265 / VP8 / VP9 / MJPEG / MPEG-2 等
硬件解码|硬件编码
ffmpeg对这些平台和操作系统都有支持,其中AMD的支持较差,略过不提。
另外只讨论 H.264/H.265 这2种最常用的视频编码格式,忽略其他。
只谈硬件编码,暂时忽略硬件解码。
查看本机安装的ffmpeg支持的编码器
ffmpeg -encoders
Windows系统下可用的硬件编码
hevc_前缀代表适用于H.265编码的加速器
默认编码器:libx264 / libx265
转码举例: ffmpeg -i 1.mp4 -c:v libx264 out.mp4
ffmpeg -i 1.mp4 -c:v libx265 out.mp4
Intel 硬件编码加速器:h264_qsv / hevc_qsv
查看本机ffmpeg是否支持:ffmpeg -encoders|findstr h264_qsv
转码举例: ffmpeg -i 1.mp4 -c:v h264_qsv out.mp4
Nvidia 硬件编码加速器: h264_nvenc nvenc_h264 / hevc_nvenc nvenc_hevc
转码举例: ffmpeg -i 1.mp4 -c:v h264_nvenc out.mp4
查看本机ffmpeg是否支持:ffmpeg -encoders|findstr h264_nvenc
Linux系统下可用的硬件编码
hevc_前缀代表适用于H.265编码的加速器
默认编码器:libx264 / libx265
转码举例: ffmpeg -i 1.mp4 -c:v libx264 out.mp4
Intel 硬件编码加速器: h264_vaapi / hevc_vaapi
转码举例: ffmpeg -i 1.mp4 -c:v h264_vaapi out.mp4
查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_vaapi
Nvidia 硬件编码加速器:h264_nvenc nvenc_h264 / hevc_nvenc nvenc_hevc
转码举例: ffmpeg -i 1.mp4 -c:v h264_nvenc out.mp4
查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_nvenc
MacOS系统可用的硬件编码
hevc_前缀代表适用于H.265编码的加速器
默认编码器:libx264 / libx265
转码举例: ffmpeg -i 1.mp4 -c:v libx264 out.mp4
Intel 硬件编码加速器:h264_videotoolbox / hevc_videotoolbox
转码举例: ffmpeg -i 1.mp4 -c:v h264_videotoolbox out.mp4
查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_videotoolbox
Apple Silicon硬件加速:h264_videotoolbox / hevc_videotoolbox
转码举例: ffmpeg -i 1.mp4 -c:v h264_videotoolbox out.mp4
查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_videotoolbox
判断当前系统可用硬件加速器
def get_video_codec():
import platform,subprocess
from pathlib import Path
plat=platform.system()
mp4_test="test.mp4"
mp4_target="target.mp4"
codec='libx264'
if plat in ['Windows','Linux']:
import torch
if torch.cuda.is_available():
codec='h264_nvenc'
elif plat=='Windows':
codec='h264_qsv'
elif plat=='Linux':
codec='h264_vaapi'
elif plat=='Darwin':
codec='h264_videotoolbox'
s=time.time()
try:
subprocess.run([
"ffmpeg",
"-y",
"-hide_banner",
"-ignore_unknown",
"-i",
mp4_test,
"-c:v",
codec,
mp4_target
],
check=True,
creationflags=0 if sys.platform != 'win32' else subprocess.CREATE_NO_WINDOW)
# except subprocess.CalledProcessError as e:
except Exception as e:
print('error='+str(e))
return 'libx264'
finally:
print(f'time={time.time()-s}')
return codec