web端调用本地摄像头麦克风+WebRTC腾讯云,实现直播功能
目录
- 关于直播
- 直播流程
- 直播视频格式封装
- 推流和拉流
- 获取摄像头和麦克风权限
- navigator.getUserMedia()
- MediaDevices.getUserMedia()
- WebRTC
- 腾讯云快直播
关于直播
视频直播技术大全、直播架构、技术原理和实现思路方案整理
直播流程
-
视频采集端:
1、视频采集:使用摄像头设备获取实时视频流。
2、视频处理: 对采集到的视频进行处理,可以包括美颜、滤镜、水印等效果的添加。
3、音视频编码压缩: 将处理后的音视频数据进行编码压缩,常用的编码方式有H.264视频编码和AAC音频编码。 -
直播流视频服务端:
1、视频流解析编码:接收视频采集端传来的音视频数据流,进行解析和解码。
2、推送RTMP/HLS格式视频流:将解码后的音视频数据流封装成RTMP或HLS格式,并推送到流媒体服务器上。这些流媒体服务器会处理客户端的连接和请求,将直播内容分发给客户端。 -
视频播放端:
1、音视频解码:在播放端,接收到来自直播流视频服务端的数据流,进行解码,得到原始的音频和视频数据。
2、播放+聊天互动:将解码后的音视频数据进行播放,同时提供用户界面供观众观看。可以在播放端实现一些互动功能,比如弹幕、点赞、评论等。
直播视频格式封装
直播视频通常会经过特定的封装格式,以便在网络上传输和播放。这些封装格式可以将音频、视频、元数据等信息进行组合和管理,以确保流畅的传输和播放体验。
FLV: 一种由Adobe公司开发的流媒体封装格式,最初用于Flash播放器和RTMP协议传输。它可以容纳音频、视频、文本和元数据,并且适用于实时传输和播放。
TS: 一种用于传输多媒体内容的封装格式,常用于数字电视和IPTV。它可以容纳多路音频、视频和数据流,适合实时传输和广播。HLS协议中使用的就是TS格式来封装音视频流。
MP4: 一种通用的多媒体封装格式,可以容纳音频、视频、字幕和元数据。它被广泛用于存储和传输音视频内容,也可以用于直播。MP4格式通常使用H.264视频编码和AAC音频编码。
推流和拉流
推流(Publishing)
和拉流(Subscribing)
是在实时音视频通信中常见的术语,用于描述音视频数据的传输过程。推流指的是将本地音视频数据发送到服务器,而拉流则是从服务器接收远程音视频数据。
HLS 是由苹果公司开发的一种流媒体传输协议,主要用于在iOS设备、Web浏览器和其他支持HLS的设备上实现实时的音视频流播放。HLS将音视频流切割成一系列小的媒体文件(使用 .ts 格式进行封装,将音视频流分割成小的.ts文件),通过HTTP协议逐个传输和播放。
优点:
1、适用于多种设备和平台,包括iOS、Android、Web等。
2、支持自适应码率,根据网络状况动态调整视频质量。
3、在不同带宽下都能提供较好的流畅播放体验。
4、使用HTTP协议传输,不需要特定的服务器支持。
缺点:
1、延迟相对较高,通常在10秒左右。
2、需要将媒体流切割成小文件,增加服务器压力和存储开销。
RTMP 是Adobe公司开发的实时消息传输协议,基于TCP协议传输,最初用于Flash播放器与媒体服务器之间的音视频传输。
优点:
1、延迟相对较低,通常在1-3秒左右,适合实时互动。
2、支持即时性的直播,适用于一些对延迟要求较高的场景。
3、在Flash播放器上有较好的兼容性。
缺点:
1、不适用于iOS设备和某些平台,因为不被广泛支持。
2、需要专门的RTMP服务器支持,部署和维护相对复杂。
3、需要考虑防火墙和代理等网络限制。
获取摄像头和麦克风权限
navigator.getUserMedia()
MDN-navigator.getUserMedia()
Navigator.getUserMedia()
方法提醒用户需要使用音频(0 或者 1)和(0 或者 1)视频输入设备,比如相机,屏幕共享,或者麦克风。
语法: navigator.getUserMedia ( constraints, successCallback, errorCallback );
代码:
<body><video autoplay id="video" width="400" height="300"></video><script>var video = document.getElementById('video');//作兼容处理navigator.getMedia = navigator.getUserMedia ||navagator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.msGetUserMedia;navigator.getMedia({ audio: true, video: true },function (stream) {//MDN文档案例中这样写会报错:video.src = window.URL.createObjectURL(stream);video.srcObject = streamvideo.onloadedmetadata = function (e) {video.play();};},function (err) {console.log("The following error occurred: " + err.name);});</script>
</body>
虽然这个api依然可以使用,但是官网上已经换了另一个api——MediaDevices.getUserMedia()
MediaDevices.getUserMedia()
MDN-MediaDevices.getUserMedia()
MediaDevices.getUserMedia()
会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其他轨道类型。
语法:
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { /* 使用这个 stream stream */ }).catch(function (err) { /* 处理 error */});
代码:
<video autoplay id="video" width="400" height="300"></video>
<script>var video = document.getElementById('video');navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(function (stream) {/* 使用这个 stream stream */video.srcObject = streamvideo.onloadedmetadata = function (e) {video.play();};}).catch(function (err) {/* 处理 error */console.log("The following error occurred: " + err.name);});</script>
WebRTC
MDN-WebRTC API
WebRTC
(Web Real-Time Communication)是一种支持浏览器之间实时通信的开放式标准和技术,它使得浏览器可以直接在不需要插件或额外的软件的情况下进行音频、视频和数据的传输和通信。WebRTC 技术的核心目标是实现实时的、点对点的通信,包括视频聊天、音频通话、数据共享等功能。
代码:
<body><!-- 显示本地视频 --><h2>本地视频</h2><video id="localVideo" autoplay playsinline style="width: 300px;"></video><!-- 显示远程视频 --><h2>远程视频</h2><video id="remoteVideo" autoplay playsinline style="width: 300px;"></video><button id="startCall">发起通话</button><button id="answerCall">接听通话</button>//呼叫者:<script>const localVideo = document.getElementById('localVideo');let localStream;// 呼叫者:获取本地摄像头和麦克风权限navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => {localStream = stream;localVideo.srcObject = localStream;}).catch(error => {console.error('获取本地媒体流失败:', error);});const startCallButton = document.getElementById('startCall');startCallButton.addEventListener('click', () => {startCall();});async function startCall() {// 呼叫者:创建PeerConnectionconst peerConnection = new RTCPeerConnection();// 添加本地媒体流到PeerConnectionlocalStream.getTracks().forEach(track => {peerConnection.addTrack(track, localStream);});// 呼叫者:创建Offer并设置本地描述peerConnection.createOffer().then(offer => peerConnection.setLocalDescription(offer)).then(() => {// 发送本地描述到远程const offerSdp = peerConnection.localDescription;// 在实际应用中,需要将offerSdp发送给远程端// 远程端通过RTCPeerConnection.setRemoteDescription()设置远程描述}).catch(error => {console.error('创建Offer失败:', error);});}</script>//被呼叫者:<script>const remoteVideo = document.getElementById('remoteVideo');let remoteStream;const answerCallButton = document.getElementById('answerCall');answerCallButton.addEventListener('click', () => {answerCall();});async function answerCall() {// 创建PeerConnectionconst peerConnection = new RTCPeerConnection();// 设置ontrack事件处理程序以接收远程流peerConnection.ontrack = event => {remoteStream = event.streams[0];remoteVideo.srcObject = remoteStream;};// 在实际应用中,你需要获取呼叫者发送的offerSdp// 并通过RTCPeerConnection.setRemoteDescription()设置远程描述// 创建Answer并设置本地描述const answer = await peerConnection.createAnswer();await peerConnection.setLocalDescription(answer);const answerSdp = peerConnection.localDescription;// 在实际应用中,你需要将answerSdp发送给呼叫者// 呼叫者通过RTCPeerConnection.setRemoteDescription()设置远程描述}</script>
</body>
腾讯云快直播
腾讯云直播-WebRTC协议推流
云直播提供了推流
SDK TXLivePusher
用于 Web 推流,负责将浏览器采集的音视频画面通过 WebRTC 协议推送到直播服务器。目前支持摄像头采集、麦克风采集、屏幕分享采集、本地媒体文件采集和用户自定义采集等采集方式,支持对采集到的内容进行本地混流处理,然后推送到后端服务器。
1、引入初始化脚本(需要在 HTML 的 body 部分引入脚本,如果在 head 部分引入会报错。)
<script src="https://video.sdk.qcloudecdn.com/web/TXLivePusher-2.1.0.min.js" charset="utf-8"></script>
2、创建视频容器
<div id="local_video" style="width:100%;height:500px;display:flex;align-items:center;justify-content:center;"></div>
3、生成推流 SDK 实例
//通过全局对象 TXLivePusher 生成 SDK 实例,后续操作都是通过实例完成。const livePusher = new TXLivePusher();// 指定本地视频播放器容器 div,浏览器采集到的音视频画面会渲染到这个 div 当中。livePusher.setRenderView('local_video');// 设置音视频流 livePusher.setVideoQuality('720p');// 设置音频质量livePusher.setAudioQuality('standard');// 自定义设置帧率livePusher.setProperty('setVideoFPS', 25);
4、开启直播推流
// 开启直播// 打开摄像头 livePusher.startCamera();// 打开麦克风livePusher.startMicrophone();//传入云直播推流地址,开始推流。livePusher.startPush(推流地址);
使用腾讯云直播服务时,推流地址需要满足腾讯云标准直播推流 URL 的格式 ,如下所示,它由四个部分组成:
5、关闭直播
// 关闭直播// 停止直播推流livePusher.stopPush();// 关闭摄像头livePusher.stopCamera();// 关闭麦克风livePusher.stopMicrophone();
完整代码:
<body><div id="local_video" style="width:100%;height:500px;display:flex;align-items:center;justify-content:center;"></div></div><script src="https://video.sdk.qcloudecdn.com/web/TXLivePusher-2.1.0.min.js" charset="utf-8"></script><script>//通过全局对象 TXLivePusher 生成 SDK 实例,后续操作都是通过实例完成。const livePusher = new TXLivePusher();// 指定本地视频播放器容器 div,浏览器采集到的音视频画面会渲染到这个 div 当中。livePusher.setRenderView('local_video');// 设置音视频流 livePusher.setVideoQuality('720p');// 设置音频质量livePusher.setAudioQuality('standard');// 自定义设置帧率livePusher.setProperty('setVideoFPS', 25);// 开启直播// 打开摄像头 livePusher.startCamera();// 打开麦克风livePusher.startMicrophone();//传入云直播推流地址,开始推流。livePusher.startPush(推流地址);// 关闭直播// 停止直播推流livePusher.stopPush();// 关闭摄像头livePusher.stopCamera();// 关闭麦克风livePusher.stopMicrophone();</script>
</body>
如有误,请指正!
相关文章:

