webrtc 入门第一章 基本设备操作

这篇具有很好参考价值的文章主要介绍了webrtc 入门第一章 基本设备操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、介绍
1、webrtc是什么

webrtc是一个由google发起的开源实时通信方案,其中包括视频/音频采集、编解码、数据传输、音视频展示的功能。在浏览器,桌面应用,移动设备或者lot设备上都有可以运行的api接口,均可实现实时通信能力。web开发者可以基于web api开发基于视频、音频的实时通信应用,如视频会议,远程教育,视频通话,视频直播,游戏直播,远程协助,互动游戏,实时人脸识别等功能。

2、优点是什么

webrtc主要应用在实时通信方面,其优点总结为如下几点。

1、跨平台:可以在Web,Android,iOS,Windows,MacOS、Linux等环境下运行

2、实时传输:传输速度快,低延迟,适合实时性要求较高的场景

3、音视频引擎:有强大的音视频处理能力

4、免插件:不需要安装任何插件,兼容性高,打开浏览器即可使用,并且免费开源

5、强大的打洞能力:webrtc技术包含了使用STUN、ICE、TURN、RTP-over-TCP的关键NAT和防火墙穿透技术

本次将通过webrtc实现一对一视频对话的功能,首先要进行本地媒体资源的操作

二、实践
1、打开摄像头
<body>
  <input type="button" title="开启摄像头" value="开启前置摄像头" v-on:click="getMedia(0)"/>
  <input type="button" title="开启摄像头" value="开启后置摄像头" v-on:click="getMedia(1)"/>
   <video height="120px" autoplay="autoplay" :src="video_1_url" crossOrigin="anonymous" muted="muted" controls></video>
    <hr/>
 </body>
  <script src="/static/js/Vue.2.5.3.js"></script>
<script type="text/javascript"> 
 // 兼容版本
  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
getMedia: function (a) {
    let that = this;
    if (that.exArray.length <= a) {
        alert("设备不存在")
        return
    }


    if (navigator.getUserMedia) {
    	// 获取用户媒体数据,
        navigator.getUserMedia({
            'video': {
                'optional': [{
                    'sourceId': that.exArray[a] //0为前置摄像头,1为后置
                }]
            },
            'audio': true // 不需要音频的话为false
        }, that.successFunc, that.errorFunc); //success是获取成功的回调函数,也可以使用await来处理异步
    } else {
        alert('Native device media streaming (getUserMedia) not supported in this browser.');
    }
},
        // 摄像头加载成功
            successFunc: function (stream) {
                if (this.video.mozSrcObject !== undefined) {
                    //Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
                    this.video.mozSrcObject = stream;
                } else {
                	// 将流媒体复制给video标签进行播放 
                    this.video.srcObject = stream 
                }
                this.stream = stream


                // 获取track  视频轨道
                let deviceInfo = stream.getVideoTracks()
                let tracks = deviceInfo[0]
                // 可以对轨道进行操作
                console.log(tracks.getConstraints())
                this.deviceName = deviceInfo[0].label
                this.video.play();


                // 音频
                this.audio = new Audio();
                this.audioType = this.getAudioType(this.audio);
                if (this.audioType) {
                    this.audio.src = 'polaroid.' + this.audioType;
                    this.audio.play();
                }
            }
             loadDevice: function () {
                let that = this;

                navigator.mediaDevices.enumerateDevices()
                    .then(function (sourceInfos) {
                            // 获取设备列表
                            console.log(sourceInfos)
                            for (let i = 0; i != sourceInfos.length; ++i) {
                                let sourceInfo = sourceInfos[i];
                                //这里会遍历audio,video,所以要加以区分
                                if (sourceInfo.kind === 'videoinput') {
                                    that.exArray.push(sourceInfo.deviceId);
                                }
                            }
                        }
                    ).catch(function (err) {
                    alert("获取设备列表错误")
                });
            },
            
<script type="text/javascript">

本次只展示部分重要代码,部分代码可以自行补充,打开摄像头流程如下

