uni-app 高版本IOS系统 在web-view中使用uni.postMessage 导致视频暂停播放

发布于 1周前 作者 nodeper 来自 Uni-App

uni-app 高版本IOS系统 在web-view中使用uni.postMessage 导致视频暂停播放

示例代码:

uni.postMessage({  
    data: {  
        type: "wvLightControl",  
        value: lightEnabled  
    }  
});

操作步骤:

调用uni.postMessage 方法, 视频就会卡死

预期结果:

调用uni.postMessage 方法, 视频正常播放

实际结果:

调用uni.postMessage 方法, 视频就会卡死

bug描述:

高版本iOS系统 在web-view中使用uni.postMessage ,导致视频暂停播放

信息类别 信息内容
产品分类 uniapp/App
PC开发环境操作系统 Windows
PC开发环境操作系统版本号 windows11
HBuilderX类型 正式
HBuilderX版本号 4.29
手机系统 iOS
手机系统版本号 iOS 18
手机厂商 苹果
手机机型 iphone15
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

7 回复

你反馈 vue2 运行 ios18 真机有 webview 的问题,经过你测试本地可以稳定复现吗,你的 HBuilderX 版本是多少,提供一个单页面源码吧,相同的代码在其他系统没问题吗?


<!DOCTYPE html> <html lang="en"> <head> <title> </title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript" src="js/web.mqtt.min.js"></script> <script> window.forceWebGL = true; var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)')) document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />') </script> <style> html, body { background-color: #000000; width: 100% !important; height: 100% !important; } * { margin: 0; padding: 0; border: 0; }
#v1 {  
    position: absolute;  
    right: 0;  
    top: 20;  
    z-index: 100;  
    /* 镜像自己的画面 */  
    transform: scaleX(-1);  
}  

#v2,  
#v3 {  
    position: absolute;  
    right: 0;  
    top: 0;  
    left: 0;  
    bottom: 0;  
    z-index: 1;  
    /* object-fit: cover; */  
}  

/* 隐藏video 播放按钮 */  
.video::-webkit-media-controls-play-button {  
    display: none;  
}  

/* 隐藏video 进度条 */  
.video::-webkit-media-controls-timeline {  
    display: none;  
}  

/* 隐藏video 观看的当前时间 */  
.video::-webkit-media-controls-current-time-display {  
    display: none;  
}  

/* 隐藏video 剩余时间 */  
.video::-webkit-media-controls-time-remaining-display {  
    display: none;  
}  

/* 隐藏video 全屏按钮 */  
.video::-webkit-media-controls-fullscreen-button {  
    display: none;  
}  

/*  

.video::-webkit-media-controls-enclosure {
display: none;
} */

.control-container {  
    position: fixed;  
    left: 0;  
    top: 0;  
    right: 0;  
    bottom: 0;  
    z-index: 99999;  
    opacity: 0;  
}  

.navback {  
    position: absolute;  
    left: 50px;  
    top: 30px;  
    background-color: rgba(0, 0, 0, .3);  
    border-radius: 100%;  
    width: 40px;  
    height: 40px;  
    display: flex;  
    justify-content: center;  
    align-items: center;  
}  

.navback img {  
    width: 25px;  
    height: 25px;  
}  

.joy-div1 {  
    width: 160px;  
    height: 160px;  
    background: rgba(0, 0, 0, 0.3);  
    border-radius: 100%;  
    position: absolute;  
    top: 50%;  
    left: 50%;  
    margin-left: -80px;  
    margin-top: -80PX;  
}  

.joy-div2 {  
    width: 80px;  
    height: 80px;  
    background: rgba(255, 255, 255, 0.7);  
    border-radius: 100%;  
    position: absolute;  
    top: 50%;  
    left: 50%;  
    margin-left: -40px;  
    margin-top: -40px;  
}  

.joy-div3 {  
    width: 160px;  
    height: 160px;  
    border-radius: 100%;  
    position: absolute;  
    top: 50%;  
    left: 50%;  
    margin-left: -80px;  
    margin-top: -80px;  
}  

.main-joy {  
    position: absolute;  
    width: 160px;  
    height: 160px;  
    left: 100px;  
    bottom: 70px;  
    z-index: -1;  
    opacity: 0;  
}  

.control-right {  
    position: absolute;  
    right: 30px;  
    top: 0;  
    bottom: 70px;  
    display: flex;  
    flex-flow: column;  
    align-items: center;  
    justify-content: flex-end;  
    box-sizing: border-box;  
    opacity: 0;  
    z-index: -1;  
    min-width: 50px;  

}  