web端调用本地摄像头麦克风+WebRTC腾讯云,实现直播功能
目录 关于直播直播流程直播视频格式封装推流和拉流 获取摄像头和麦克风权限navigator.getUserMedia()MediaDevices.getUserMedia() WebRTC腾讯云快直播 关于直播 视频直播技术大全、直播架构、技术原理和实现思路方案整理 直播流程 视频采集端: 1、视频采集&#…...

React笔记(八)Redux
一、安装和配置 React 官方并没有提供对应的状态机插件,因此,我们需要下载第三方的状态机插件 —— Redux。 1、下载Redux 在终端中定位到项目根目录,然后执行以下命令下载 Redux npm i redux 2、创建配置文件 在 React 中,…...
数据库 | 数据库概述、关系型数据库、非关系型数据库
目录: 1.数据库:1.1 数据库的含义1.2 数据库的特点 2.数据表3.数据库管理系统4.数据库系统5.关系型数据库 和 非关系型数据库:5.1 关系型数据库5.2 关系型数据库“优势”5.3 非关系型数据库 6.关系型数据库 和 非关系型数据库 的“区别” 1.数…...
【备战csp-j】 csp常考题目详解(4)
四.数值转换与编码 1. 十进制数 11/128 可用二进制数码序列表示为( ) 。 A.1011/1000000 B.1011/100000000 C.0.001011 D.0.0001011 答案:D 解析:暂时未找到解决方法,以后会解决。 2. 算式(2047)10 - (3FF)16 + …...
linux中常见服务端安装
linux安装服务脚本 1、yum安装 # 通过apt安装yum apt install yum # yum安装软件 yum install pam-devel # yum 卸载 yum remove pam-devel2、rpm安装 # 安装 rpm -i example.rpm #安装 example.rpm 包; rpm -iv example.rpm #安装 example.rpm 包并在安装过程…...

