video src不生效主因是跨域未配cors、file://协议被禁、混用src与source导致外层src被忽略、移动端编码不兼容或preload不当、js动态赋值后未调用load()。

video src 属性不生效的常见原因
直接写 src 却看不到视频,大概率不是语法错,而是资源加载被拦了。浏览器对 video 的 src 有明确限制:跨域资源必须带 CORS 响应头,否则即使地址正确、网络通,控制台也会静默失败(部分浏览器连错误都不报)。
本地开发时用 file:// 协议打开 HTML,绝大多数浏览器会直接拒绝加载本地视频文件——这不是 bug,是安全策略。解决方式只有两个:http:// 或 https:// 协议访问,哪怕只是 localhost:8080。
- 检查浏览器开发者工具 Network 面板,看视频请求是否返回 200,响应头是否含
Access-Control-Allow-Origin - 避免在
src中写相对路径如./videos/demo.mp4后忘了起服务,直接双击 HTML 打开必失败 - 不要把视频放在 GitHub Pages 根目录就以为能直链——GitHub Pages 默认不给静态资源加 CORS 头,需换托管或加代理
src 和 source 元素混用时的优先级问题
<video></video> 支持两种写法:一种是直接写 src 属性,另一种是嵌套多个 <source></source>。二者不能混用——一旦用了 <source></source>,浏览器就**完全忽略**外层 video 的 src 属性,哪怕它存在。
这种设计是为了让浏览器按 type 和 media 自主选择最合适的资源,但代价是调试时容易误判。比如你写了:
<video controls src="fallback.mp4"><source src="demo.webm" type="video/webm"><source src="demo.mp4" type="video/mp4"></source></source></video>
实际播放的是 demo.webm 或 demo.mp4,fallback.mp4 永远不会被加载。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 想留 fallback,只能靠 JS 监听
error事件后手动设置video.src -
<source></source>的type必须准确,比如写成video/mp4而不是mp4,否则浏览器可能跳过该条目 - 多个
<source></source>的顺序有影响:浏览器从上到下尝试,第一个能播的就停,不继续往下找
移动端 video src 加载失败的特殊表现
iOS Safari 和 Android Chrome 对自动播放和资源加载更激进。即使 src 地址完全合法,也可能出现「有控件、没画面、无报错」的假死状态——本质是视频元数据(duration、dimensions)没加载完,而 preload 属性默认值在不同平台不一致。
典型症状:点击播放按钮没反应,但拖动进度条突然能播;或者只出声音没画面。这往往是因为视频容器格式或编码参数不符合移动端硬解要求(比如 H.264 的 profile 必须是 Main 或 Baseline,不能是 High)。
- 强制指定
preload="metadata",避免 iOS 在页面加载时就试图下载整个视频 - 用
ffmpeg重编码时加上-profile:v baseline -level 3.0,确保兼容性 - 不要依赖
canplay事件判断“已就绪”,移动端更可靠的是监听loadedmetadata+readyState >= 1
src 动态赋值时的注意事项
用 JS 改 video.src 后不生效?不是代码没执行,而是浏览器不会自动调用 load()。DOM 属性变了,但内部加载器没触发,得手动唤起:
const v = document.querySelector('video');
v.src = 'new.mp4';
v.load(); // 必须加这一句
v.play().catch(e => console.error('Auto-play rejected:', e));
另外,频繁切换 src 可能导致内存泄漏或解码器卡死,尤其在低配安卓机上。建议每次换源前先调用 v.pause() 和 v.removeAttribute('src'),再设新值。
- 动态设置后立即
play(),大概率被浏览器拦截(需用户手势触发),要捕获 Promise rejection 并提示用户点击播放 - 如果新
src和旧的一样,load()不会重载,但load()+play()组合在某些版本 Chrome 下会触发重复解码,建议加简单比对 - SSR 渲染时,服务端无法识别
video,所以src最好延迟到客户端 hydrate 后再注入,避免首屏渲染空白或报错
src 不等于视频就能播。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










