Skip to content
本页目录

[TOC] img.png

web直播

  • WebRTC 采集传输 STUN(Session Traversal Utilities for NAT, TURN ChannelData Message)
  • video 播放
  • 流媒体服务器 处理
  • webSocket(ZegoExpressWebRTC-sdk) 发房间消息 在线人数

实现原理

  • 采集
  • 预览
  • 传输 推流
  • 显示 拉流
  • 最小原型
javascript
let constraints = { audio: true, video: { width: 1280, height: 720 } };
// 视频采集
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints)                                                                          
// 预览
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
    video.play();
};
// 传输 WebRTC todo 
// 显示
video.srcObject = remoteStream;

实现步骤

  1. 登录房间
  2. 推流
  3. 流更新获取拉流地址
javascript
await zg.loginRoom(this.data.roomID, this.data.token, {userID: this.data.userID, userName: 'nick' + this.data.userID});
// 获取推流地址
const {url} = await zg.startPublishingStream(context.data.pushStreamID);
// 推流到服务启后触发流更新 从streamList中拿到拉流src
zg.on("roomStreamUpdate", (roomID, updateType, streamList) => {
  // ... 解析出 remoteStream
  video.srcObject = remoteStream
});

demo

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>WebRTC直播</title>
  <script src="./ZegoExpressWebRTC-2.1.0.js"></script>
</head>
<body>
<video id="local-video" autoplay width="500px" height="500px"></video>
<video id="remote-video" autoplay width="500px" height="500px"></video>

<script>
  (async () => {
    try {
      let appID = 173****9272****706; // 请从官网控制台获取对应的appID
      let server = 'wss://webliveroom-test.zego.im/ws'; // 请从官网控制台获取对应的server地址,否则可能登录失败
      const userId = '1';
      const zg = new ZegoExpressEngine(appID, server);
      // console.log(zg)
      let url = 'https://wsliveroom-alpha.zego.im:8282/token';
      const query = new URLSearchParams({
        app_id: appID,
        id_name: userId
      });
      url = url + '?' + query.toString();
      // url = 'https://wsliveroom-alpha.zego.im:8282/token?app_id=1739272706&id_name=sample1613981824652'
      const res = await fetch(url);
      const token = await res.text();

      const result = await zg.loginRoom('2', token, {
        userID: userId,
        userName: 'feng'
      });
      console.warn({result})

      let constraints = {
        camera: {
          AEC: true,
          AGC: true,
          ANS: true,
          audio: true,
        }
      }
      const localStream = await zg.createStream(constraints);
      let localVideo = document.getElementById('local-video');
      let remoteVideo = document.getElementById('remote-video');
      localVideo.srcObject = localStream;
      // localStream 为创建流获取的 MediaStream 对象
      let t = zg.startPublishingStream('stream002', localStream)
      console.warn('publish stream' , t);


      zg.on('publisherStateUpdate',async result => {
        console.warn('publisherStateUpdate',result);
        const remoteStream = await zg.startPlayingStream(result.streamID);
        // remoteVideo为本地<video>或<audio>对象
        remoteVideo.srcObject = remoteStream;
        // 推流状态更新回调
        // ...
      })

      zg.on('publishQualityUpdate', (streamID, stats) => {
        console.warn('publishQualityUpdate',result);
        // 推流质量回调
        // ...
      })
    } catch (e) {
      console.error(e);
    }
  })();

</script>
</body>
</html>

参考

has loaded