当前位置: 首页 > news >正文

【音视频】WebRTC-Web 音视频采集与播放

一、打开摄像头

打开摄像头首先需要有一个htmlvideo标签:

  • id = "local-video",是为了后续的js脚本调用这个对象
  • autoplay是设置打开后自动播放,playsinline则是为了兼容移动端
 <video id = "local-video" autoplay playsinline></video>

添加<script>脚本标签:

  • 需要定义一个constraints对象,内部需要设置音频和视频的打开情况,比如这里只打开摄像头,则:
//媒体限制
const constraints = {audio:false,video:true
};
  • 通过documentquerySelector方法,返回对应标签id的对象,比如这里要得到<video>标签,就传入"#local-video",如果要得到对应的<button>标签对象,则查找"#showVideoBtn"
const video = document.querySelector("#local-video");
document.querySelector("#showVideoBtn").addEventListener("click",onOpenCamera);
  • 要在点击按钮后,打开摄像头,我们要实现下面三个回调函数:

handleSucess

function handleSuccess(stream){//document是内置全局变量,表示当前HTML文档,这里是选择对应的video对象const video = document.querySelector("#local-video"); //#local-video选择对应的id,返回的是引用video.srcObject = stream; //把视频流赋值给video对象
}function handleError(error){//console是内置全局变量,表示浏览器端的控制台console.error("getUserMedia error:" + error); //控制台打印错误
}

这个函数在打开摄像头成功之后调用,会传入一个stream对象,表示对应的媒体流,我们在这个回调函数中要将媒体流传入上述<video>标签对象,具体的方法是赋值<video>对象的srcObject属性:

video.srcObject = stream;

handleError

function handleError(error){//console是内置全局变量,表示浏览器端的控制台console.error("getUserMedia error:" + error); //控制台打印错误
}

这个函数用于打开摄像头失败之后的回调函数,传入错误信息,我们可以在控制台打印对应的信息:

onOpenCamera

 function onOpenCamera(e){//navigator也是内置全局变量,表示导航对象//mediaDevice是对应的媒体设备对象//getUserMedia是获取用户媒体的方法,返回一个Promise对象,promise执行成功后调用then函数,失败触发catch函数navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);}

这个函数在我们按钮点击后触发,是按钮点击的事件回调函数,传入一个事件对象,我们可以在这个事件回调函数内部调用navigator对象的mediaDevices.getUserMedia方法,也就是先获得媒体设备,然后在将我们的媒体限制、回调函数绑定,具体如下:

  • getUserMedia函数返回一个promise对象,这个对象执行完打开摄像头任务后,会调用对应的函数
    • 如果任务成功,调用then里面的回调函数
    • 如果任务错误,调用catch里面的回调函数
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);

最后,我们需要将按钮的点击事件回调函数绑定在showVideoBtn

document.querySelector("#showVideoBtn").addEventListener("click",onOpenCamera);

完整代码如下:

<!DOCTYPE html><html> <body><video id = "local-video" autoplay playsinline></video><button id = "showVideoBtn"> 打开摄像头</button><p>通过getUserMedia获取视频</p></body><script>//媒体限制const constraints = {audio:false,video:true};function handleSuccess(stream){//document是内置全局变量,表示当前HTML文档,这里是选择对应的video对象const video = document.querySelector("#local-video"); //#local-video选择对应的id,返回的是引用video.srcObject = stream; //把视频流赋值给video对象}function handleError(error){//console是内置全局变量,表示浏览器端的控制台console.error("getUserMedia error:" + error); //控制台打印错误}function onOpenCamera(e){//navigator也是内置全局变量,表示导航对象//mediaDevice是对应的媒体设备对象//getUserMedia是获取用户媒体的方法,返回一个Promise对象,promise执行成功后调用then函数,失败触发catch函数navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);}//绑定按钮的点击事件,点击后调用onOpenCamera函数document.querySelector("#showVideoBtn").addEventListener("click",onOpenCamera);</script></html>

Web页面效果如下:

在这里插入图片描述

二、打开麦克风