1先使用getUserMedia 约束条件获取到媒体, 其中 ‘audio’: true 表示获取视频,video:turn 表示获取声音

2.使用navigator.mediaDevices.enumerateDevices 方法获取到设备

3.获取到媒体资源后使用video标签进行播放

4.在媒体流中通过getVideoTracks 方法可以获取到当前流媒体的轨道即正在使用的设备。
webrtc 入门第一章 基本设备操作

2、打开麦克风
<body>
	<input type="button" value="开启麦克风" v-on:click="checkVoice()"/>
</body>
<script type="text/javascript">
    // 开启声音
  checkVoice: function () {
                if (navigator.getUserMedia) {
                    window.audioContext = new AudioContext()
                    navigator.getUserMedia({
                        'video': false,
                        'audio': true
                    }, this.onVoice, this.errorFunc); //success是获取成功的回调函数
                } else {
                    alert('Native device media streaming (getUserMedia) not supported in this browser.');
                }

            },
  // 获取到媒体声音后 音量展示 stream表示流媒体              
  onVoice: function (stream) {      
                let that = this;
       			//创建一个管理、播放声音的对象
                let audioContext = new AudioContext()
                let analyser = audioContext.createAnalyser()
                liveSource = audioContext.createMediaStreamSource(stream); //将麦克风的声音输入这个对象\
                // 音频连入分析器
                liveSource.connect(analyser)
                // 分析器再将音频连入麦克风-这样播放的音频就会通过分析器
                analyser.connect(audioContext.destination)

                analyser.fftSize = 128


                setInterval(() => {
                    let dataArray = new Uint8Array(analyser.frequencyBinCount)
                    analyser.getByteFrequencyData(dataArray)
                    // console.log(dataArray)
                    let maxVal = 0;
                    for (let i = 0; i < dataArray.length; i++) {
                        if (maxVal < dataArray[i]) {
                            maxVal = dataArray[i];
                        }
                    }
                    that.voiceWidth = Math.round(maxVal) + "px"
                    that.drow(dataArray)
                }, 50)
            },
                // 画图案
            drow: function (array) {
                var canvas = document.getElementById('canvas3'),
                    cwidth = canvas.width,
                    cheight = canvas.height - 2,
                    meterWidth = 10, //能量条的宽度
                    gap = 2, //能量条间的间距
                    capHeight = 2,
                    meterNum = 800 / (10 + 2), //计算当前画布上能画多少条
                    ctx = canvas.getContext('2d')
                var step = Math.round(array.length / meterNum);
                ctx.clearRect(0, 0, cwidth, cheight); //清理画布准备画画
                gradient = ctx.createLinearGradient(0, 0, 0, 300);
                gradient.addColorStop(1, '#0f0');
                gradient.addColorStop(0.5, '#ff0');
                gradient.addColorStop(0, '#f00');
                ctx.fillStyle = gradient;
                for (var i = 0; i < meterNum; i++) {
                    var value = array[i * step];
                    ctx.fillRect(i * 12, cheight - value + capHeight, meterWidth, cheight);
                }
            },
</script>

和打开视频流程一样,

1.同样使用getUserMedia()方法 约束条件’audio’: true , 即可请求麦克风。

2.当获取到音频流后传递给audio对象的srcObject方法即可。

3.音频可视化,audioContext 方法可以创建一个音频分析器,将音频流载入后就能展示音频的大小

webrtc 入门第一章 基本设备操作

3、截屏及下载图片
<body>
	<input type="button" title="截屏" value="截屏" v-on:click="getPhoto()"/><br/>
	<canvas id="canvas1" height="120px"></canvas>
