如何捕获屏幕共享取消事件?基于getDisplayMedia的WebRTC应用问题
捕获屏幕共享取消事件的两种场景处理
在使用navigator.mediaDevices.getDisplayMedia实现屏幕共享时,用户取消操作分为两种场景,分别对应不同的捕获方式:
1. 用户在选择屏幕阶段点击取消(未启动共享)
getDisplayMedia返回一个Promise,当用户在系统/浏览器的屏幕选择弹窗中点击取消时,Promise会被拒绝并抛出错误。你可以通过catch块捕获这个错误,判断错误名称来识别取消操作:
async function initScreenShare() { try { const stream = await navigator.mediaDevices.getDisplayMedia({ video: true }); // 这里执行获取流后的逻辑:创建WebRTC连接、绑定事件监听等 } catch (err) { // 不同浏览器抛出的错误名称可能不同,需兼容判断 if (err.name === 'AbortError' || err.name === 'NotAllowedError') { // 确认是用户主动取消选择 console.log('用户取消了屏幕共享选择'); // 执行取消后的清理:重置按钮状态、取消Socket连接初始化等 } else { console.error('屏幕共享流获取失败:', err); } } }
2. 用户在共享过程中主动停止(已启动共享)
如果用户已经成功开始屏幕共享,之后通过浏览器的停止共享按钮(或系统级停止操作)终止共享,此时媒体流的视频轨道会触发ended事件。你需要给视频轨道绑定该事件监听器来捕获:
async function initScreenShare() { try { const stream = await navigator.mediaDevices.getDisplayMedia({ video: true }); // 获取视频轨道并监听停止事件 const videoTrack = stream.getVideoTracks()[0]; videoTrack.addEventListener('ended', () => { console.log('用户停止了屏幕共享'); // 执行停止后的清理:关闭WebRTC连接、释放流资源、更新UI状态等 // 例如:停止发送流、通知对方共享结束 }); // 后续的流处理、WebRTC连接建立逻辑 } catch (err) { // 处理选择阶段的取消逻辑同场景1 if (err.name === 'AbortError' || err.name === 'NotAllowedError') { console.log('用户取消了屏幕共享选择'); } else { console.error('屏幕共享流获取失败:', err); } } }
注意事项
- 不同浏览器对取消操作抛出的错误名称可能有差异:Chrome/Edge通常抛出
AbortError,Firefox可能抛出NotAllowedError,所以需要同时判断这两个错误类型。 - 捕获到取消/停止事件后,记得及时清理相关资源(比如关闭媒体流、终止WebRTC连接、重置UI状态),避免内存泄漏或无效连接占用资源。
内容的提问来源于stack exchange,提问作者Roman Nozhenko
相关产品推荐
相关产品推荐