L1-058 6翻了(Python实现) 测试点全过
前言: {\color{Blue}前言:} 前言: 本系列题使用的是,“PTA中的团体程序设计天梯赛——练习集”的题库,难度有L1、L2、L3三个等级,分别对应团体程序设计天梯赛的三个难度。更新取决于题目的难度,…...

初学Python记
Python这个编程语言的大名当然听说过了呀,这几年特别火,火的一塌涂地。大家可以回忆一下:朋友圈推荐的广告里经常可以看见python的网课广告。 本学期,学校开设了python课程,这几天学习了一下入了一下门,感…...

计算机竞赛 基于深度学习的目标检测算法
文章目录 1 简介2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 1 简介 ǵ…...
sentinel-core
引入依赖<dependencies><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId></dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-anno…...

【美团3.18校招真题1】
大厂笔试真题网址:https://codefun2000.com/ 塔子哥刷题网站博客:https://blog.codefun2000.com/ 小美剪彩带 提交网址:https://codefun2000.com/p/P1088 题意:找出区间内不超过k种数字子数组的最大长度 使用双指针的方式&…...

Springboot 实践(14)spring config 配置与运用--手动刷新
前文讲解Spring Cloud zuul 实现了SpringbootAction-One和SpringbootAction-two两个项目的路由切换,正确访问到项目中的资源。这两个项目各自拥有一份application.yml项目配置文件,配置文件中有一部分相同的配置参数,如果涉及到修改…...
MyBatisPlus枚举类最佳实践(非常典型和高效的枚举类写法)
目录 1、MyBatisPlus枚举类最佳实践 2、枚举类的作用及问题 3、MyBatisPlus注解实现枚举最佳实践 4、简单来说 5、下面我们看一个使用上述注解的完整枚举类示例: (1)枚举类: (2)DTO类: 6、根据上面…...