</body>
<script>
    
         getPhoto: function () {
             	// 创建canvas画布
                 this.canvas1 = document.getElementById('canvas1');
            this.context1 = this.canvas1.getContext('2d');
                //将video对象内指定的区域捕捉绘制到画布上指定的区域,实现拍照。
                this.context1.drawImage(this.video, 0, 0, 90, 120);
             
             
             	// 转图片下载
                // 抓取照片数据
                let imgData = this.canvas1.toDataURL(); //将图像转换为base64数据
                let base64Data = imgData.substr(22); //在前端截取22位之后的字符串作为图像数据

          
                imgData = imgData.replace(this.changeImageType("png"), 'image/octet-stream');
                let save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
                save_link.href = imgData;
                save_link.download = (new Date()).getTime() + '.' + "png";

                let event = document.createEvent('MouseEvents');
                event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                save_link.dispatchEvent(event);
            }
    		// 修改图片类型操作
            changeImageType: function (type) {
                type = type.toLowerCase().replace(/jpg/i, 'jpeg');
                let r = type.match(/png|jpeg|bmp|gif/)[0];
                return 'image/' + r;
            },
      
</script>

在摄像头正常可以播放的时候,可以使用canvas进行图像捕捉

1.使用媒体约束条件,调用getUserMedia()方法,实现摄像头播放正常

2.获取到媒体流时,传递给video的srcObject对象进行播放

3.创建canvas 标签,调用canvas的drawImage 方法,传递video对象可以生成一张2d图片。

4.将canvas 图转换格式实现本地下载

4.视频同步与
<body>
    <input type="button" title="视频" value="视频" v-on:click="getVideo()"/><br/>
	<canvas id="canvas2" height="120px"></canvas>
</body>
<script>
			//视频
           getVideo: function () {
                this.canvas2 = document.getElementById('canvas2');
            	this.context2 = this.canvas2.getContext('2d');
                this.drawVideoAtCanvas(this.video, this.context2);
            },
             // 将视频帧绘制到Canvas对象上,Canvas每60ms切换帧,形成肉眼视频效果
            drawVideoAtCanvas: function (video, context) {
                window.setInterval(function () {
                    context.drawImage(video, 0, 0, 90, 120);
                }, 60);
            },
</script>

在摄像头正常可以播放的时候,可以使用canvas进行图像捕捉

1.使用媒体约束条件,调用getUserMedia()方法,实现摄像头播放正常

2.获取到媒体流时,传递给video的srcObject对象进行播放

3.将video的视频源载入canvas ,实现图案绘制,最后每隔60毫秒,绘制一张图片实现视频的同步

三、总结

1.访问相关设备API

方法名 参数 说明
getUserMedia 定义约束对象,是否调用音频或者视频 采集摄像头或者麦克风设备
getDisplayMedia 定义约束对象,设置视频采集宽高,是否调用视频 捕获计算机屏幕的方法(本章未用到)
MediaStreamConstanints video,audio 调用getUserMedia和getDisplayMedia方法的约束条件,ture表示采集,false表示不采集

2.在本章学习使用媒体设备的基本操作,首先我们要解决的兼容性,因为不同的浏览器的不同版本对webrtc的兼容性不同,因此在使用前首先要解决兼容性。

3.再次我们学回了如何访问媒体设备,使用设置约束调剂调用音频或者视频流。

4.最后我们将媒体流以不同的形式进行了展示,做到了可视化。每一步都很有意思

5.在使用webrtc的时候需要我们部署https服务访问,否则可能会因为安全问题而操作失败
6.当然在后面还有一些分享桌面,捕捉等操作没在本次示例中演示。具体可以查看代码仓库。

四、感谢

感谢作者 亢少军老师的 《WebRTC音视频开发 》 课本指导文章来源地址https://www.toymoban.com/news/detail-433958.html

