WebRTC音视频采集和播放示例及MediaStream媒体流解析

这篇具有很好参考价值的文章主要介绍了WebRTC音视频采集和播放示例及MediaStream媒体流解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

WebRTC音视频采集和播放示例及MediaStream媒体流解析


目录

  1. 示例代码——同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音
  2. API解析
    1. mediaDevices
    2. MediaStream媒体流

1. 示例代码——同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音

  1. 代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebRTC Demo</title>
</head>
<body>
<video id="local-video" autoplay playsinline></video>
<button id="showVideo">打开音视频</button>
</body>

<script>
    const constraints = {
        audio: true,
        video: {width: 640, height: 480}
    }

    // 处理打开摄像头成功
    function handleSuccess(mediaStream) {
        const video = document.querySelector("#local-video");
        video.srcObject = mediaStream;
    }

    // 异常处理
    function handleError(error) {
        console.error("getUserMedia error: " + error)
    }

    function onOpenAV(e) {
        navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
    }

    document.querySelector("#showVideo").addEventListener("click", onOpenAV)

</script>
</html>

  1. 效果
    WebRTC音视频采集和播放示例及MediaStream媒体流解析

2. API解析

1. mediaDevices

  1. mediaDevices 是 Navigator 只读属性,返回一个 MediaDevices 对象,该对象可提供对相机和麦克风等媒体输入设备的连接访问,也包括屏幕共享。
  2. 语法:
var mediaDevices = navigator.mediaDevices;
  1. MediaDevices 是一个单例对象,可以直接使用此对象的成员,例如通过调用navigator.mediaDevices.getUserMedia()。

2. MediaStream媒体流

  1. navigator.mediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream(媒体流),媒体流是信息的载体,代表了一个媒体设备的内容流。
  2. 媒体流可以被采集、传输和播放,通常一个媒体流包含多个媒体轨道,如音频轨道、视频轨道。
  3. 媒体流使用MediaStream接口来管理,通常获取媒体流的方式有如下几种。
    a. 从摄像头或者话筒获取流对象。
    b. 从屏幕共享获取流对象。
    c. 从canvas(HTMLCanvasElement)内容中获取流对象。
    d. 从媒体元素(HTMLMediaElement)获取流对象。
  4. 上述方法获取的媒体流都可以通过WebRTC进行传输,并在多个对等端之间共享。
  5. 返回一个 Promise 对象,成功后会resolve回调一个 MediaStream 对象。
  6. 若用户拒绝了使用权限,或者需要的媒体源不可用,promise会reject回调一个 PermissionDeniedError 或者 NotFoundError 。
  7. 常见用法:
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  /* 使用这个 stream stream */
})
.catch(function(err) {
  /* 处理 error */
});
  1. MediaStream的定义
interface MediaStream : EventTarget {
  constructor();
  constructor(MediaStream stream);
  constructor(sequence<MediaStreamTrack> tracks);
  readonly attribute DOMString id;
  sequence<MediaStreamTrack> getAudioTracks();
  sequence<MediaStreamTrack> getVideoTracks();
  sequence<MediaStreamTrack> getTracks();
  MediaStreamTrack? getTrackById(DOMString trackId);
  void addTrack(MediaStreamTrack track);
  void removeTrack(MediaStreamTrack track);
  MediaStream clone();
  readonly attribute boolean active;
  attribute EventHandler onaddtrack;
  attribute EventHandler onremovetrack;
};
1. MediaStream属性
1. active只读
  1. 返回MediaStream的状态,类型为布尔,true表示处于活跃状态,false表示处于不活跃状态。
2. id只读
  1. 返回MediaStream的UUID,类型为字符串,长度为36个字符。
