uni-app 使用 uni.createVideoContext(videoId, this)方法调用打开全屏后,再调用exitFullScreenAPI同时隐藏video组件(v-if)会导致整个应用关闭

uni-app 使用 uni.createVideoContext(videoId, this)方法调用打开全屏后,再调用exitFullScreenAPI同时隐藏video组件(v-if)会导致整个应用关闭

操作步骤:

  • 开一个nvue,使用video组件加v-if,调用createVideoContext,再调用全屏,关闭全屏同video的组件中v-if值为false,ios端的问题

预期结果:

  • 把全屏关掉同时video组件隐藏

实际结果:

  • 整个应用关闭

bug描述:

视频中点击返回按钮 会调用这两个方法,ios端直接把应用关闭了,安卓端正常

| 项目信息 | 详情 |
| --- | --- |
| 产品分类 | uniapp/App |
| PC开发环境操作系统 | Mac |
| PC开发环境操作系统版本号 | macOS Monterey |
| HBuilderX类型 | 正式 |
| HBuilderX版本号 | 3.2.16 |
| 手机系统 | iOS |
| 手机系统版本号 | iOS 15 |
| 手机厂商 | 苹果 |
| 手机机型 | iphone13 |
| 页面类型 | nvue |
| vue版本 | vue2 |
| 打包方式 | 云端 |
| 项目创建方式 | HBuilderX | 


更多关于uni-app 使用 uni.createVideoContext(videoId, this)方法调用打开全屏后,再调用exitFullScreenAPI同时隐藏video组件(v-if)会导致整个应用关闭的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

【社区问题/bug处理优先级规则】:https://ask.dcloud.net.cn/article/38139

更多关于uni-app 使用 uni.createVideoContext(videoId, this)方法调用打开全屏后,再调用exitFullScreenAPI同时隐藏video组件(v-if)会导致整个应用关闭的实战教程也可以访问 https://www.itying.com/category-93-b0.html


提供一下可复现问题的工程

提交了demo问题

这是一个已知的 iOS 平台特定问题,涉及 video 组件在 nvue 页面中的生命周期管理。当 video 组件处于全屏状态时,直接通过 v-if 将其销毁,会导致 iOS 系统视频播放控制器发生异常,进而可能触发应用级错误(表现为应用闪退或关闭)。

核心原因
在 iOS 上,全屏视频播放由原生控件接管。如果视频仍在全屏状态下,直接移除 video 组件(v-if 设为 false),原生层会因无法正常退出全屏而引发系统级错误。

解决方案
确保退出全屏操作完成后再隐藏或销毁 video 组件。可以通过以下步骤实现:

  1. 监听全屏状态变化:使用 video 组件的 [@fullscreenchange](/user/fullscreenchange) 事件,或在调用 exitFullScreen() 后通过定时器或回调确保全屏已完全退出。
  2. 延迟隐藏组件:在调用 exitFullScreen() 后,延迟一段时间(例如 300ms)再设置 v-iffalse,确保原生层完成全屏退出流程。

示例代码调整

// 在 video 组件上添加事件监听
<video 
  ref="videoRef"
  v-if="showVideo"
  [@fullscreenchange](/user/fullscreenchange)="onFullscreenChange"
/>

// 在方法中处理
methods: {
  async closeVideo() {
    const videoContext = uni.createVideoContext('videoId', this);
    // 先退出全屏
    videoContext.exitFullScreen();
    // 不立即隐藏,等待全屏退出完成
  },
  onFullscreenChange(e) {
    if (!e.fullScreen) {
      // 确认全屏已退出后,再隐藏 video 组件
      setTimeout(() => {
        this.showVideo = false;
      }, 100);
    }
  }
}
回到顶部