audio / video:结构比标签名更重要

本示例不外链任何音视频(自包含才能离线跑),下面的播放器带有海报图但没有源文件,把 src 换成你自己的 mp4 就能播。

可用的完整结构

<video controls preload="metadata" width="1280" height="720" poster="/img/poster.jpg">
  <source src="/media/demo.av1.mp4"  type="video/mp4;codecs=av01.0.09M.08">
  <source src="/media/demo.webm"     type="video/webm">
  <source src="/media/demo.mp4"      type="video/mp4">
  <track kind="subtitles" src="/media/demo.zh.vtt" srclang="zh" label="中文" default>
  你的浏览器不支持 video 标签,这里是降级内容:<a href="/media/demo.mp4">下载视频</a>。
</video>

示例故意不给这个播放器挂 <source>(自包含的页面里不该请求不存在的文件,否则控制台会被 404 刷屏)。把上面这段整体粘进你自己的项目、换成真实路径,就是可用的多格式降级播放器。

三条规则:① <source> 从上往下试,第一个能解码的用;② 最后一定要留降级内容(不支持时的提示或下载链接);③ controls 不写就没有播放条,用户什么都点不了。

属性速查

属性作用注意
controls显示浏览器自带播放条自己实现播放条要写几十行 JS,优先用它
autoplay自动播放必须同时 muted 才生效(浏览器策略);有声音的自动播放会被拦,且对用户很不友好
muted静音与 autoplay 搭配;用户手动取消静音后策略不再限制
loop循环循环背景视频请同时写 muted playsinline preload="metadata"
playsinlineiOS 上内联播放漏了它,iPhone 会强制全屏播放器,覆盖层字幕全部失效
preloadnone / metadata / auto列表里的视频写 none 或 metadata,别一进来就下载 N 个视频
poster首帧占位图省流量也防塌陷,值可以是图片 URL 或内联 SVG
width / height固有尺寸和 img 一样:写了才不会跳版
crossorigin跨域媒体用于 canvas 时服务器要返回 CORS 头,否则读像素会报安全错误

字幕文件长这样(WebVTT)

WEBVTT

00:00:01.000 --> 00:00:04.000
第一句字幕,可以做 <i>斜体</i> 和 <c.yellow>着色</c>

00:00:04.500 --> 00:00:07.000
align:start position:0%
靠左显示的旁白

要点:文件第一行必须是 WEBVTT;kind 用 subtitles(翻译)或 captions(含音效说明,给听障用户);字幕文件与页面不同源时必须带 CORS 响应头,否则静默失败、只表现为「字幕出不来」。

响应式视频容器

视频宽度跟着容器走、高度按 16:9 算,这是最常用的写法:

16:9 容器里的海报示意
<!-- 现代写法 -->
<video controls style="width:100%;aspect-ratio:16/9" src="…" poster="…"></video>

<!-- 老写法(需要兼容很旧的浏览器时):padding 撑比例 -->
<div style="position:relative;padding-top:56.25%">
  <video style="position:absolute;inset:0;width:100%;height:100%"></video>
</div>

audio 的最简形态

<audio controls preload="none" src="/media/podcast-01.mp3">
  你的浏览器不支持 audio,<a href="/media/podcast-01.mp3">下载音频</a>。
</audio>

给一段文字配语音时,考虑直接放文字稿而不是只放播放器:音频不可检索、不可扫读,也不利于搜索引擎理解内容。