打开麦克风和打开摄像头类似,把对应的<video>标签改为audio标签,然后添加上controls模块,这个模块是添加一些暂停、声音调节等功能

<audio id = "local-audio" autoplay controls></audio>

还需要要修改对应的媒体限制对象constraints,关闭video,打开audio

const constraints = {video: false,audio: true
}

其他部分和打开摄像头保持一致

<!DOCTYPE html>
<html><body><audio id = "local-audio" autoplay controls></audio><button id = "showAudioBtn"> 打开麦克风</button><p>通过getUserMedia获取音频</p></body><!--类似video部分的js脚本--><script>const constraints = {video: false,audio: true}function handleSuccess(stream){const audio = document.querySelector("#local-audio");audio.srcObject = stream;}function handleError(error){console.error("getUserMedia error" + error);}function onOpenMicrophone(e){navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);}showAudioBtn = document.querySelector("#showAudioBtn");showAudioBtn.addEventListener("click",onOpenMicrophone);</script></html>

Web页面效果如下:

在这里插入图片描述

三、同时打开摄像头和麦克风

同时打开摄像头和麦克风,和打开摄像头一致,唯一需要修改的就是媒体限制对象constraints,将视频和音频都设置为true

const constraints = {video: true,audio: true
}

完整代码如下:

<!DOCTYPE html><html><body><video id = "local-video" autoplay playsinline></video><button id = "showVideoAudioBtn"> 打开摄像头和麦克风</button><p>通过getUserMedia获取摄像头和麦克风</p></body><script>const constraints = {video: true,audio: true}function handleSuccess(stream){const video = document.querySelector("#local-video");video.srcObject = stream;}function handleError(error){console.error("getUserMedia error" + error);}function onOpenVideo_Audio (e){navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);}showVideoBtn = document.querySelector("#showVideoAudioBtn");showVideoBtn.addEventListener("click",onOpenVideo_Audio);</script></html>

在这里插入图片描述

更多资料:https://github.com/0voice

http://www.lryc.cn/news/604781.html

相关文章:

  • 【预判一手面试问题:排序】
  • 依托客户满意度分析协助企业精准把握市场趋势​(满意度调查)
  • 智能AI医疗物资/耗材管理系统升级改造方案分析
  • InfluxDB 与 Java 框架集成:Spring Boot 实战(二)
  • VSCode插件开发完整教程:从零开始创建文件导出插件
  • Python 程序设计讲义(37):字符串的处理方法——设置字符串居中显示:center() 方法
  • 图像平滑处理
  • 9.项目起步(3)
  • OpenCV学习day1
  • 实习小记(个人中心的编辑模块)
  • 商标注册后可以随意更改字体和颜色吗!
  • 怎么理解锁相环主时钟(PLL)怎么做到对时钟进行倍频?
  • Keil STM32工程各文件作用
  • AI框架工具FastRTC快速上手2——整体框架及Stream类详解
  • 方块世界:失落文明的遗产
  • Deforum Stable Diffusion,轻松实现AI视频生成自由!
  • 语音识别dolphin 学习笔记
  • UE5多人MOBA+GAS 番外篇:将冷却缩减属性应用到技能冷却中
  • 设计模式十四:适配器模式(Adapter Pattern)
  • Linux ps -ef 命令解析
  • 基于成像空间转录组技术的肿瘤亚克隆CNV原位推断方法
  • composer 常用命令
  • 智慧城市SaaS平台|市政公用管理系统
  • 从单机到分布式:Redis如何成为架构升级的胜负手
  • 串口接收数据包(协议带帧头帧尾)的编程实现方法:1、数据包格式定义结构体2、使用队列进行数据接收、校验解包
  • 三十二、【Linux网站服务器】搭建httpd服务器演示虚拟主机配置、网页重定向功能
  • uni-app webview 的message无法触发的解决方案
  • MacTex+Vscode数学建模排版
  • 字节跳动“扣子”(Coze)开源:AI智能体生态的技术革命
  • AI Compass前沿速览:可灵创意工坊、字节Coze StudioCoze Loop、通义万相2.2 、智谱GLM-4.5、腾讯混元3D世界模型开源