@[TOC](?Web前端JS通过getUserMedia API 获取 麦克风、摄像头(相机) 音视频等多媒体数据(语音、录音、相机、视频对话、流媒体)
?写在前面
随着人工智能的逐渐普及和广泛应用,不仅提高了设备的智能化水平,还为我们的日常生活带来了便利和新的可能,在各个应用领域中,通过多媒体设备如:麦克风、摄像头等多媒体设备,极大地丰富了我们的日常生活。而且随着技术的不断进步,未来还将在更多的领域中,如:智能家居、健康医疗、教育娱乐、交通运输 等多个领域发挥更大的作用,也将更进一步的提升我们生活和工作质量。
?前提条件
想要在Web浏览器(无论是PC端浏览器,还是移动端浏览器)中,获取麦克风、摄像头的音视频数据需要满以下几个基本条件:
硬件设备
麦克风:想要录音、获取音频数据,就一定要有音频采集设备 如 麦克风,而且要保证能正常使用。摄像头:想要画面、获取视频数据,就一定要有视频采集设备 如 摄像头,而且要保证能正常使用。协议要求
由于Web安全策略为了保证安全,要求Web浏览器必须在HTTPS通信协议下,才允许使用getUserMedia API访问多媒体设备(如果是在本地开发环境localhost
中是能正常访问的,但要在生产环境中使用必须是HTTPS
才行)。 接口支持
在Web浏览器中 获取音频、视频数据一般都是调用 getUserMedia API来获取数据的。所以Web浏览器本身得支持这个API,但这点不用担心,因为到目前为止,几乎所有的Web浏览器都支持 getUserMedia API 这个接口。用户权限
在满足以上两个必要条件以后,为了安全起见,在Web浏览器中 通过程序代码 来调用 getUserMedia API 之前还得用户的许可受权后才能调用。?️API简介
在HTML5中提供了 navigator.mediaDevices.getUserMedia API
为用户提供访问连接硬件设备多媒体设备,比如:麦克风(录音)、摄像头(相机 | 视频)、屏幕共享(录屏)等多媒体,可根据不同的设置轻松获取到对应的媒体数据资源,基于这个接口,Web应用程序开发者可以在不依赖任何浏览器插件的条件下访问硬件媒体设备。
在调用MediaDevices.getUserMedia() API时,首先会提示用户受权予使用媒体采集、输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。
在用户通过提示受权允许的情况下,打开电脑上的相机、麦克风、屏幕共享等采集设备,并提供 MediaStream 包含多媒体如:视频轨道或音频轨道的输入。
MediaStream 接口是一个媒体内容的流.。一个流包含几个轨道,比如视频和音频轨道。
?实际案例
科大迅飞语音听写(流式版)WebAPI,Web前端、H5调用 语音识别,语音搜索,语音听写Web前端JS如何获取 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据Web前端JS如何控制 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据Web前端JS通过使用AudioWorkletNode() 获取 Video/Audio 视音频声道(左右声道|多声道)?实例代码
Web前端JS通过getUserMedia API 获取 麦克风、摄像头 的音视频数据流,具体代码下如:
使用navigator.mediaDevices.enumerateDevices() API 获取当前可用的多媒体设备情况!
// 查看当前可用的媒体设备function getMediaDevices() { try { navigator.mediaDevices.enumerateDevices().then(function (devices) { devices.forEach(function (device) { switch (device?.kind) { case 'audioinput': console.log('音频输入设备(麦克风|话筒):', device); break; case 'audiooutput': console.log('音频输出设备(扬声器|音响):', device); break; case 'videoinput': console.log('视频输入设备(摄像头|相机):', device); break; default: console.log('当前可用的媒体设备: ', device); break; } }); }).catch(function (err) { console.error(err); }); } catch (err) { console.error(err); } finally { if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { console.log("不支持mediaDevices.enumerateDevices(), 未识别到多媒体设备!"); } }};getMediaDevices();
使用 navigator.mediaDevices.getUserMedia() 或 navigator.getUserMedia() API 获取 麦克风(话筒)、摄像头(相机) 等音视频多媒体流数据
// 处理媒体流数据function handleMediaStream(MediaStream) { console.log('MediaStream 流媒体对象:', MediaStream) /** * 哈哈,在这里就可以对采集到的媒体流数据进行操作啦! * * 比如:下面就是将采集到的媒体流数据在页面中进行播放 */ const video = document.createElement('video'); video.controls = true; video.srcObject = MediaStream; video.onloadedmetadata = function () { video.play(); }; document.body.appendChild(video);};// 获取媒体流数据function getUserMedia() { try { const options = { audio: true, // 注:这里 audio、video 默认都为false【一定要确保有麦克风或摄像头(有啥设备就开启啥设备)硬件设备的情况下才设为true 或 {...},否则会报DOMException: Requested device not found 等错!!】 video: true,// 获取视频 默认video: { facingMode: 'user' } }前置相机 // video: { // width: 1280, // 设置摄像头分辨率 // height: 720, // facingMode: { exact: 'environment' } // 获取视频 后置相机 // } } if (navigator.mediaDevices.getUserMedia) { // 访问用户媒体设备的 新标准API navigator.mediaDevices.getUserMedia(options).then(function (MediaStream) { handleMediaStream(MediaStream) }).catch(function (err) { console.error("访问用户媒体设备失败:权限被拒绝 或 未识别到多媒体设备!", err); }).finally(() => { console.log('navigator.mediaDevices.getUserMedia API') }); } else if (navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia) { try { //访问用户媒体设备的 旧标准API 兼容方法 navigator.getUserMedia(options, function (MediaStream) { handleMediaStream(MediaStream) }, function (err) { console.error("访问用户媒体设备失败:权限被拒绝 或 未识别到多媒体设备!", err); }) } catch (error) { console.error(err); } finally { console.log('navigator.getUserMedia API') }; } else { if (0 > location.origin.indexOf('https://')) { console.error("提示:请尝试在本地localhost域名 或 https协议 的Web服务器环境中重新运行!"); } } } catch (error) { console.error("访问用户媒体设备失败:", error); }};getUserMedia();
?常见问题
当我们兴高采烈的完成以上各个环节后,在Web浏览器打开试着运行一下代码功能,可能会出现以下报错信息,特别是涉及到用户隐私、安全等方面的操作,需要得到用户的受权许可、开启浏览器相关配置才能正常使用。
比如:在访问麦克风、摄像头的时候,如果多媒体设备在当前环境中不可用 、未连接等情况时,会在Web浏览器控制台中显示相关的报错信息!
?报错信息1:
DOMException: Requested device
DOMException: Requested device not found
根据错误信息提示:DOMException: Requested device not found 表示找不到请求的设备!
?解决方案:
确认用户的设备上确实有可以正常使用的媒体设备,如:麦克风、摄像头、扬声器等媒体设备。
如果是编程错误,请检查代码中的媒体设备访问代码,确保正确处理设备未找到的情况,可能需要引导用户选择正确的设备
在navigator.mediaDevices.getUserMedia({audio: true、video: true}) 默认都为false【一定要确保有麦克风或摄像头(有啥设备就开启啥设备)硬件设备的情况下才设为true
如果是在开发环境中,确保你的开发服务器正确配置,并且在生产环境中部署时,所有设备设置和权限都已正确配置。
?报错信息2:
DOMException: Permission denied
根据错误信息提示:DOMException: Permission denied 表示权限被拒绝!
?解决方案:
检查用户是否给予了网站访问媒体设备的权限。
检查电脑 所有设置(隐私或安全性)、Web浏览器 等是否有什么插件 或 扩展阻止了媒体设备的访问。
?报错信息3:
Uncaught TypeError: navigator.mediaDevices is undefined
Uncaught TypeError: Cannot read property 'getUserMedia' of undefined
Uncaught TypeError: Cannot read properties of undefined (reading 'enumerateDevices')
根据错误信息提示:Uncaught TypeError: navigator.mediaDevices is undefined 表示navigator.mediaDevices API不存在或未定义。
出现以上报错信息:基本都是访问和运行环境 或 通信协议的问题
?解决方案:
如果是在本地开发环境,可以使用 live-serve、http-server、phpstudy 等工具,启动一个本地Web服务 在 localhost 或 127.0.0.1 域名、IP中访问和运行。如果是已发布在生产环境, 就给域名添加https安全证书,将http
通信协议 改为https通信协议就可以啦。