第十四章 Web端常用的API

本文将详细解析青龙流式系统的三大API:MediaStream、RTCPeerConnection和RTCDataChannel,帮助读者理解并应用这些技术。

MediaStream

MediaStream API是WebRTC中的关键组件之一,它允许使用JavaScript访问设备的摄像头和麦克风。通过使用这个API,开发者可以控制多媒体流数据的消费位置,并对产生媒体的设备进行一定的控制。此外,MediaStream API还提供了有关能够捕获和呈现媒体的设备的信息。

在使用MediaStream API时,我们需要注意以下几点:

  1. 确保浏览器支持该API,并在用户同意的情况下获取媒体访问权限。
  2. 根据需求选择合适的媒体类型和分辨率,以保证通信质量和性能。
  3. 在通信结束时,确保正确释放媒体资源,避免内存泄漏和性能问题。

getUserMedia

getUserMedia是什么?

getUserMedia 是 WebRTC API 中用于访问用户音视频设备的接口,包括摄像头和麦克风。无论是通过 USB 连接的设备还是虚拟设备,都可以通过这个 API 进行访问。它允许用户授予网页访问其设备的权限,并返回一个MediaStream对象,其中包含了音视频轨道。

如何使用 getUserMedia

在简单场景下,直接调用 getUserMedia 的默认参数即可获取 PC 的默认摄像头和麦克风。然而,在处理复杂场景时,例如选择特定的设备,可以按以下步骤操作:

  1. 列出所有可用的媒体设备:获取设备列表以便选择。
  2. 选择所需的设备:从设备列表中选择适合的摄像头和麦克风。
  3. 配置并传递设备信息:将所选设备的信息传递给浏览器 API 以进行设置。

// 1. 列出所有可用的媒体设备
navigator.mediaDevices.enumerateDevices()  
  .then(devices => {    
    devices.forEach(device => {      
        console.log(device.kind, device.label, device.deviceId);    
        });    
        // 2. 根据用户选择的 deviceId 请求媒体流    
        const constraints = {     
            audio: { deviceId: { exact: selectedAudioDeviceId } },
            video: { deviceId: { exact: selectedVideoDeviceId } }    
        };    
        // 3. 请求用户媒体流   
        return navigator.mediaDevices.getUserMedia(constraints);  
      })  
  .then(stream => {    
      // 将媒体流绑定到视频或音频元素上    
      const videoElement.srcObject = stream;  
      })  
  .catch(error => {  
      // 处理获取媒体流失败的情况  
      console.error('媒体设备访问失败:', error);  
  });

媒体约束 constraints

在上述代码片段中,constraints 参数用于指定音视频设备和其属性。以下是几种常见配置及其应用场景:

  1. 同时获取视频和音频输入

const constraints = { audio: true, video: true }

如果没有视频设备,调用时会报错。可以先使用 enumerateDevices 判断是否有视频输入源,再决定是否设置 videofalse

  1. 指定设备

const constraints = { audio: { deviceId: audioId }, video: { deviceId: videoId } }

  1. 指定分辨率

根据网络带宽和设备能力设置分辨率。例如:

// 高分辨率
const constraints = {    
    audio: true,    
    video: {        
          width: { min: 320, ideal: 1280, max: 1920 },        
          height: { min: 240, ideal: 720, max: 1080 }    
          }
 }
 // 低分辨率
 const constraints = {    
     audio: true,    
     video: { width: 720, height: 480 }
 }

  1. 指定摄像头方向

使用 facingMode 属性来选择前置或后置摄像头:

// 前置
const constraints = { audio: true, video: { facingMode: "user" } } 
// 后置
const constraints = { audio: true, video: { facingMode: { exact: "environment" } } }

  1. 指定帧速率 frameRate

帧速率影响视频的流畅度。可以根据网络条件调整帧速率:

const constraints = {    
    audio: true,    
    video: {        
        width: 1920,        
        height: 1080,        
        frameRate: { ideal: 10, max: 24 }    
    }
 }

getDisplayMedia

getDisplayMedia 是什么?

getDisplayMedia API 用于在浏览器中实现屏幕分享功能。它允许用户选择并分享整个屏幕或特定应用窗口,适用于远程会议和在线演示等场景。

如何使用 getDisplayMedia

调用 getDisplayMedia 获取屏幕分享的媒体流。此 API 返回一个 Promise,解析值为包含屏幕视频流的 MediaStream 对象。

async function getShareMedia() {  
    const constraints = { 
        video: { width: 1920, height: 1080 }, 
        audio: false 
     };  
     // 停止之前的媒体流  
     if (window.stream) {    
         window.stream.getTracks().forEach(track => track.stop());  
      }  try {    
          return await navigator.mediaDevices.getDisplayMedia(constraints);  
      } catch (error) {    
          console.error('屏幕分享失败:', error);  
      }
 }