2. MediaStream方法
1. addTrack()方法:向媒体流中加入新的媒体轨道。
stream.addTrack(track);
参数:Track,媒体轨道,类型为MediaStreamTrack。
返回值:无。
2. clone()方法:返回当前媒体流的副本,副本具有不同且唯一的标识。
const newstream = stream.clone();
// sameId为false
const sameId = newstream.id === stream.id? true : false
参数:无。
返回值:一个新的媒体流对象。
3. getAudioTracks()方法:返回媒体种类为audio的媒体轨道对象数组,数组成员类型为MediaStreamTrack。
  1. 注意,数组的顺序是不确定的,每次调用都可能不同。
const mediaStreamTracks = mediaStream.getAudioTracks()
参数:无。
返回值:mediaStreamTracks,媒体轨道对象数组,如果当前媒体流没有音频轨道,则返回数组为空。
  1. 示例:使用getUserMedia()方法获取包含视频及音频轨道的媒体流,如果调用成功,则将媒体流附加到<video>元素,然后设置计时器,5s后调用getAudioTracks()方法获取所有音频轨道,最后停止播放第一个音频轨道。
navigator.mediaDevices.getUserMedia({audio: true, video: true})
  .then(mediaStream => {
  document.querySelector('video').srcObject = mediaStream;
  // 5s后,停止播放第一个音频轨道
  setTimeout(() => {
    const tracks = mediaStream.getAudioTracks()
    tracks[0].stop()
  }, 5000)
})
4. getVideoTracks()方法:返回kind属性值为video的媒体轨道对象数组,媒体轨道对象类型为MediaStream Track。
  1. 注意,对象在数组中的顺序是不确定的,每次调用都可能不同。
const mediaStreamTracks = mediaStream.getVideoTracks()
参数:无。
返回值:mediaStreamTracks是媒体轨道对象数组。如果当前媒体流没有视频轨道,则返回数组为空。
  1. 示例:getUserMedia()方法获取视频流,如果调用成功,则将媒体流附加到<video>元素,之后获取第一个视频轨道并从视频轨道截取图片。
navigator.mediaDevices.getUserMedia({video: true})
  .then(mediaStream => {
  document.querySelector('video').srcObject = mediaStream;
  const track = mediaStream.getVideoTracks()[0];
  // 截取图片
  const imageCapture = new ImageCapture(track);
  return imageCapture;
})
5. getTrackById()方法:返回指定ID的轨道对象。
  1. 如果未提供参数,或者未匹配ID值,则返回null;如果存在多个相同ID的轨道,该方法返回匹配到的第一个轨道。
const track = MediaStream.getTrackById(id);
参数:id,类型为字符串。
返回值:如果输入参数id与MediaStreamTrack.id匹配,则返回相应的MediaStream-Track对象,否则返回null
  1. 示例:获取指定ID的媒体轨道并应用约束,将音量调整到0.5。
stream.getTrackById("primary-audio-track").applyConstraints({ volume: 0.5 });
6. getTracks()方法:返回所有媒体轨道对象数组,包括所有视频及音频轨道。
  1. 数组中对象的顺序不确定,每次调用都有可能不同。
const mediaStreamTracks = mediaStream.getTracks()
参数:无。
返回值:媒体轨道对象数组。
  1. 使用getUserMedia()方法获取包含视频轨道的流,如果调用成功,则将流附加到<video>元素,然后设置计时器,5s后获取所有媒体轨道,并停止播放第一个媒体轨道(即视频轨道)。
navigator.mediaDevices.getUserMedia({audio: false, video: true})
.then(mediaStream => {
  document.querySelector('video').srcObject = mediaStream;
  // 5s后,停止播放第一个媒体轨道
  setTimeout(() => {
    const tracks = mediaStream.getTracks()
    tracks[0].stop()
  }, 5000)
})
3. MediaStream事件
1. addtrack事件:当有新的媒体轨道(MediaStreamTrack)加入时触发该事件,对应事件句柄onaddtrack
  1. 注意,只有在如下情况下,才会触发该事件,主动调用MediaStream.addTrack()方法则不会触发。
    1. RTCPeerConnection重新协商。
    2. HTMLMediaElement.captureStream() 返回新的媒体轨道。
  2. 示例:当有新的媒体轨道添加到媒体流时,显示新增媒体轨道的种类和标签。
