PHP不直接处理MKV字幕编码,乱码源于ffmpeg未正确识别原始字幕编码(如GBK/UTF-8-BOM);需用Notepad++或file/chardet确认编码,提取时加-sub_charenc参数,烧录前转为UTF-8无BOM。

PHP 本身不直接处理 MKV 字幕编码问题,乱码根源在 ffmpeg 提取或烧录字幕时未正确识别原始字幕的字符编码(通常是 GBK/GB2312 或 UTF-8-BOM)。PHP 的作用是调用 ffmpeg 命令并传入正确的编码参数,关键在命令行配置而非 PHP 逻辑。
确认字幕实际编码格式
MKV 内嵌字幕(如 ASS/SSA/SRT)常以本地编码存储,尤其是中文 Windows 环境生成的文件多为 GBK。不能只看文件扩展名或编辑器显示——需用工具验证:
- 用 Notepad++ 打开提取出的 SRT/ASS 文件 → 查看右下角编码标识(如“GBK”“UTF-8-BOM”)
- 用命令行:
file -i subtitle.srt(Linux/macOS)或chardet subtitle.srt(需安装 chardet) - 若用 mkvextract 提取:
mkvextract tracks video.mkv 3:sub.srt(3 是字幕轨道号),再检查 sub.srt 编码
ffmpeg 提取字幕时指定输入编码(-sub_charenc)
从 MKV 提取字幕文本(如转 SRT)时,必须告诉 ffmpeg 源字幕用什么编码,否则默认按 UTF-8 解码导致乱码:
- 提取 GBK 字幕:
ffmpeg -i video.mkv -map 0:s:0 -f srt -sub_charenc GBK sub.srt - 提取含 BOM 的 UTF-8:
ffmpeg -i video.mkv -map 0:s:0 -f srt -sub_charenc UTF-8-BOM sub.srt - PHP 中安全执行(注意 shell 转义):
$cmd = escapeshellcmd("ffmpeg -i 'video.mkv' -map 0:s:0 -f srt -sub_charenc GBK 'sub.srt'");<br>exec($cmd, $output, $return_code);
烧录字幕(硬字幕)时确保编码兼容
若用 ffmpeg 把字幕烧进视频(-vf subtitles=...),ASS/SSA 文件必须是 UTF-8 编码(无 BOM 更稳妥),否则 libass 渲染会出错:
立即学习“PHP免费学习笔记(深入)”;
- 先将 GBK 字幕转为 UTF-8:
iconv -f GBK -t UTF-8 sub_gbk.srt > sub_utf8.srt - 再烧录:
ffmpeg -i video.mkv -vf "subtitles=sub_utf8.srt" -c:a copy output.mp4 - PHP 中可组合调用:
exec("iconv -f GBK -t UTF-8 'sub_gbk.srt' > 'sub_utf8.srt'");,再执行 ffmpeg 烧录命令
PHP 处理建议:封装编码检测与转换
避免硬编码 GBK/UTF-8,可让 PHP 自动判断并转换:
- 用
mb_detect_encoding()粗略判断(对单字节编码效果有限,建议配合 file 命令) - 更可靠方式:调用系统
file -i或uchardet获取编码,再决定 iconv 参数 - 始终将最终用于烧录的字幕保存为 UTF-8(无 BOM):
file_put_contents('sub_final.srt', mb_convert_encoding($content, 'UTF-8', $detected_enc)); - 注意:ASS 文件头部若有
PlayResX等字段,转码后需保留原格式,避免破坏语法



















