uni-app video组件三端行为差异大:ios微信需静音+用户手势触发才可autoplay;app端需启用videoplayer模块;h5端chrome要求muted,safari还需playsinline;小程序需合法域名且poster须https。

uni-app 的 video 组件在 H5、App 和小程序三端行为不一致,直接照搬 HTML5 写法大概率会失效;关键参数如 autoplay、muted、controls 必须配合平台特性使用,否则 iOS 微信里点不动、Android 打不开、小程序静音也播不了。
为什么 autoplay 在 iOS 微信里无效
不是 bug,是 Safari 和微信 WebView 的策略限制:iOS 端所有自动播放必须满足「静音 + 用户手势触发过一次」两个条件。即使你写了 autoplay="true" muted="true",首次进入页面仍不会播——除非用户已点击过页面任意位置(比如弹个提示框再关掉),后续路由跳转或 v-if 切换才可能生效。
- App 端(Android/iOS)可正常启用
autoplay,但需确保 manifest.json 中已勾选 VideoPlayer 模块,否则打包后白屏无报错 - H5 端依赖浏览器策略,Chrome 70+ 要求
muted为 true 才允许 autoplay;Safari 更严格,还要求playsinline属性存在 - 小程序端(微信/支付宝)对 autoplay 支持较好,但需注意:微信要求视频域名在 request 合法域名列表中,否则直接拒绝加载
poster 和 show-center-play-btn 怎么协同工作
poster 是视频封面图,但只在视频未开始播放时显示;而 show-center-play-btn 控制中间大播放按钮是否出现——它默认为 true,设为 "disable"(字符串,不是布尔值)才会隐藏。
- 若同时设置
poster和show-center-play-btn="disable",封面图仍显示,但用户无法点击启动播放,必须靠外部按钮调用this.$refs.video.play() - 微信小程序中,
poster图片必须是 HTTPS 地址,本地 static 目录路径(如../../static/cover.jpg)会被忽略 - App 端的 poster 渲染有时延迟,建议加 loading 占位或用 CSS 背景图 fallback
如何让视频在 iOS 微信里真正「自动静音播放」
光写属性不够,得补上三件事:playsinline、webkit-playsinline、x5-video-player-type,且必须用 setAttribute 动态挂载,模板里写死无效。
- 在
onReady钩子中获取 video 实例:const video = uni.createVideoContext('myVideo', this),然后用原生 DOM 操作追加属性 - 必须设置:
videoEl.setAttribute('playsinline', 'true')、videoEl.setAttribute('webkit-playsinline', 'true')、videoEl.setAttribute('x5-video-player-type', 'h5') - 如果视频地址是 m3u8 流,还需额外加
videoEl.setAttribute('x5-video-player-fullscreen', 'false'),否则安卓 X5 内核会强制全屏 - 部分安卓厂商(如华为)需要
videoEl.setAttribute('x5-video-orientation', 'portraint')防止横屏闪退
刷新视频 src 为什么没反应?
video 组件的 src 变更不会自动 reload,尤其当新旧地址仅 query 参数不同(如 ?t=123 → ?t=456)时,浏览器会直接复用缓存的解码器实例,导致画面卡住或黑屏。
- 最稳妥方式是用
v-if销毁重建:<video v-if="videoKey" :src="currentSrc" :id="videoId"></video>,切换时先this.videoKey = false,this.$nextTick(() => { this.videoKey = true }) - 不要依赖
load事件监听重载完成,App 端该事件常不触发;改用timeupdate或canplay判断是否真正可播 - 若用
ref调用play()失败,检查是否处于非活跃 tab(如微信后台切回来),此时需监听visibilitychange事件后手动恢复
最易被忽略的是:App 端 video 组件实际由原生 SDK 渲染,DOM 操作仅作用于占位节点,真播放器生命周期不受 Vue 响应式控制;所以任何「想用 data 控制播放状态」的思路,在 App 端都得绕道原生 API 或 plus.video 补充实现。