// event类型为MediaStreamTrackEvent
// event.track类型为MediaStreamTrack
stream.onaddtrack = (event) => {
  let trackList = document.getElementById("tracks");
  let label = document.createElement("li");

  label.innerHTML = event.track.kind + ": " + event.track.label;
  trackList.appendChild(label);
};
  1. 此外,也可以使用addEventListener()方法监听事件addtrack。
2. removetrack事件:当有媒体轨道被移除时触发该事件,对应事件句柄onremovetrack
  1. 注意,只有在如下情况下才会触发该事件,主动调用MediaStream.removeTrack()方法则不会触发。
    1. RTCPeerConnection重新协商。
    2. HTMLMediaElement.captureStream()返回新的媒体轨道。
  2. 示例:当从媒体流中删除媒体轨道时,记录该媒体轨道信息。
// event类型为MediaStreamTrackEvent
// event.track类型为MediaStreamTrack
stream.onremovetrack = (event) => {
  let trackList = document.getElementById("tracks");
  let label = document.createElement("li");

  label.innerHTML = "Removed: " + event.track.kind + ": " + event.track.label;
  trackList.appendChild(label);
};
  1. 此外,也可以使用addEventListener()方法监听事件removetrack。

4. 参数constraints
  1. constraints作为一个MediaStreamConstraints对象,指定了请求的媒体类型和相对应的参数。

  2. constraints 参数是一个包含了video 和 audio两个成员的MediaStreamConstraints 对象,用于说明请求的媒体类型。

    1. 必须至少一个类型或者两个同时可以被指定。
    2. 如果浏览器无法找到指定的媒体类型或者无法满足相对应的参数要求,那么返回的 Promise 对象就会处于 rejected[失败]状态,NotFoundError作为 rejected[失败]回调的参数。
  3. 以下同时请求不带任何参数的音频和视频:

{ audio: true, video: true }
  1. 如果为某种媒体类型设置了 true ,得到的结果的流中就需要有此种类型的轨道。如果其中一个由于某种原因无法获得,getUserMedia() 将会产生一个错误。

  2. 当由于隐私保护的原因,无法访问用户的摄像头和麦克风信息时,应用可以使用额外的 constraints 参数请求它所需要或者想要的摄像头和麦克风能力。

  3. 下面演示了应用想要使用 1280x720 的摄像头分辨率:文章来源地址https://www.toymoban.com/news/detail-403712.html

{
  audio: true,
  video: { width: 1280, height: 720 }
}
  1. 浏览器会试着满足这个请求参数,但是如果无法准确满足此请求中参数要求或者用户选择覆盖了请求中的参数时,有可能返回其它的分辨率。
  2. 强制要求获取特定的尺寸时,可以使用关键字min、max 或者 exact(就是 min == max)。
  3. 以下参数表示要求获取最低为 1280x720 的分辨率。
{
  audio: true,
  video: {
    width: { min: 1280 },
    height: { min: 720 }
  }
}
  1. 如果摄像头不支持请求的或者更高的分辨率,返回的 Promise 会处于 rejected 状态,NotFoundError 作为rejected 回调的参数,而且用户将不会得到要求授权的提示。
  2. 造成不同表现的原因是,相对于简单的请求值和ideal关键字而言,关键字min, max, 和 exact有着内在关联的强制性,比如:
{
  audio: true,
  video: {
    width: { min: 1024, ideal: 1280, max: 1920 },
    height: { min: 776, ideal: 720, max: 1080 }
  }
}
  1. 当请求包含一个 ideal(应用最理想的)值时,这个值有着更高的权重,意味着浏览器会先尝试找到最接近指定的理想值的设定或者摄像头(如果设备拥有不止一个摄像头)。
  2. 简单的请求值也可以理解为是应用理想的值,因此我们的第一个指定分辨率的请求也可以写成如下:
{
  audio: true,
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 }
  }
}
  1. 并不是所有的 constraints 都是数字。例如,在移动设备上面,如下的例子表示优先使用前置摄像头(如果有的话):
{ audio: true, video: { facingMode: "user" } }
  1. 强制使用后置摄像头,请用:
{ audio: true, video: { facingMode: { exact: "environment" } } }
  1. 在某些情况下,比如WebRTC上使用受限带宽传输时,低帧率可能更适宜。
{ video: { frameRate: { ideal: 10, max: 15 } } };
5. 返回值
var promise = navigator.mediaDevices.getUserMedia(constraints);
  1. 返回一个 Promise,这个 Promise 成功后的回调函数带一个 MediaStream 对象作为其参数。
