团队使用的云真机平台之前从minicap切换到了scrcpy的方案后,出现云真机的画面开始传输后,如果此时将浏览器切换到其他tab页面后,然后隔一段时间回来操作会发现,屏幕的画面传输会延迟非常多, 这个延迟跟放置到后台的时间有关。
这个问题一开始怀疑是因为使用的库 h264-converter 的问题, 但是从官方的issue中,也没有看到有相关的问题体现,而且这个问题从操作表现的来更像是浏览器的一些形式,类似于将置于后台的video的视频播放给停止了似的。
所以实在没找到好的方式,采用了一种相当糟糕的解决方法,就是浏览器切换回原有的tab的时候,将手机画面的h264传输断开后,重新传输一遍。 这个就会导致,页面切换回来的时候,手机的画面会出现黑屏的情况。
if (window.converter !== null && !isUndefined(window.converter)) {
if (document.hidden) {
this.hideTime = new Date().valueOf();
this.isPause = true;
window.converter.pause();
} else {
// 大于2分钟的话
if (new Date().valueOf() - this.hideTime > 1000 * 60 * 2) {
document.getElementById("videoTagId").style.height = document.getElementById("canvas-container").clientHeight + "px";
window.androidWebsocket.send(JSON.stringify({ operation: 'solution' }))
}
this.isPause = false;
window.converter.play();
}
}
因为尝试后发现一旦切换时间超过2分钟以后,画面就出现了比较明显的延迟了。所以在浏览器tab切换回来后, 发送切换分辨率的逻辑,让画面的数据重新进行传输。
以上的这个处理逻辑并不是最优解, 首先是这个两分钟就是自己假想的, 所以实际在使用的过程中仍然出现画面延迟的问题。所以这个问题搁置了好久,想着要不试试看 换一个h264的库看看是否就没有这个问题了。直到看到了这篇文章。
jmuxer.js 之二 – 简单使用_sinat_27720649的博客-程序员秘密 - 程序员秘密
里面出现了这样子的描述
切换到后台、标签页失去焦点时,video控件会暂停播放。这是chrome 内核的一个机制,当页面失去焦点时,如果video标签内的数据没有音轨,会暂停播放,MSE的数据会堆积,导致延迟。可以考虑采用将页面置顶,失去焦点后定时检查video播放状态 、失去焦点后不播放等策略。
所以其实我们本身播放画面的延迟应该也是这个原因了。
那这种问题,难道就没有什么解决方案吗?
然后又找到关于github上的一个issue
https://github.com/bilibili/flv.js/issues/259
这个问题的描述就跟目前我们遇到的问题基本都是一样的,
可以直接video.currentTime设到buffered.end(0)附近
就有以上的这样子的回复。这里的设置的目的是将播放器当前的时间设置到缓冲区结束的位置。
至此问题得到了比较好的解决,以下是问题的解决方式
if (window.converter !== null && !isUndefined(window.converter)) {
if (!document.hidden) {
// 设置video的播放时间
let player = document.getElementById("videoTagId");
let buffered = player.buffered;
// 主要是为了严谨一点先判断有没有缓存,然后把他时间设置到缓存前一点点时间所以-0.5,如果直接设置到.end(0)他还需要去加载内容才能流畅继续播放
player.currentTime = buffered.end(0) - 0.5
}
}