一次“有控件无画面”的视频播放问题
最近在开发一个 Next.js 项目时,需要在页面中嵌入几个 MP4 视频,用的是标准的
<video controls>标签。 结果发现一个诡异的现象:三个视频使用了完全相同的 HTML 结构,其中两个可以正常显示画面,另一个却只出现了播放控件条,画面区域一片黑/白,时间轴可以拖动,但没有图像输出。 现象
- 页面代码完全一致,仅视频文件路径不同。
- 不正常的视频:VLN1.mp4
- 正常的视频:VLN2.mp4、VLA.mp4
- 在本地文件夹中用系统播放器(如 VLC、Windows 媒体播放器)打开 VLN1.mp4 完全正常。
- 在浏览器(Chrome/Edge)以及 VSCode 的内置预览中均无法显示画面。
排查思路
排除前端代码问题 既然三个视频的
<video>标签一模一样,且有两个能正常工作,说明不是代码逻辑、CSS 或 JavaScript 的问题。 也不是服务器 MIME 类型问题(因为同一个目录下的其他 MP4 能正常加载)。怀疑视频编码格式不兼容 浏览器对视频编码的支持是有限制的。目前最广泛支持的是 H.264(AVC)视频 + AAC 音频 的组合。 很多现代浏览器不默认支持
H.265(HEVC),因为专利授权复杂且硬件解码支持不统一。使用
ffprobe查看视频编码信息 安装ffmpeg后,可以用ffprobe命令快速查看视频流的编码格式:
ffprobe -v error -show_entries stream=codec_name,profile,level -of default=noprint_wrappers=1 VLN1.mp4输出结果:
codec_name=hevc
profile=Main
level=120
codec_name=aac
profile=LC关键信息:codec_name=hevc —— 视频编码是
H.265(HEVC),而音频是AAC(正常)。 再查看正常播放的 VLN2.mp4:
ffprobe -v error -show_entries stream=codec_name,profile,level -of default=noprint_wrappers=1 VLN2.mp4输出:
codec_name=aac
profile=LC
codec_name=h264
profile=High
level=40结论:正常视频是
H.264+AAC,问题视频是HEVC+AAC。 浏览器不支持HEVC解码,所以只能解析出音频(如果有)和元数据(控件条能出现),但无法渲染视频帧。
解决方案
将 VLN1.mp4 重新编码为
H.264+AAC,并添加faststart标志(将 moov 元数据移到文件头部,优化网页渐进式播放)。
方法一:使用 ffmpeg 命令行(推荐)
ffmpeg -i VLN1.mp4 \
-c:v libx264 \
-preset medium \
-crf 23 \
-c:a aac \
-b:a 128k \
-movflags +faststart \
VLN1_fixed.mp4参数说明:
- c:v libx264:视频编码器改为 H.264
- preset medium:编码速度与压缩率的平衡(可选:fast, medium, slow)
- crf 23:恒定质量因子,18~28 之间,数值越小画质越好、体积越大;23 是默认值
- c:a aac:音频编码为 AAC
- b:a 128k:音频比特率 128kbps
- movflags +faststart:将元数据移到文件开头,网页加载时无需下载完整文件即可开始播放