媒体约束 Constraints

  • 基本配置
  • 在屏幕分享中video属性不能设置为false。

const constraints = { video: true };

  • 指定分辨率

 constraints = { video: { width: 1920, height: 1080 } };

  • 音频设置
  • 如果需要分享系统音频,可以将 audio 设置为 true。注意,并非所有浏览器都支持音频分享功能。

const constraints = {  audio: true,  video: { width: 1920, height: 1080 }};

  • 示例对比:
    • 有音频:
    • **无音频:**当audio设置为false后,底部就少了开启系统音频的按钮。

小提示:

在获取新的媒体流之前,建议停止之前的媒体流,以避免设备使用提示,并确保应用逻辑清晰。

if (window.stream) {  
    window.stream.getTracks().forEach(track => track.stop());
}

RTCPeerConnection

RTCPeerConnection 是什么?

RTCPeerConnection用于管理音视频连接。它帮助你建立和维护与其他用户的实时通信,处理媒体流、网络连接等问题。

RTCPeerConnection API是每个浏览器之间点对点连接的核心,RTCPeerConnectionWebRTC组件,用于处理对等体之间流数据的稳定和有效通信。

RTCPeerConnection可以保护Web开发人员免受潜伏在其中的无数复杂性的影响。WebRTC使用的编解码器和协议可以进行大量工作,即使在不可靠的网络上也可以进行实时通信:

  • 丢包隐藏
  • 回声消除
  • 带宽适应性
  • 动态抖动缓冲
  • 自动增益控制
  • 降噪和抑制
  • 图像'清洁'。

如何使用 RTCPeerConnection

创建 RTCPeerConnection 需要提供一个配置对象,通常包含用于网络穿透的服务器信息(如 STUN 服务器)。

const configuration = {    
    iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
};
const peerConnection = new RTCPeerConnection(configuration);

主要功能:

1. 创建连接请求

  • createOffer(): 发起连接请求。
  • createAnswer(): 响应连接请求。

peerConnection.createOffer()    
.then(offer => peerConnection.setLocalDescription(offer))    
.then(() => {        
    // 发送 offer 给对端    
    });

2. 设置描述信息

  • setLocalDescription(description): 设置本地的连接信息。
  • setRemoteDescription(description): 设置对端的连接信息。

peerConnection.setRemoteDescription(new RTCSessionDescription(remoteOffer))    
.then(() => peerConnection.createAnswer())    
.then(answer => peerConnection.setLocalDescription(answer));

3. 处理媒体流

  • addTrack(track, stream): 添加音视频轨道到连接中。
  • addIceCandidate(candidate): 添加网络候选地址。

navigator.mediaDevices.getUserMedia({ video: true, audio: true })    
.then(stream => {        
    stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));    
    });
 peerConnection.addIceCandidate(new RTCIceCandidate(candidate));

4. 事件处理

  • onicecandidate: 当新的网络候选地址出现时触发。
  • ontrack: 当接收到对端的媒体流时触发。
  • oniceconnectionstatechange: 当连接状态变化时触发。

peerConnection.onicecandidate = (event) => {
    if (event.candidate) {        
    // 发送候选地址到信令服务器    
    }
};
peerConnection.ontrack = (event) => {    
     const remoteStream = event.streams[0];    
     // 显示远程媒体流    
     videoElement.srcObject = remoteStream;
};

RTCDataChannel

RTCDataChannel 是什么?

RTCDataChannel 是 WebRTC 提供的一个 API,用于在对等端之间传输任意数据。它支持低延迟、可靠性可选的数据传输方式,使得在音视频通信之外,还可以传输文本、文件等数据。

如何使用 RTCDataChannel

通过 RTCPeerConnection 创建一个数据通道,并定义其配置。

const dataChannel = peerConnection.createDataChannel("myDataChannel");

主要功能:

1. 发送和接收数据

  • send(data): 通过数据通道发送数据,可以是字符串、二进制数据等。
  • onmessage: 当接收到数据时触发。

dataChannel.send("Hello, WebRTC!");
dataChannel.onmessage = (event) => {    
    console.log("Received message:", event.data);
};

2. 事件处理

  • onopen: 当数据通道打开时触发。
  • onclose: 当数据通道关闭时触发。

dataChannel.onopen = () => {    
    console.log("Data channel is open");
 };
 dataChannel.onclose = () => {    
    console.log("Data channel is closed");
 };

参考资料

MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaStream

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉达曼迪斯II

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值