到了这里,关于webrtc 入门第一章 基本设备操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • javacv从入门到精通——第一章:javacv介绍

    JavaCV是一个开源的Java框架,它提供了基于Java的接口,用于访问各种计算机视觉库和工具包,如OpenCV、FFmpeg等。JavaCV旨在为Java开发人员提供快速、简单和可靠的图像和视频处理能力。 JavaCV的历史可以追溯到2007年,当时一个名为“JavaCPP”的项目开始了。JavaCPP旨在为Java开发人

    2023年04月09日
    浏览(52)
  • 基于STM32的homeassistant(采用FreeRTOS操作系统)【第一章:设备配网、连接服务器、断网重连、断服务器重接】

      主控 STM32F103C8T6 WIFI模块 ESP01S 开发语言 C 开发编译器· KEIL 组网方式 WIFI 服务器协议 MQTT ESP01S的AT指令配网以及服务器连接 STM32与ESP01S的usart协议通信 断网重连以及断服务器重连 STM32向服务器端口发送对应指令         ESP01S的配网方式为AT指令集,通过识别对对应的AT指令

    2024年02月12日
    浏览(53)
  • LINUX网络第一章:基本命令

    目录 一.网络配置 1.ifconfig     ip地址 ifconfig的基础用法 ifconfig命令详解 常用格式 修改网卡名称 临时修改 永久修改 ​编辑临时修改网卡 设置虚拟网卡 ​编辑​编辑​编辑延伸——ethtool 永久修改网卡 实验  ——  双网卡配置 添加新的网卡 ​编辑将ens33的配置文件拷给en

    2024年01月20日
    浏览(35)
  • 苍穹外卖-第一章项目介绍

    1)管理端功能 员工登录/退出 , 员工信息管理 , 分类管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 订单管理 ,数据统计,来单提醒。 2)用户端功能 微信登录 , 收件人地址管理 , 用户历史订单查询 , 菜品规格查询 , 购物车功能 , 下单 , 支付、分类及菜品浏览。 1)管理端 餐饮企业

    2024年02月08日
    浏览(44)
  • 小满nestjs(第一章 介绍nestjs)

    视频课程 小满nest js 系列_哔哩哔哩_bilibili Nestjs 是一个用于构建高效可扩展的一个基于Node js 服务端 应用程序开发框架 并且完全支持typeScript  结合了 AOP 面向切面的编程方式 nestjs 还是一个spring MVC 的风格 其中有依赖注入 IOC 控制反转 都是借鉴了Angualr nestjs 的底层代码运用了

    2024年02月01日
    浏览(37)
  • 第一章 数据库操作

    1.1 创建数据库 创建数据库是指在数据库系统中划分一块空间,用来存储相应的数据,这是进行表操作的基础,也是数据库管理的基础 在MySQL中创建数据库之前,可以使用show语句来显示当前已经存在的数据库,具体SQL语句如下 创建数据库的SQL语句如下,其中 参数database_name代

    2024年02月05日
    浏览(65)
  • 第一章 操作系统

    2023/6/14 第一章 计算机系统概述 提供的功能 处理器管理 存储器管理 作为系统资源的管理者 文件管理 目标安全高效 设备管理 特征 并发 目标和功能 共享 最基本 概论 虚拟 异步 计算机系统资源的管理者 命令接口 目标和功能 用户与计算机系统之间的接口 程序接口 扩充机器

    2024年02月08日
    浏览(46)
  • 第一章 MATLAB入门

    MATLAB(矩阵实验室的简称)是一种专业的计算机程序,用于工程科学的矩阵数学运算。但 在以后的几年内,它逐渐发展为一种极其灵活的计算体系,用于解决各种重要的技术问题。 Matlab程序执行MATLAB语言,并提供了一个极其广泛的预定义函数库,这样就使得技术工作 变得简

    2024年02月05日
    浏览(45)
  • 第一章 小程序入门

    小程序的基本结构 小程序的页面组成部分 JSON 配置文件的作用 app.json 配置文件 project.config.json 配置文件 sitemap.json 配置文件 页面 .json 配置文件 什么是 wxml wxml 和 html 的区别 什么是 wxss wxss 和 css 的区别 通信模型 小程序的启动过程 页面渲染过程 button 按钮的基本使用 img 组件

    2024年02月08日
    浏览(64)
  • 第一章:SpringBoot基础入门

    Spring 能做什么 Spring 的能力 Spring 的生态 网址: https://spring.io/projects/spring-boot 覆盖了: Web 开发、数据访问、安全控制、分布式、消息服务、移动开发、批处理等。 Spring5 重大升级 响应式编程 内部源码设计 基于 Java8 的一些新特性。 为什么用 SpringBoot ​ Spring Boot makes it eas

    2024年02月12日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包