likes
comments
collection
share

WebRTC 入门笔记

作者站长头像
站长
· 阅读数 1

WebRTC(Web Real-Time Communication)为现代网络应用提供了实时通信的能力。这项技术使得在不需要安装任何插件或第三方软件的情况下,用户可以通过网页浏览器进行音视频通话和数据共享。以下是一个结合了API介绍和实践案例的基础入门文章。

核心特性及API介绍

数据通道(Data Channels)

WebRTC 允许你创建数据通道来发送任意类型的数据。这可以通过 RTCDataChannel API 实现,该 API 提供了一个双向通道来传输数据。

// 假设已经建立了 RTCPeerConnection
let dataChannel = peerConnection.createDataChannel("myDataChannel");

dataChannel.onopen = function(event) {
  dataChannel.send("Hello WebRTC!");
};

信令(Signaling)

虽然 WebRTC API 不直接处理信令,但它提供了所需的所有钩子来交换信令消息。你可以使用 WebSocket、Server-Sent Events 或任何其他服务器端技术来交换这些信息。

// 在A端
peerConnection.onicecandidate = function(event) {
  if (event.candidate) {
    // 通过信令服务器发送候选信息到B端
    sendToServer({
      type: 'new-ice-candidate',
      candidate: event.candidate
    });
  }
};

// 在B端
peerConnection.addIceCandidate(new RTCIceCandidate(candidate))
  .catch(e => console.error(e));

媒体捕获和流(MediaStream API)

WebRTC 使用 navigator.mediaDevices.getUserMedia 来捕获音频和视频。

// 捕获视频和音频流
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
  .then(function(stream) {
    /* 使用这个流 */
  })
  .catch(function(err) {
    /* 处理错误 */
  });

媒体处理

WebRTC 自动处理编解码和其他媒体处理需求。但是,你可以通过 RTCRtpSenderRTCRtpReceiver 接口来获取媒体轨道的详细控制。

// 获取音视频轨道
const tracks = stream.getTracks();
tracks.forEach(function(track) {
  peerConnection.addTrack(track, stream);
});

安全性

WebRTC 通信是通过 DTLS(数据报传输层安全性)和 SRTP(安全实时传输协议)自动加密的。这些是内建在浏览器中的,无需开发者额外配置。

跨平台支持

WebRTC API 是标准化的,因此它在所有支持的浏览器上提供一致的体验。无需任何特殊配置,就可以在桌面和移动平台上使用。

会话描述(Session Description Protocol, SDP)

通过 RTCPeerConnection 创建的 offer 和 answer 对象包含了使用 SDP 描述的媒体元数据。

peerConnection.createOffer().then(function(offer) {
  return peerConnection.setLocalDescription(offer);
}).then(function() {
  // 将 offer 发送给远端
}).catch(function(reason) {
  // 处理错误
});

统计 API(Stats API)

WebRTC 提供了访问实时通信统计数据的 API,你可以通过 getStats 方法获取。

peerConnection.getStats(null).then(function(stats) {
  // 使用统计数据
});

实践案例

视频捕获和显示

以下是一个简单的示例,展示了如何使用 WebRTC API 调用摄像头和麦克风,并显示在本地视频元素上。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebRTC 本地视频示例</title>
</head>
<body>

<video id="localVideo" autoplay playsinline></video>

<script>
  // 获取视频元素
  const localVideo = document.getElementById('localVideo');

  // 设置媒体约束条件
  const mediaConstraints = {
    video: true, // 请求视频
    audio: false // 不请求音频
  };

  // 使用 getUserMedia API 获取媒体流
  navigator.mediaDevices.getUserMedia(mediaConstraints)
    .then((stream) => {
      // 将媒体流绑定到视频元素上,以显示视频
      localVideo.srcObject = stream;
    })
    .catch((error) => {
      console.error('获取媒体流失败:', error);
    });
</script>

</body>
</html>

在这个示例中,我们使用 getUserMedia 方法请求用户的视频和音频设备。成功后,我们将获取到的媒体流绑定到 <video> 元素的 srcObject 属性,从而在页面上显示视频。

录音与播放

首先,需要在HTML中添加一个按钮来控制录音的开始和停止,以及一个audio元素用来播放录制的音频。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebRTC 音频录制示例</title>
</head>
<body>

<button id="startButton">开始录音</button>
<button id="stopButton" disabled>停止录音</button>
<audio id="audioPlayback" controls></audio>

<script>
  // 获取页面元素
  const startButton = document.getElementById('startButton');
  const stopButton = document.getElementById('stopButton');
  const audioPlayback = document.getElementById('audioPlayback');

  // 全局MediaRecorder实例
  let mediaRecorder;
  // 用于存储音频数据的数组
  let audioChunks = [];

  // 开始录音
  startButton.addEventListener('click', () => {
    navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then(stream => {
        mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.start();

        // 数据可用时触发
        mediaRecorder.addEventListener('dataavailable', event => {
          audioChunks.push(event.data);
        });

        // 录音停止时触发
        mediaRecorder.addEventListener('stop', () => {
          // 创建音频Blob
          const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
          // 清空chunks
          audioChunks = [];
          // 创建用于播放的URL
          const audioUrl = URL.createObjectURL(audioBlob);
          // 设置audio元素的src
          audioPlayback.src = audioUrl;
        });

        // 更新按钮状态
        startButton.disabled = true;
        stopButton.disabled = false;
      })
      .catch(error => {
        console.error('获取音频流失败:', error);
      });
  });

  // 停止录音
  stopButton.addEventListener('click', () => {
    mediaRecorder.stop();
    // 更新按钮状态
    startButton.disabled = false;
    stopButton.disabled = true;
  });
</script>

</body>
</html>

在这个示例中,当用户点击“开始录音”按钮时,会调用getUserMedia来请求音频流。成功获取流之后,我们创建一个MediaRecorder实例并开始录音。录音过程中,通过监听dataavailable事件来收集音频数据。当用户点击“停止录音”按钮时,MediaRecorder停止录音,并触发stop事件,此时我们将收集到的音频数据块组合成一个Blob对象,并使用URL.createObjectURL方法为这个Blob对象创建一个URL,这个URL可以被audio元素用来播放录制的音频。

结语

WebRTC 是一项强大且灵活的技术,它打开了实时通信的大门,无论是在应用程序中添加视频聊天功能,还是构建复杂的实时数据共享系统。通过了解和使用 WebRTC 提供的各种 API,你可以创建出令人惊叹的实时通信体验。随着 WebRTC 社区的不断发展,我们期待看到更多创新和功能的加入。