6. 异常值
  1. 返回一个失败状态的 Promise,这个 Promise 失败后的回调函数带一个DOMException对象作为其参数。 可能的异常有:
  2. AbortError[中止错误]
    1. 尽管用户和操作系统都授予了访问设备硬件的权利,而且未出现可能抛出NotReadableError异常的硬件问题,但仍然有一些问题的出现导致了设备无法被使用。
  3. NotAllowedError[拒绝错误]
    1. 用户拒绝了当前的浏览器实例的访问请求;或者用户拒绝了当前会话的访问;或者用户在全局范围内拒绝了所有媒体访问请求。
    2. 较旧版本的规范使用了SecurityError,但在新版本当中SecurityError被赋予了新的意义。
  4. NotFoundError[找不到错误]
    1. 找不到满足请求参数的媒体类型。
  5. NotReadableError[无法读取错误]
    1. 尽管用户已经授权使用相应的设备,操作系统上某个硬件、浏览器或者网页层面发生的错误导致设备无法被访问。
  6. OverconstrainedError[无法满足要求错误]
    1. 指定的要求无法被设备满足,此异常是一个类型为OverconstrainedError的对象,拥有一个constraint属性,这个属性包含了当前无法被满足的constraint对象,还拥有一个message属性,包含了阅读友好的字符串用来说明情况。
  7. NotFoundError[找不到错误]
    1. 找不到满足请求参数的媒体类型。
  8. NotReadableError[无法读取错误]
    1. 尽管用户已经授权使用相应的设备,操作系统上某个硬件、浏览器或者网页层面发生的错误导致设备无法被访问。
  9. OverconstrainedError[无法满足要求错误]
    1. 指定的要求无法被设备满足,此异常是一个类型为OverconstrainedError的对象,拥有一个constraint属性,这个属性包含了当前无法被满足的constraint对象,还拥有一个message属性,包含了阅读友好的字符串用来说明情况。
  10. SecurityError[安全错误]
    1. 在getUserMedia() 被调用的 Document 上面,使用设备媒体被禁止。这个机制是否开启或者关闭取决于单个用户的偏好设置。
  11. TypeError[类型错误]
    1. constraints 对象未设置[空],或者都被设置为false。