uniapp分包 解决分多个包的问题
1. 分包可以分很多个, 但是在"optimization": { "subPackages": true } 里面只能写一个, 2. 想分多个包 , 在 pages.json 里面 的 subPackages 里面继续加 第三个 第四个即可 3. 保存之后 创建页面就可以看见多个包了...

美国封锁激励中国制造业数字化转型的崛起 | 百能云芯
上海在近日公布了第二批工赋链主培育企业名单,共有15家企业入选。这些被称为“链主”的企业在上海制造业数字化转型的过程中扮演着关键角色,类似于领头大雁,它们是上海制造业的数字化网络中的关键节点。 中新社的报道指出,“数字技…...
鼠标键盘自动化工具pyautogui
安装 pip install pyautogui pip install keyboard获取鼠标实时位置 import pyautogui pyautogui.displayMousePosition()样例代码 # https://pyautogui.readthedocs.org/ # https://github.com/asweigart/pyautogui# 紧急停止,手动将鼠标移动到屏幕的4个角落imp…...

0基础学习VR全景平台篇 第96篇:VR电子楼书
大家好,欢迎观看蛙色VR官方系列课程——VR电子楼书! 作为2021年底全新上线的行业解决方案,是专门针对地产、园区数字化营销的一站式VR解决方案,为行业潜在客户提供优质的7x24小时线上看房体验。 本期教程将通过功能介绍后台操作&…...

【MySQL】数据库的约束
MySQL 数据库的约束 文章目录 MySQL 数据库的约束01 数据库的约束1.1 约束类型1.1.1 NOT NULL1.1.2 UNIQUE1.1.3 DEFAULT1.1.4 PRIMARY KEY1.1.5 FOREIGN KEY1.1.6 CHECK 继上文 MySQL基础(一), MySQL基础(二)&#…...

改变金融贷款市场营销方式 ---- 运营商大数据精准获客
与传统的企业网络营销相比,最常见的是网络推广和硬广告推广。一些企业无法找到可靠准确的数据来源,也无法找到一些未知的总数据。这些数据大多存在持续时间长、准确性差的缺点,企业在将这些数据信息应用于商品在线营销时往往会遇到不足。 在…...
SpringBoot实现分页的四种方式
一 自己封装Page对象实现 博客链接 二 使用sql实现分页 2.1 场景分析 前段传递给给后台什么参数? 当前页码currentPage每页显示条数pageSize 后台给前端返回什么数据? 当前页数据List总记录数totalCount 2.2 前段代码 <template><el-paginationsize-change&q…...

远程工作面试:特殊情况下的面试技巧
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...