系列文章目录
第一篇 基于SRS 的 WebRTC 情况搭建
第二篇 基于SRS 实现RTSP接入与WebRTC播放
第三篇 centos下基于ZLMediaKit 的WebRTC 情况搭建
第四篇 WebRTC学习一:获取音频和视频设备
第五篇 WebRTC学习二:WebRTC音视频数据采集
第六篇 WebRTC学习三:WebRTC音视频束缚
第七篇 WebRTC学习四:WebRTC常规视觉滤镜
第八篇 WebRTC学习五:从视频中提取图片
第九篇 WebRTC学习六:MediaStream 常用API介绍
前言
WebRTC(Web Real-Time Communication)是一个强盛的技能,可以让网页应用程序和网站举行实时音频、视频和数据共享。通过使用 WebRTC,开发者可以实现高质量的音视频通话,构建实时多媒体应用,而无需用户安装任何插件。本文将在前面文章的基础上进一步介绍 WebRTC 中的 MediaStream API,这是一组用于处理音频和视频流的常用方法。我们将深入探讨这些方法的用法,并给出一个简单的示例,帮助大家更好地理解如安在实际应用中运用这些 API。
一、WebRTC MediaStream API 常用方法
1.getUserMedia()
getUserMedia() 方法是 WebRTC 的焦点,用于请求访问用户的音频和视频设备。该方法接受一个束缚对象,指定请求的音频和视频选项。
- navigator.mediaDevices.getUserMedia({
- video: true,
- audio: true
- }).then(function(stream) {
- // 处理成功获取的媒体流
- }).catch(function(error) {
- // 处理错误
- });
复制代码 2.MediaStream.getTracks()
通过 getTracks() 方法,可以获取与媒体流相关的全部轨道。此方法返回一个包罗全部轨道的数组。
- const tracks = stream.getTracks();
复制代码 3.MediaStream.getAudioTracks()
getAudioTracks() 方法返回音频轨道的数组,便于单独使用或管理音频流。
- const audioTracks = stream.getAudioTracks();
复制代码 4.MediaStream.getVideoTracks()
getVideoTracks() 方法返回视频轨道的数组,开发者可以使用该方法来处理视频相关的使用。
- const videoTracks = stream.getVideoTracks();
复制代码 5.MediaStream.addTrack()
假如需要将新轨道添加到现有的媒体流,可以使用 addTrack() 方法。
- stream.addTrack(newTrack);
复制代码 6.MediaStream.removeTrack()
该方法允许从媒体流中移除指定的轨道。使用时,将要移除的轨道作为参数传入。
- stream.removeTrack(track);
复制代码 7.MediaStream.clone()
clone() 方法用于创建媒体流的副本,副本中的轨道是原轨道的副本,方便用于差别的目标。
- const clonedStream = stream.clone();
复制代码 8.MediaStream.active
该属性为只读布尔值,指示媒体流是否包罗至少一个活动的轨道。可以用来判断流的状态。
- if (stream.active) {
- console.log("Stream is active");
- }
复制代码 2.MediaStream.getTracks()
通过 getTracks() 方法,可以获取与媒体流相关的全部轨道。此方法返回一个包罗全部轨道的数组。
- const tracks = stream.getTracks();
复制代码 9.事件处理
onactive 和 oninactive 事件可以用于跟踪轨道的活动状态。当轨道变为活动或非活动时,会触发相应的事件。
- stream.onactive = function() {
- console.log("At least one track is active");
- };
- stream.oninactive = function() {
- console.log("All tracks are inactive");
- };
复制代码 二、示例
1.html代码
index.html文件内容如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>WebRTC获取视频约束</title>
- <link rel="stylesheet" href="./css/style.css"> <!-- 引入CSS文件 -->
- </head>
- <body>
- <div id="controls">
- <div>
- <label>Audio Source:</label>
- <select id="audioSource"></select>
- </div>
- <div>
- <label>Audio Output:</label>
- <select id="audioOutput"></select>
- </div>
- <div>
- <label>Video Source:</label>
- <select id="videoSource"></select>
- </div>
- <div>
- <label>Filter:</label>
- <select id="filter">
- <option value="none">None</option>
- <option value="blur">Blur</option>
- <option value="grayscale">Grayscale</option>
- <option value="invert">Invert</option>
- <option value="sepia">sepia</option>
- </select>
- </div>
- </div>
- <div id="videoContainer">
- <table>
- <tr>
- <td><video autoplay playsinline id="player"></video></td>
- <td><div id="video-tracks" class="Output"></div></td>
- <td><div id="audio-tracks" class="Output"></div></td>
- </tr>
-
- </table>
- </div>
-
-
- <script src="../adapter.js"></script>
- <script src="./js/client.js"></script>
- </body>
- </html>
复制代码 2.css代码
style.css文件内容如下:
- body {
- display: flex;
- flex-direction: column;
- align-items: center;
- font-family: Arial, sans-serif;
- margin: 0;
- padding: 20px;
- }
- #controls {
- display: flex;
- justify-content: space-between;
- width: 100%;
- max-width: 800px; /* 设置一个最大宽度 */
- margin-bottom: 20px; /* 控件与视频和画布的间距 */
- }
- #videoContainer {
- display: flex;
- }
- #player {
- width: 400px; /* 设置视频宽度 */
- height: auto; /* 自动高度 */
- border: 1px solid #ccc; /* 可选,给视频一个边框 */
- }
- .Output {
- font-family: Arial, sans-serif;
- font-size: 14px;
- line-height: 1.1;
- padding: 10px;
- border: 1px solid #7c6464;
- border-radius: 5px;
- background-color: #f9f9f9;
- }
- .Output div {
- margin-bottom: 2px;
- }
- button {
- margin-top: 10px; /* 按钮与其它元素之间的间距 */
- }
- select {
- margin-right: 10px; /* 下拉框之间的间距 */
- }
- .none {
- -webkit-filter:none;
- }
- .blur {
- -webkit-filter: blur(3px);
- }
- .grayscale {
- -webkit-filter: grayscale(1);
- }
- .invert {
- -webkit-filter: invert(1);
- }
- .sepia {
- -webkit-filter: sepia(1);
- }
复制代码 3.js代码
client.js文件内容如下:
- 'use strict';
- const audioSource = document.querySelector('select#audioSource');
- const audioOutput = document.querySelector('select#audioOutput');
- const videoSource = document.querySelector('select#videoSource');
- const filterSelect = document.querySelector('select#filter');
- const snapshot = document.querySelector('button#snapshot');
- const picture = document.querySelector('canvas#picture');
- const videoplay = document.querySelector('video#player');
- // const audioplay = document.querySelector('audio#audioplayer');
- var videoTrackConstraints = document.querySelector('div#video-tracks');
- var audioTrackContainer = document.querySelector('div#audio-tracks');
-
- // 获取设备列表
- function gotDevices(deviceInfos) {
- deviceInfos.forEach(deviceInfo => {
- const option = document.createElement('option');
- option.text = deviceInfo.label;
- option.value = deviceInfo.deviceId;
- switch (deviceInfo.kind) {
- case "audioinput":
- audioSource.appendChild(option);
- break;
- case "audiooutput":
- audioOutput.appendChild(option);
- break;
- case "videoinput":
- videoSource.appendChild(option);
- break;
- }
- });
- }
- // 获取媒体流
- function gotMediaStream(stream) {
- videoplay.srcObject = stream;
- var videoTracks = stream.getVideoTracks()[0];
- var videoConstraints = videoTracks.getSettings();
- // 将 JSON 对象转换为 HTML 字符串
- let constraintsHTML = '';
- constraintsHTML = '<h2>视频轨道</h2>';
- for (const [key, value] of Object.entries(videoConstraints)) {
- constraintsHTML += `<div><strong>${key}:</strong> ${value}</div>`;
- }
-
- // 插入到 div 元素中
- videoTrackConstraints.innerHTML = constraintsHTML;
- // 显示音频轨道信息
- const audioTracks = stream.getAudioTracks()[0];
- var audioConstraints = audioTracks.getSettings();
- let audioconstraintsHTML = '';
- audioconstraintsHTML= '<h2>音频轨道</h2>';
-
- for (const [key, value] of Object.entries(audioConstraints)) {
- audioconstraintsHTML += `<div><strong>${key}:</strong> ${value}</div>`;
- }
- audioTrackContainer.innerHTML = audioconstraintsHTML;
- return navigator.mediaDevices.enumerateDevices();
- }
- // 处理错误
- function handleError(err) {
- console.error('getUserMedia error:', err);
- }
- // 启动媒体流
- function start() {
- if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
- console.error('getUserMedia is not supported!');
- return;
- }
- const constraints = {
- video: {
- width: 640,
- height: 480,
- frameRate: 30,
- facingMode: "environment",
- deviceId: videoSource.value ? { exact: videoSource.value } : undefined, // 确保使用确切的设备ID
- },
-
- audio: {
- noiseSuppression: true,
- echoCancellation: true
- }
- };
- navigator.mediaDevices.getUserMedia(constraints)
- .then(gotMediaStream)
- .then(gotDevices)
- .catch(handleError);
- }
- // 滤镜选择更改事件
- filterSelect.onchange = function () {
- videoplay.className = filterSelect.value;
- };
- // 初始化
- start();
- videoSource.onchange = start;
复制代码 二、演示效果
在欣赏器中打开 index.html 文件,运行成功的话可以看到左边是视频画面,中间是获取的视频轨道信息,右边是音频轨道信息,下图是我的欣赏器上显示的效果。
总结
WebRTC 的 MediaStream API 提供了一系列强盛而灵活的方法,可以轻松访问和管理用户的音频与视频流。通过使用这些 API,开发者可以大概构建高质量的实时通讯应用。本文介绍的常用 API 及其用法,结合示例代码,希望能帮助大家更好地理解如何使用这些接口。
假如你对 WebRTC 另有其他题目或希望相识更多内容,请随时留言或分享你的看法。
你好,我是阿灿,慢慢理解世界,慢慢更新自己。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |