如何用ffmpeg将GoPro MP4转成浏览器兼容的音视频MP4文件
我有一批包含GPS等元数据流的GoPro MP4文件,在Windows和Linux系统的Firefox、Chrome浏览器中打开时仅能播放音频,无法播放视频,但在VLC播放器中可正常播放音视频。现需通过ffmpeg提取原文件的音视频流,生成可在浏览器播放的新MP4文件,要求转换过程中不丢失帧,可轻微压缩视频以缩小文件体积,但必须保留原文件的帧数、FPS等参数。
ffprobe分析结果(中文翻译)
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55ce62e37a00] 使用非标准帧率 59/1
输入 #0, mov,mp4,m4a,3gp,3g2,mj2, 来自 '/winclients/ASFINAG/Abnahme/GX010005.MP4':
元数据:
major_brand : mp41
minor_version : 538120216
compatible_brands: mp41
creation_time : 2021-06-07T15:21:10.000000Z
location : +48.3743+016.2383/
location-eng : +48.3743+016.2383/
firmware : HD9.01.01.00.00
时长: 00:08:51.54, 起始时间: 0.000000, 码率: 60205 kb/s
流 #0:0(eng): 视频: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 59941 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 59.94 tbc (默认)
元数据:
creation_time : 2021-06-07T15:21:10.000000Z
handler_name : GoPro H.265
encoder : GoPro H.265 encoder
timecode : 15:35:51:04
流 #0:1(eng): 音频: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 立体声, fltp, 189 kb/s (默认)
元数据:
creation_time : 2021-06-07T15:21:10.000000Z
handler_name : GoPro AAC
timecode : 15:35:51:04
流 #0:2(eng): 数据: none (tmcd / 0x64636D74) (默认)
元数据:
creation_time : 2021-06-07T15:21:10.000000Z
handler_name : GoPro TCD
timecode : 15:35:51:04
流 #0:3(eng): 数据: bin_data (gpmd / 0x646D7067), 47 kb/s (默认)
元数据:
creation_time : 2021-06-07T15:21:10.000000Z
handler_name : GoPro MET
流 #0:4(eng): 数据: none (fdsc / 0x63736466), 13 kb/s (默认)
元数据:
creation_time : 2021-06-07T15:21:10.000000Z
handler_name : GoPro SOS
输入流2的编解码器ID 0不被支持
输入流3的编解码器ID 100359不被支持
输入流4的编解码器ID 0不被支持
问题核心是主流浏览器对HEVC(H.265)编码支持有限,需转码为浏览器原生支持的H.264编码,同时严格保留原文件的帧率、帧数,实现轻微压缩:
基础转码命令(保留GPS元数据+边播边加载)
ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 23 -c:a copy -r 59.94 -map 0:0 -map 0:1 -map 0:3 -movflags +faststart output.mp4
参数说明:
-c:v libx264:使用浏览器全兼容的H.264视频编码-preset medium:平衡编码速度与压缩比,更快可选fast,更高压缩比可选slow-crf 23:恒定质量参数,23为H.264默认值,20-25区间属于轻微压缩,画质接近原片;需更小体积可上调至24/25-c:a copy:直接复制原AAC音频流(浏览器原生支持,无需转码)-r 59.94:强制匹配原文件帧率,确保帧数、播放速度完全一致-map 0:0 -map 0:1 -map 0:3:选择视频流、音频流及GPS元数据流(无需GPS可去掉-map 0:3)-movflags +faststart:将文件索引移至开头,支持浏览器边下载边播放
帧精确转码命令(严格保证不丢帧)
若需绝对保证帧数量与原文件一致,添加-vsync 0参数:
ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 23 -c:a copy -r 59.94 -vsync 0 -map 0:0 -map 0:1 -map 0:3 -movflags +faststart output.mp4
-vsync 0会让ffmpeg严格按输入帧的时间戳输出,不丢帧、不重复帧,完全匹配原文件的帧数量。
内容的提问来源于stack exchange,提问作者Matthias

