

新闻资讯
技术学院PHP仅调用ffmpeg实现视频转换,保持画质关键在于合理使用-c:v copy -c:a copy流拷贝、必要时用-crf 18等参数重编码,并确保路径、权限、输入源质量等基础环节无误。
PHP 本身不直接转视频,ffmpeg 才是真正干活的工具;PHP 只负责调用它。想“不损坏画质”,关键不是 PHP 写得多漂亮,而是 ffmpeg 命令参数是否合理、输入源是否足够干净、是否绕过了不必要的重编码。
exec() 调 ffmpeg 是唯一靠谱路径PHP 没有内置视频编解码能力,所有号称“纯 PHP 视频转换”的库(如某些 GD 或 FFmpeg 扩展封装)最终都得调 ffmpeg 二进制或依赖系统命令。自己拼命令最可控,也最容易排查问题。
shell_exec() 直接拼接用户上传的文件名——必须用 escapeshellarg() 过滤www-data 或 nginx)对输入/输出目录有读写权限ffmpeg 必须已安装且在 $PATH 中,可用 which ffmpeg 验证set_time_limit(0) 和 ini_set('memory_limit', '-1')(但更推荐异步处理)如果源文件容器格式不是 MP4(比如是 .mov、.avi、.mkv),而内部视频流已经是 H.264 + AAC,那根本不需要重新压缩——用 -c:v copy -c:a copy 就能秒转,画质 0 损失。
ffmpeg -i input.mov -c:v copy -c:a copy output.mp4
ffprobe input.mov 查看流信息:Stream #0:0(eng): Video: h264 和 Stream #0:1(eng): Audio: aac 同时存在,才适合流拷贝mp3 或视频是 vp9,则必须转码,此时画质损失不可避免,只能尽量控制-qscale:v 或 -crf 等参数做流拷贝,会强制触发重编码,反而毁画质-crf 控制质量比固定码率更稳当源流不兼容 MP4(如 ProRes、DV、无音频等),就得重编码。此时用恒定质量模式(CRF)比固定码率(-b:v)更能兼顾清晰度和体积。
ffmpeg -i input.avi -c:v libx264 -crf 18 -preset slow -c:a aac -b:a 128k output.mp4
-crf 18 是视觉无损起点(范围 0–51,越小越好;18–23 是常用平衡点)-preset slow 比 fast 或 ultrafast 编码更准、压缩更优,但耗时增加——别为省几秒牺牲质量-q:v(老参数),它和 -crf 行为不一致,容易误判
s)或 HDR,记得加 -vf "fps=30" 或 -colorspace bt709 -color_primaries bt709 -color_trc bt709 避免色彩异常很多“转完花屏/无声/黑屏”根本不是画质问题,而是基础配置漏掉:
mkdir -p dirname($output) 再执行 ffmpeg
ffprobe -v quiet -show_entries stream=codec_type -of csv=p=0 input.mp4 | grep audio
-vsync vfr 或 -copyts(视需求)-map_metadata 0 保留原始元数据exec($cmd, $output, $return_code) 检查 $return_code !== 0,再读 $output 看报错画质不丢的前提,是整个链路没出低级错误——参数对了,路径对了,权限对了,日志看了,才能谈“怎么更好”。否则再精细的 -crf 16 也救不回一个被截断的输出文件。