uni-app视频组件真机问题根源在于跨端渲染差异:iOS用AVPlayer、Android用VideoView、H5用原生video,导致格式、路径、加载时机、横屏、全屏、HLS支持及事件行为均不一致,需按平台分别适配。

uni-app 里 <video> 组件不播放、黑屏或报错
真机上常见表现是:控制台没报错但画面纯黑,或者提示 DOMException: The element has no supported sources。根本原因不是组件写错了,而是 uni-app 的 <video> 是个“壳”——它在不同平台渲染成不同原生控件(iOS 用 AVPlayer,Android 用 VideoView,H5 用原生 <video>),而各端对视频格式、路径、加载时机的要求差异极大。
实操建议:
- 视频必须走 HTTPS(尤其 iOS 和微信小程序),HTTP 地址在真机上直接静默失败
- H5 端支持
.mp4(H.264 + AAC)、.webm;微信小程序只认.mp4;App 端 Android 对编码更敏感,优先用avc1.42E01E编码的 MP4 - 不要用相对路径如
./videos/demo.mp4,资源得放static/目录下,用绝对路径/static/videos/demo.mp4 - 首次播放前确保
src已赋值且非空字符串,异步设置src后需手动调用this.$refs.video.play()(H5 有效,App 端不一定)
uni-app 视频全屏、横屏适配在 App 端失效
微信小程序里 direction="1" 能强制横屏,但在 uni-app 编译为 App 时完全不生效——因为 App 端的横屏逻辑由原生层控制,<video> 组件本身无权切换屏幕方向。
实操建议:
- App 端横屏必须在
manifest.json里全局配置:"orientation": "landscape"(整个应用横屏)或通过plus.screen.lockOrientation("landscape-primary")动态锁定(需在onReady后调用) - 全屏按钮点击后,别只靠
show-fullscreen-btn属性,要配合fullscreen-change事件监听,并在回调里手动调用plus.screen.lockOrientation或uni.setScreenBrightness等原生 API - 安卓真机上,部分厂商(如华为、小米)会拦截
requestFullscreen,需在nativePlugins中配置权限或使用自定义原生插件接管全屏逻辑
uni-app 视频播放卡顿、进度条拖动失败
常见于从服务器拉流或分段视频(如 HLS),表现为拖动后卡住、反复 loading、timeupdate 事件不触发。这不是前端代码问题,而是 uni-app 的 <video> 在非 H5 端不支持 HLS(.m3u8)协议,也不支持 MSE。
实操建议:
- 避免直接传
.m3u8地址给<video src="xxx.m3u8">—— 微信小程序和 App 均不识别,只会显示“无法播放” - 需要 HLS 播放,H5 端可用
hls.js,但 App 和小程序必须换方案:App 用原生插件(如uni-plugin-html5-video),小程序用live-player(仅直播)或转封装为 MP4 - 服务端务必开启
Accept-Ranges: bytes响应头,否则拖动时无法按 byte range 请求,导致只能从头加载 - 安卓低端机上,视频分辨率超过 720p 易卡顿,建议服务端提供多清晰度版本,前端用
uni.getSystemInfo判断设备性能后选择合适 URL
uni-app 视频组件事件在不同平台行为不一致
play、pause、ended 这些事件在 H5 上触发及时,在 App 端可能延迟几百毫秒甚至丢失,微信小程序则对 error 事件捕获极弱(比如网络中断常无响应)。
实操建议:
- 别依赖单一事件做状态同步,例如用
playing代替play判断是否真在播(playing更可靠) - 错误处理不能只靠
@error,要在@timeupdate里加超时检测:如果连续 3 秒video.currentTime不变,大概率已卡死,主动调用load()重载 - App 端需监听
fullscreenchange,但该事件在 iOS App 中不触发,得改用plus.webview.currentWebview().addEventListener('resize', ...)监听窗口尺寸变化来间接判断 - 所有事件回调里避免执行耗时操作(如请求接口、复杂计算),否则会阻塞视频解码线程,加剧卡顿


















