不能靠video的autoplay属性自动控制,必须用swiper的@change事件配合手动play()/pause()精准调度,否则ios/安卓真机会出现声音重叠、画面卡死、静音失效等问题。

直接结论:不能靠 video 的 autoplay 属性自动控制,必须用 swiper 的 @change 事件 + 手动 play()/pause() 精准调度,否则 iOS/安卓真机会出现声音重叠、画面卡死、静音失效等连锁问题。
为什么 swiper 的 autoplay 和 video 的 autoplay 都不适用
它们的设计目标和实际场景错位了:
-
swiper的autoplay只控制翻页节奏,完全不管视频是否加载完成、是否在可视区、是否已解码——滑动中它可能还在播上一个video,而当前项 DOM 还没 ready -
video的autoplay="true"在 iOS(尤其微信 WebView)和部分安卓 APP 中被系统级拦截,即使加了muted="true"也不一定生效,必须依赖用户手势后 1 秒内调用play() - 惯性滑动时,
@change会延迟触发(尤其 iOS),导致“跳过中间项”或“播放滞后”,单纯监听它不够稳
怎么让 current 项自动播、其他项静音暂停(含预加载)
核心是「提前一帧准备」:在 @transition 中预加载临近项,在 @change 中确认并接管播放权:
- 模板里用
:ref="el => videoRefs[idx] = el"绑定每个video实例,避免uni.createVideoContext拿不到上下文 - 只对
currentIndex ± 1范围内的video调用load(),避免网络请求堆积;超出范围的统一pause()并清空src(防内存泄漏) - 在
@change回调里用$nextTick包一层再调videoContext.play(),确保 DOM 渲染完成 - iOS 真机必须搭配
playsinline、webkit-playsinline、x5-playsinline三个属性,否则微信里强制全屏
真机最常踩的三个坑
这些不是配置问题,而是平台行为差异导致的硬伤:
- iOS APP 中,
video.play()必须在@touchstart后 1 秒内执行,否则即使静音也失败——建议在@touchstart记时间戳,@change后立刻判断是否超时,超时就显示「点击播放」浮层 - 安卓低端机频繁销毁重建
videoDOM(尤其用v-if控制显隐),导致内存暴涨卡顿——改用v-show+ 手动pause()+load()重置 - 视频列表动态加载后,没重置
currentIndex,导致越界或卡在空白页——新数据 push 进videoList后,要手动校验并修正currentIndex值
真正难的不是写几行代码,而是把「播放状态」、「DOM 生命周期」、「平台策略限制」三者在每一帧里对齐。哪怕只差 10ms,iOS 就可能拒绝播放,安卓就可能卡住渲染。别迷信文档里的“支持”,真机跑一遍才是唯一验证方式。