到了这里,关于WebRTC音视频采集和播放示例及MediaStream媒体流解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • WebRTC音视频通话-WebRTC视频自定义RTCVideoCapturer相机

    WebRTC音视频通话-WebRTC视频自定义RTCVideoCapturer相机 在之前已经实现了WebRTC调用ossrs服务,实现直播视频通话功能。但是在使用过程中,RTCCameraVideoCapturer类提供的方法不能修改及调节相机的灯光等设置,那就需要自定义RTCVideoCapturer自行采集画面了。 iOS端WebRTC调用ossrs相关,实现

    2024年02月12日
    浏览(62)
  • WebRTC音视频原理

    WebRTC,网页即时通讯(Web Real-Time Communication),是直接在 Web 浏览器内驱动实时通信(语音、视频和任意数据)方法的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准,并于 2011 年标准化,是谷歌开源的一款产品。 WebRTC 实现了浏览器快速

    2023年04月08日
    浏览(73)
  • 【WebRTC】音视频通信

    WebRTC对等体还需要查找并交换本地和远程音频和视频媒体信息,例如分辨率和编解码器功能。 交换媒体配置信息的信令通过使用被称为SDP的会话描述协议格式来交换,被称为提议和应答的元数据块 一方发起调用 getUserMedia 打开本地摄像头 媒体协商(信令交换,媒体协商主要

    2024年02月07日
    浏览(58)
  • WebRTC音视频通话-WebRTC本地视频通话使用ossrs服务搭建

    iOS开发-ossrs服务WebRTC本地视频通话服务搭建 之前开发中使用到了ossrs,这里记录一下ossrs支持的WebRTC本地服务搭建。 ossrs是什么呢? SRS(Simple Realtime Server)是一个简单高效的实时视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT等多种实时流媒体协议。 官网地址:https://ossrs.net/lt

    2024年02月12日
    浏览(46)
  • WebRTC音视频会议底层支撑技术

    WebRTC允许应用使用P2P通信。WebRTC是一个广泛的话题,在本文中,我们将重点讨以下问题。 为什么Web RTC 如此受欢迎? 在P2P连接过程中会发生什么 信号传递 NATs和ICE STUN TURN服务器 VP9视频编解码器 WebRTC APIs 安全 1.为什么Web RTC 如此受欢迎? 开放源代码 它为浏览器提供了端到端

    2024年02月11日
    浏览(59)
  • mediasoup webrtc音视频会议搭建

    拉下源码: https://github.com/versatica/mediasoup-demo 源码里有以下目录其中,app网页的界面终端,broadcasters是广播,也就是他支持我们用ffmpeg推流上去给所有的成员广播,server是流媒体服务器。 源码包含了,https服务器用于浏览器获取界面,信令服务器用于房间管理,和流媒体服务

    2024年02月05日
    浏览(45)
  • webRTC一对一音视频对话

    环境 阿里云操作系统: ubuntu 18.4 amd         注意:安全组一定添加对应的入口端口 nodejs -v 18.19.0 npm -v 10.2.3 需要安装的库 package.json 服务器端         webRTC一定要使用https服务器,如果没有ssl证书,可以使用自制证书         1.创建HTTPS服务器                 使用soc

    2024年01月19日
    浏览(60)
  • WebRTC实战-第二章-使用WebRTC实现音视频通话

    、 什么是WebRTC|WebRTC入门到精通必看|快速学会音视频通话原理|WebRTC超全资料分享FFmpeg/rtmp/hls/rtsp/SRS WebRTC **WebRTC详细指南** http://www.vue5.com/webrtc/webrtc.html WEBRTC三种类型(Mesh、MCU 和 SFU)的多方通信架构 WebRTC API包括媒体捕获,音频和视频编码和解码,传输层和会话管理 。 假设

    2023年04月12日
    浏览(53)
  • WebRTC音视频通话-RTC直播本地视频及相册视频文件

    WebRTC音视频通话-RTC直播本地视频及相册视频文件 WebRTC音视频通话-RTC直播本地视频文件效果图如下 WebRTC音视频通话-RTC直播本地视频文件时候,用到了AVPlayer、CADisplayLink。 AVPlayer是什么? AVPlayer是基于AVFoundation框架的一个类,很接近底层,灵活性强,可以自定义视频播放样式

    2024年02月13日
    浏览(50)
  • WebRTC | 音视频直播客户端框架

            端到端通信互动技术可分解为以下几个技术难点:客户端技术、服务器技术、全球设备网络适配技术和通信互动质量监控与展示技术。         音视频直播可分成两条技术路线:一条是以音视频会议为代表的实时互动直播;另一条是以娱乐直播为代表的流媒体

    2024年02月14日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包