实时音视频云

  • 快速开始

    最近更新时间:2018-10-08 13:49:22

    如果您是想体验一下 SDK 的基本使用,下面的内容会是很好的选择。但是如果您准备集成 SDK 到您的 Web 应用中,建议阅读这篇更为详细的 实时音视频应用开发实践

    注意事项

    因为 Chrome 的安全设置,请确保下面代码中的页面在 localhost 下打开。

    之后的代码我们会使用 async/await 的方式来编写,请确保下面的代码运行在一个 async
    函数包裹之下。比如 async iife。

    (async () => {
      // code goes here
    })();
    

    如果你想使用 promise,可以对下面的代码做一些简单的替换

    try {
      const a = await some_method();
    } catch(e) {
      console.log(e);
    }
    
    // promise 写法
    some_method().then(a => {
    
    }).catch(e => {
      console.log(e);
    })
    

    以下过程的完整代码可以从这里下载 http://sdk-release.qnsdk.com/qnrtc-web-example.zip

    加入房间

    好了,准备就绪之后,让我们准备开始吧。 首先准备一个页面命名为 publish.html, 然后引入我们的 SDK

    <!DOCTYPE html>
    <html>
        <head>
        <meta charset="utf-8" />
            <title>Publish</title>
        <!-- 这里引入我们的 SDK -->
        <script src="./pili-rtc-web.js"></script>
        </head>
        <body>
        <script>
          (async() => {
            // 使用局部变量,将全局变量的 QNRTC 销毁
            const QNRTC = window.QNRTC;
            window.QNRTC = undefined;
          })()
        </script>
        </body>
    </html>
    
    

    在这里我们需要 1 个已知参数,roomToken, 关于这个参数的获取请参照上文提到的 使用 RoomToken
    在这里让我们准备在同一个房间下,不同用户的 2 个 roomToken,一个用于发布,一个用于订阅(之后使用)

    在 script 下写入如下代码,保存。本地起一个 http 服务,通过 localhost 访问这个 publish.html 页面,打开浏览器 log 后看到 current users 后说明加入房间成功。

    const QNRTC = window.QNRTC;
    window.QNRTC = undefined;
    const roomToken = "Your roomToken1";
    const myRTC = new QNRTC.QNRTCSession(); // 初始化我们的 SDK (QNRTC的引入方式见上)
    try {
      const users = await myRTC.joinRoomWithToken(roomToken); // 加入房间
    
      // 因为 await 的特性,当代码执行到这里的时候,joinRoomWithToken 这个异步请求已经完成
      // 如果过程中出现错误,会直接 throw 出来,如果需要处理只要 try/catch 就好
      // 这里的 users 表示该房间中已经存在的用户,具体可以参照 API 文档
      // 你也随时可以通过 myRTC.users 获取当前的用户列表
      console.log('current users', users);
    } catch (e) {
      // 加入房间失败,关于错误处理可以参考下文的 错误处理 一节
      console.log('join room error!', e);
    }
    

    采集本地音视频

    加入房间完成,开始发布吧 , 在发布之前,我们需要通过本机的媒体设备采集本地的媒体数据。为了能够播放这个媒体数据,我们先修改publish.html 增加一个 div 用来播放我们的媒体数据

    <body>
       <div id="localplayer" style="width: 640px; height: 480px; background: #000"></div>
       <script>...</script>
    </body>
    

    script 中继续加入代码

    // 使用内置的 deviceManager 对象采集本地媒体数据
    const stream = await QNRTC.deviceManager.getLocalStream({
        video: { enabled: true },
        audio: { enabled: true },
    });
    
    // 页面上准备用来播放的元素,就是我们刚刚创建的
    const localVideo = document.getElementById('localplayer');
    
    // 拿到 stream 对象后,调用 play 就可以播放了
    // sdk 会在指定的元素下创建相应的 video/audio 标签完成播放
    // 这里第二个参数代表用 静音模式 来播放,本地预览的时候一般我们会设置成静音
    stream.play(localVideo, true);
    

    此时刷新打开 publish 页面(注意需要在 localhost 下),就能看到自己的摄像头画面了。

    发布采集数据

    当我们拿到采集的流后 (刚刚代码中的 stream 对象),就可以将其发布到房间中了。在 script 中继续加入如下代码

    
    // 发布自己本地的流
    try {
      await myRTC.publish(stream);
      console.log("publish success!");
    } catch (e) {
      console.log('publish error!', e);
    }
    

    当 log 看到 punish success!后就表示已经成功地将采集到的音视频数据发布到房间中了,可以被房间中的其他人订阅观看了。下一步,我们将通过一个新的页面订阅这个刚刚发布的流。

    订阅远端数据

    SDK不允许用户自己订阅自己,所以这里我们需要另一个用户来做测试,所以这里用到了之前准备的第二个 roomToken。注意这个 roomToken 需要和上一个页面的房间名一致但是用户名不一致。同时,让我们新准备一个页面 subscribe.html来完成我们的订阅逻辑。这个页面也需要一个div,用于播放我们订阅到的流。

    <!DOCTYPE html>
    <html>
        <head>
        <meta charset="utf-8" />
            <title>Subscribe</title>
        <!-- 同样,这里引入我们的 SDK -->
        <script src="./pili-rtc-web.js"></script>
        </head>
        <body>
           <div id="remoteplayer" style="width: 640px;height: 480px;background: #000"></div>
        <button onclick="joinRoom()">加入房间</button>
        <script>
          // 注意这里我们没有默认运行,而是通过点击加入房间后再运行
          // 这是因为 Chrome 最近禁止了在没有用户交互的前提下网页自动播放有声媒体
          async function joinRoom() {
            // 使用局部变量,将全局变量的 QNRTC 销毁
            const QNRTC = window.QNRTC;
            window.QNRTC = undefined;
            // 同上一章,我们先加入房间,注意这里 roomToken 需要满足上文的要求
            const roomToken = "Your roomToken2";
            // 准备好用来播放的元素
            const remoteVideo = document.getElementById('remoteplayer');
            const myRTC = new QNRTC.QNRTCSession();
            const users = await myRTC.joinRoomWithToken(roomToken);
          }
        </script>
        </body>
    </html>
    
    
    

    接下来就来完成订阅的逻辑吧。这里订阅分 2 种情况:

    • 当进入房间的时候对方就已经发布了,直接可以订阅
    • 当进入房间的时候对方还没有发布,需要等待对方发布才能订阅

    我们分别讨论这 2 种情况

    直接订阅

    在直接订阅之前,我们首先需要判断进入房间的时候对方是否已经发布了,我们注意到 joinRoomWithToken 的返回中有 users 对象,这个对象就是当前房间的用户列表,我们可以通过这个用户列表完成这个判断。

    在 script 中加入如下代码

    for (let i = 0; i < users.length; i +=1) {
      const user = users[i];
      // 如果这个用户正在发布并且不是自己,我们就订阅他
      if (user.published && user.userId !== myRTC.userId) {
        // 通过用户的 userId 订阅目标用户
        // 这里返回和我们最初从本地获取媒体流时的返回格式一样
        // 都是封装后的 Stream 对象
        const remoteStream = await myRTC.subscribe(user.userId);
        // 同样,调用 play 方法,选择页面上准备好用来播放的元素,就可以播放啦
        remoteStream.play(remoteVideo);   
      }
    }
    

    通过这个 for 循环,我们遍历了当前房间中所有的用户(目前例子中只有 2 人),一旦找到了满足订阅条件的,我们就会调用订阅并把他的流播放出来。先打开之前的 publish 页面,通过 log 确认其已经发布了之后,打开 subscribe 页面点击 加入房间,此时就能在画面上看到刚刚摄像头采集的画面了(通过订阅观看)。

    但是如果我们先在 subscribe 页面加入房间,之后再加入这段代码就不管用了。(因为遍历 users 的时候对方还没有发布)。针对这个情况,通过下面的代码来处理。

    事件订阅

    SDK 提供了丰富的事件回调来通知房间内各种状态的变化,具体可以查阅 API 文档中的 事件列表。这里我们使用的事件叫做 "user-publish" 当房间中有用户发布流的时候触发。

    在刚刚的 for 循环之前,joinRoomWithToken 之后,加入如下代码。

    ...
    const users = await myRTC.joinRoomWithToken(roomToken);
    
    myRTC.on("user-publish", async (user) => {
      const remoteStream = await myRTC.subscribe(user.userId);
      remoteStream.play(remoteVideo);
    });
    
    for (let i = 0; i < users.length; i +=1) {
    ...
    

    这样,无论谁先加入房间,只要 publish 页面发布了,最终都能在这里看到他采集下来的流数据。

    至此,我们基本完成了连麦应用的 2 个基本功能的使用——发布和订阅。关于 SDK 所暴露的各个 API 的细节,您之后可以参考我们的 API 文档

    以上内容是否对您有帮助?
  • Icon free helper
    Close