iframe 无法直接加载 MP4,必须嵌入含 video 标签的 HTML 页面或第三方 embed 地址;iOS 需 iframe allow 属性包含 playsinline 且子页 video 同时声明 playsinline 和 webkit-playsinline;跨域下 video.play() 被禁止,须用 postMessage 通信;自动播放需 autoplay、muted、playsinline 三者齐全。

iframe src 指向 MP4 文件就注定失败
直接写 <iframe src="video.mp4"></iframe> 在手机上根本不会播放,浏览器会尝试下载或显示空白页。因为 iframe 只能加载 HTML 文档,不是视频容器。MP4 是二进制文件,没有 HTML 解析上下文,autoplay 属性压根没机会生效。
必须让 iframe 加载一个**含 <video> 标签的独立 HTML 页面**(比如 player.html),或者用第三方平台(YouTube/Bilibili)提供的 embed 地址。
- 自己托管:建
player.html,里面放<video autoplay muted playsinline src="video.mp4"></video> - 嵌 YouTube:
src="https://www.youtube.com/embed/xxx?autoplay=1&mute=1" - 嵌 Bilibili:
src="https://player.bilibili.com/player.html?bvid=xxx&autoplay=true&muted=true"
allow 属性漏了 playsinline,iOS 就强制全屏
iOS Safari 对 iframe 内视频的 inline 行为极其敏感。即使子页 <video> 本身写了 playsinline,父页 iframe 的 allow 列表里没声明,它照样跳全屏——而且无法通过 JS 拦截或还原。
正确写法是同时满足:
立即学习“前端免费学习笔记(深入)”;
allow="autoplay; encrypted-media; picture-in-picture; fullscreen; microphone; <strong>playsinline</strong>"-
allowfullscreen和兼容性属性也要带上:webkitallowfullscreen mozallowfullscreen allowfullscreen - 不要只写
allow="autoplay",这在 iOS 上等于没写
跨域 iframe 里 video.play() 被静默拒绝
如果你的 iframe 加载的是不同源的页面(比如你站嵌 YouTube),父页 JS 无法访问其内部 video 元素。调 iframe.contentDocument.querySelector('video').play() 会直接抛 SecurityError,控制台可能连错误都不报。
唯一可控路径是 postMessage:
- 子页(如
player.html)在window.onload后发消息:window.parent.postMessage({type: 'play'}, '*') - 父页监听并校验 origin:
if (event.origin !== 'https://yourdomain.com') return - 但注意:YouTube/Bilibili 不认自定义消息,必须用它们文档指定的 postMessage 命令格式
移动端自动播放依赖三要素,缺一不可
哪怕 iframe 加载的是同域页面,子页里的 <video> 仍需同时满足:
-
autoplay:声明意图 -
muted:绕过音频策略(哪怕视频没声音也得加) -
playsinline(+webkit-playsinline):iOS 必须双写,否则 fallback 到全屏
另外,type="video/mp4" 必须与真实编码严格匹配;H.264 Baseline + AAC 音频是 iOS 最稳妥组合;服务器要返回 Accept-Ranges: bytes,否则部分安卓机型加载卡住。
真机测试比模拟器可靠得多——iOS 模拟器常忽略 playsinline,而真机一点就跳全屏,这种差异只有插着 iPhone 点开看才暴露得出来。



















