getUserMedia vs [特殊字符]️ getDisplayMedia:摄像头与屏幕的抉择 前言你是否在开发视频会议或直播功能时纠结过“我想获取用户的摄像头画面该用哪个 API”“我想让用户分享整个桌面或某个 Chrome 标签页又该用哪个”“为什么getDisplayMedia不能直接获取麦克风声音”“这两个 API 返回的数据结构一样吗”简单来说getUserMedia是用来获取物理设备摄像头、麦克风的输入。getDisplayMedia是用来获取屏幕内容窗口、标签页、整个屏幕的输入。今天我们就来详细拆解这两者的区别帮你避免踩坑。1. 核心概念对比 getUserMedia(gUM)物理世界的捕捉者定义从本地媒体输入设备如摄像头、麦克风获取媒体流。类比“自拍”。你拿起手机前置摄像头拍自己或者用麦克风录音。主要用途视频通话中的“人像画面”、语音聊天、人脸识别、AR 特效。权限提示浏览器会弹窗询问“网站想要使用您的摄像头/麦克风。”️getDisplayMedia(gDM)数字世界的记录者定义从显示表面如整个屏幕、特定窗口、浏览器标签页捕获媒体流。类比“录屏”或“投影”。你把电脑屏幕投射到大屏幕上或者录制游戏过程。主要用途远程协作时的“屏幕共享”、在线教学、游戏直播、技术支持。权限提示浏览器会弹出一个系统级的选择器让用户选择要分享的具体内容整个屏幕 / 应用窗口 / 标签页。2. 详细差异表 维度getUserMediagetDisplayMedia数据来源硬件设备(Camera, Mic)软件渲染层(Screen, Window, Tab)典型场景视频会议人像、直播主播画面会议屏幕共享、远程桌面、教学演示音频支持✅原生支持(可直接请求 audio)❌通常不支持(需单独处理见下文)用户交互简单的权限确认弹窗 (Allow/Deny)复杂的选择器(用户必须手动选区域)隐私风险较低 (只暴露人脸/声音)极高(可能泄露密码、聊天记录等敏感信息)后台行为页面切后台通常继续运行某些浏览器在标签页切换时可能暂停或黑屏API 稳定性非常成熟广泛支持较新部分高级特性仍在演进中3. 关键细节深度解析 ⚠️ 细节一音频处理的巨大差异这是两者最大的坑点之一。getUserMedia你可以同时请求视频和音频// 轻松获取摄像头 麦克风conststreamawaitnavigator.mediaDevices.getUserMedia({video:true,audio:true,});getDisplayMedia它默认只捕获视频即使你在 constraints 里写了audio: true不同浏览器的行为也不一致且通常无法直接捕获系统声音System Audio。如何获取屏幕共享时的声音Chrome/Edge (标签页共享)如果用户选择分享“Chrome 标签页”并且该标签页正在播放声音浏览器会自动将该标签页的音频混合进视频流中无需额外配置但需在 UI 上勾选“分享标签页音频”。系统声音/麦克风如果需要捕获麦克风解说通常需要额外调用一次getUserMedia({ audio: true })然后将两个流合并使用AudioContext或MediaStream构造函数。// 1. 获取屏幕视频constscreenStreamawaitnavigator.mediaDevices.getDisplayMedia({video:true,});// 2. 获取麦克风音频constmicStreamawaitnavigator.mediaDevices.getUserMedia({audio:true});// 3. 合并流 (简单示例实际可能需要更复杂的音轨处理)constcombinedStreamnewMediaStream([...screenStream.getVideoTracks(),...micStream.getAudioTracks(),]);⚠️ 细节二隐私与安全限制getDisplayMedia必须由用户手势触发你不能在页面加载时自动调用getDisplayMedia。它必须在click事件等用户交互中触发否则浏览器会直接拒绝。无法静默录制当屏幕共享进行时浏览器通常会显示明显的指示器如红色边框、状态栏图标提醒用户当前正在被录制防止恶意软件偷窥。Track 停止事件当用户点击浏览器自带的“停止共享”按钮时视频轨道会触发ended事件。你需要监听这个事件来清理 UI。screenStream.getVideoTracks()[0].onended(){console.log(用户停止了屏幕共享);cleanupUI();};⚠️ 细节三移动端支持getUserMedia在 iOS 和 Android 上支持良好是移动端视频通话的基础。getDisplayMediaAndroid Chrome支持较好可以分享屏幕。iOS Safari支持有限。iOS 13 开始支持但体验不如桌面端且通常只能分享整个屏幕无法精确到某个 App 窗口。4. 实战代码示例 场景 A视频会议人像 屏幕共享切换letcurrentStreamnull;// 1. 开启摄像头asyncfunctionstartCamera(){try{currentStreamawaitnavigator.mediaDevices.getUserMedia({video:true,audio:true,});videoElement.srcObjectcurrentStream;}catch(err){console.error(摄像头开启失败:,err);}}// 2. 开启屏幕共享asyncfunctionstartScreenShare(){try{// 注意这会替换当前的视频流constscreenStreamawaitnavigator.mediaDevices.getDisplayMedia({video:true,});// 如果还需要保留麦克风声音需合并音频if(currentStreamcurrentStream.getAudioTracks().length0){constaudioTrackcurrentStream.getAudioTracks()[0];screenStream.addTrack(audioTrack);}// 监听用户停止共享screenStream.getVideoTracks()[0].onended(){console.log(屏幕共享已停止);// 可选自动切回摄像头// startCamera();};currentStreamscreenStream;videoElement.srcObjectcurrentStream;}catch(err){console.error(屏幕共享失败:,err);}}5. 常见误区澄清 ❌误区“getDisplayMedia可以获取任意窗口的画面包括后台运行的程序。”真相用户必须在前台主动选择要分享的窗口。一旦用户切换到其他应用分享的窗口内容可能会变黑或冻结取决于操作系统和浏览器策略以保护隐私。误区“我可以偷偷录制用户的屏幕。”真相绝对不可能。浏览器强制要求用户通过系统对话框明确选择分享区域且过程中有明显的视觉提示。误区“getUserMedia只能用于视频。”真相它常用于纯音频场景如语音房、语音识别只需设置{ video: false, audio: true }。6. 总结记忆口诀 UserMedia 采硬件摄像头里拍人像。麦克风里收声音视频通话靠它强。DisplayMedia 抓屏幕窗口标签任选样。隐私保护第一位用户必须手动选。音频处理有差异屏幕无声需另装。合并音轨莫忘记手势触发才正常。移动端上需谨慎iOS 支持尚有限。分清场景选对 API开发顺畅不迷茫。希望这篇文档能帮你彻底理清getUserMedia和getDisplayMedia的区别如果觉得有用欢迎点赞收藏