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 = stream
        video.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 = stream
        video.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() {
      // 呼叫者:创建PeerConnection
      const peerConnection = new RTCPeerConnection();

      // 添加本地媒体流到PeerConnection
      localStream.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() {
      // 创建PeerConnection
      const 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>

如有误,请指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/98819.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Spring Boot] 开发时可以运行,但Maven打包后,无法运行

问题&#xff1a;开发过程中一切正常&#xff0c;但在打包后&#xff0c;使用java -jar运行jar包时报错 Exception in thread "main" java.lang.UnsupportedClassVersionError: org/springframework/boot/loader/JarLauncher has been compiled by a more recent ver…

【Latex】使用技能站:(三)使用 Vscode 配置 LaTeX

使用 Vscode 配置 LaTeX 引言1 安装texlive2 安装vscode2.1 插件安装2.2 配置 3 安装SumatraPdf3.1 vscode配置3.2 配置反向搜索 引言 安装texlive 安装vscode 安装SumatraPdf 1 安装texlive 在线LaTeX编辑器&#xff1a;https://www.overleaf.com TeX Live下载&#xff1a;h…

环境异常总结

1.vue项目 npm run dev 运行时报错&#xff1a;webpack-dev-server --inline --progress --config build/webpack.dev.conf.js 不是内部或外部命令 原因&#xff1a;webpack-dev-server存在问题 解决方案&#xff1a;指定 webpack-dev-server 低版本号 方法&#xff1a; 删除 …

Python爬虫-某网酒店数据

前言 本文是该专栏的第5篇,后面会持续分享python爬虫案例干货,记得关注。 本文以某网的酒店数据为例,实现根据目标城市获取酒店数据。具体思路和方法跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93d3cuYnRoaG90ZWxzLmNvbS9saXN0L3NoYW5naGFp …

【LeetCode】84.柱状图中最大的矩形

题目 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释&#xff1a;最大的…

大数据精准营销怎么满足用户的个性化需求?

近年来在AI和媒体的带动下&#xff0c;大数据分析不断介入&#xff0c;各行各业都开始陆续依仗大数据营销这棵大树&#xff0c;以此来更加高效、便捷、智能、精准的服务于用户。 这就像追求恋人一样&#xff0c;投其所好方能成为眷属。 大数据精准营销的好处&#xff1a; 相…

JavaScript基本数组操作

在JavaScript中&#xff0c;内置了很多函数让我们可以去对数组进行操作&#xff0c;本文我们就来学习这些函数吧 添加元素 push ● push可以让我们在数组后面再添加一个数据&#xff0c;例如 const friends ["张三", "李四", "王五"]; frie…

(vue)Vue项目中使用jsPDF和html2canvas生成PDF

(vue)Vue项目中使用jsPDF和html2canvas生成PDF 效果&#xff1a; 安装与使用 1.&#xff1a;安装jsPDF和html2canvas npm install jspdf html2canvas2.在需要生成PDF文档的组件中引入jsPDF和html2canvas <template><div><el-button type"primary"…

一图胜千言!数据可视化多维讲解(Python)

数据聚合、汇总和可视化是支撑数据分析领域的三大支柱。长久以来&#xff0c;数据可视化都是一个强有力的工具&#xff0c;被业界广泛使用&#xff0c;却受限于 2 维。在本文中&#xff0c;作者将探索一些有效的多维数据可视化策略&#xff08;范围从 1 维到 6 维&#xff09;。…

[ros][ubuntu]ros在ubuntu18.04上工作空间创建和发布一个话题

构建catkin工作空间 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace cd ~/catkin_ws/ catkin_make 配置环境变量 echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc 检查环境变量 echo $ROS_PACKAGE_PATH…

如何在不重新安装的情况下将操作系统迁移到新硬盘?

通常情况下&#xff0c;当你的硬盘损坏或文件过多时&#xff0c;电脑会变得缓慢且卡顿。这时&#xff0c;你可能会被建议更换为一块更好的新硬盘。 ​ 在比较HDD和SSD之后&#xff0c;许多用户更愿意选择SSD作为他们的新硬盘&#xff0c;因为SSD比HDD更稳定且运行更安…

Docker consul容器服务自动发现和更新

目录 一、什么是服务注册与发现 二、Docker-consul集群 1.Docker-consul 2.registrator 3.Consul-template 三、Docker-consul实现过程 四、Docker-consul集群配置 1.下载consul服务 2.web服务器启动多例nginx容器&#xff0c;使用registrator自动发现 3.使用…

黑客可利用 Windows 容器隔离框架绕过端点安全系统

新的研究结果表明&#xff0c;攻击者可以利用一种隐匿的恶意软件检测规避技术&#xff0c;并通过操纵 Windows 容器隔离框架来绕过端点安全的解决方案。 Deep Instinct安全研究员丹尼尔-阿维诺姆&#xff08;Daniel Avinoam&#xff09;在本月初举行的DEF CON安全大会上公布了…

CSS判断手机暗黑模式

手机有个功能到了晚上会自动变成深色也就是暗黑模式.这种情况下网页会自动变颜色.如果想自由控制暗黑模式下的html样式的话,可以用如下方式: media (prefers-color-scheme: dark) {/*html, body {*//*filter: invert(1) hue-rotate(180deg);*//*}*/.maill{margin-left: 0;marg…

408考研-数据结构算法-单链表

单链表 线性表的顺序存储结构。它是有缺点的&#xff0c;最大的缺点就是插入和删除时需要移动大量元素&#xff0c;这显然就需要耗费时间。能不能想办法解决呢&#xff1f; 要解决这个问题&#xff0c;我们就得考虑一下导致这个问题的原因。 为什么当插入和删除时&#xff0…

探讨uniapp的页面问题

1 新建页面 uni-app中的页面&#xff0c;默认保存在工程根目录下的pages目录下。 每次新建页面&#xff0c;均需在pages.json中配置pages列表&#xff1b; 未在pages.json -> pages 中注册的页面&#xff0c;uni-app会在编译阶段进行忽略。pages.json的完整配置参考&am…

微信小程序校园生活小助手+后台管理系统|前后分离VUE

《微信小程序校园生活小助手后台管理系统|前后分离VUE》该项目含有源码、文档等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统&#xff0c;该后台采用前后台前后分离的形式使用JavaVUE 微信小程序——前台涉及技术&#…

使用Fiddler模拟网络

Fiddler已经预置提供了模拟Modem速度的选项&#xff0c;其位置位于&#xff1a; Rules->Performances->Simulate Modem Speeds 勾选该选项后&#xff0c;所有通过Fiddler代理的流量都会变得用56k modem上网一般。 要直观观察限速后的效果&#xff0c;最好使用运行在浏览…

微服务之架构演变

随着互联网的发展&#xff0c;网站应用规模不断扩大&#xff0c;网站架构随之不断演变&#xff0c;演变历史大致分为单体应用架构-垂直应用架构-分布式架构-SOA架构-微服务架构-云原生架构 架构演变 单体应用架构 以前网站流量小&#xff0c;只需要一个应用就可以把所有功能…

高等动物的多倍体细胞原来这么有用!从伤口愈合到物种生存,多面手的细胞机制~~~...

2008年&#xff0c;当Vicki Losick获得博士学位并加入卡内基科学研究所&#xff08;Carnegie Institute for Science&#xff09;的果蝇实验室时&#xff0c;该实验室的负责人宣布&#xff0c;他希望他的博士后能够推出新的研究领域。她选择了一个当时流行的焦点&#xff1a;干…