.control-right-item {  
    display: flex;  
    flex-flow: column;  
    align-items: center;  
    margin-top: 15px;  
}  

.control-right-item-img {  
    width: 40px;  
    height: 40px;  
    background-color: rgba(0, 0, 0, .3);  
    border-radius: 100%;  
    display: flex;  
    justify-content: center;  
    align-items: center;  
}  

.control-right-item-img img {  
    width: 25px;  
    height: 25px;  
}  

.control-right-item-text {  
    color: #fff;  
    font-size: 10px;  
}  

.traffic-data {  
    position: absolute;  
    top: 2px;  
    right: 130px;  
    z-index: 99999;  
    border-radius: 15px;  
    padding: 2px 8px;  
    color: rgb(255, 255, 255, 0.8);  
    font-size: 12px;  
    background-color: rgba(0, 0, 0, 0.3);  
    display: flex;  
    align-items: center;  
}  

.traffic-img-bgpro {  
    width: 18px;  
    height: 18px;  
    margin-right: 2px;  
}  

.loading-in-progress {  
    position: absolute;  
    top: 50%;  
    left: 50%;  
    z-index: 99999;  
    margin-left: -25px;  
    margin-top: -25px;  
    color: #fff;  
}  

.movement-direction-icon {  
    /* display: none !important; */  
    position: absolute;  
    z-index: -1;  
    bottom: 0px;  
    left: calc(50% - 40px);  
    background-color: transparent;  
}  

.img-bgpro {  
    width: 50px;  
    height: 50px;  
}  

.img-bgpro-direction {  
    width: 100px;  
    height: 70px;  
}  
</style> </head> <body> </body> <script type="text/javascript" src="js/uni.webview.1.5.5.js"></script> <script> //静音 const mutedFun = () => { uni.postMessage("asdasd"); console.log('播放网络地址') } </script> </html>

下面是web-view的源代码, 需要把index.txt改为index.html。 web-view中执行uni.postMessage 视频就卡死不播放。

你在video上绑定的点击事件啊,你把video的controls放出来看看是不是单击暂停了呢?或者你把点击事件单独弄个按钮来操作看看会不会出现问题

不是, video上的点击时间不影响。

回复 TylerLiu: 好吧

在uni-app中,如果你在高版本的iOS系统中使用web-view组件并通过uni.postMessage传递消息时遇到视频暂停播放的问题,这可能是由于web-view与原生应用之间的通信机制在高版本iOS中存在的一些特定行为导致的。尽管具体的内部机制可能复杂且难以直接控制,但你可以尝试通过一些编程技巧来绕过这个问题。

以下是一个可能的解决方案,它涉及到使用定时器来延迟消息的发送,以避免在视频播放关键时期干扰到播放流程。请注意,这种方法并非根治方案,而是一种权宜之计,实际效果可能因应用的具体场景而异。

// 在你的uni-app页面中
export default {
  data() {
    return {
      timer: null, // 用于存储定时器的引用
    };
  },
  methods: {
    sendMessageToWebView(message) {
      // 清除之前可能存在的定时器,以防多次触发
      if (this.timer) {
        clearTimeout(this.timer);
      }

      // 延迟发送消息,这里假设延迟500毫秒,你可以根据实际情况调整
      this.timer = setTimeout(() => {
        uni.postMessage({
          data: message,
        });
        // 发送后清除定时器引用
        this.timer = null;
      }, 500);
    },
    playVideo() {
      // 假设这是一个触发视频播放的函数
      // 在这里你可能已经设置了视频播放的逻辑
      // ...

      // 发送消息给web-view,这里假设消息是简单的字符串
      this.sendMessageToWebView({ type: 'video_play', data: 'some_data' });
    },
  },
  onUnload() {
    // 页面卸载时清除定时器,以防内存泄漏
    if (this.timer) {
      clearTimeout(this.timer);
    }
  },
};

在上面的代码中,sendMessageToWebView方法通过setTimeout来延迟消息的发送。这样做的好处是,它可以在视频播放的关键时刻(如开始播放时)避免立即的通信干扰,给予视频播放足够的资源来处理其内部逻辑。

此外,确保在适当的生命周期钩子(如onUnload)中清除定时器,以防止内存泄漏。

请记住,这种方法的有效性取决于具体的应用场景和iOS系统的版本。如果问题依旧存在,你可能需要更深入地调查web-viewuni-app之间的通信机制,或者考虑使用其他方式(如通过URL参数传递简单信息)来实现页面间的通信。

回到顶部