jancd/qiniu-developer_ShareGPT huggingface dataset:
human: 如何处理七牛云的实时音视频浏览器兼容性检测

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >浏览器兼容性检测

#  浏览器兼容性检测

最近更新时间: 2022-01-05 15:28:19

在开始音视频通话之前，建议先对检测当前设备是否正常。根据不同情况，SDK 提供了多种方法来完成检测。

# 接口检测

可以通过
[QNRTC.isBrowserSupported](https://developer.qiniu.com/rtc/9070/WebQNRTC#isBrowserSupported)
来获取 SDK 是否支持当前设备。

    
    
    if (QNRTC.isBrowserSupported) {
      console.log("support!");
    } else {
      console.log("not support!");
    }
    

# 设备检测

可以直接通过请求创建 Track，来判断是否支持媒体流采集。

    
    
    // 测试摄像头采集
    try {
      const track = await QNRTC.createCameraVideoTrack();
    } catch(e) {
      console.log("camera track not support!");
    }
    
    // 测试麦克风采集
    try {
      const track = await QNRTC.createMicrophoneAudioTrack();
    } catch(e) {
      console.log("microphone track not support!");
    }
    

# RTC 全流程检测

除了上面两种检测方法外，SDK 还提供了一个
[QNRTC.checkSystemRequirements](https://developer.qiniu.com/rtc/9070/WebQNRTC#checkSystemRequirements)
方法。执行该方法，会自动检测媒体流采集、加入房间、发布、订阅、离开房间等整个流程。使用方法如下。

    
    
    const result = await QNRTC.checkSystemRequirements();
    if (result.ok) {
      console.log("test ok!");
    } else {
      console.log("test fail", result.reason);
    }
    

注意，由于该方法会实际跑一遍 RTC 视频通话的流程，因此比较耗时，一般需要花费 30s 左右。

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频房间管理

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >房间管理

#  房间管理

最近更新时间: 2022-11-07 17:34:43

本部分介绍如何进行房间管理，获取房间信息以及用户信息等常见功能。

# 监听房间连接状态

SDK 内部维护了当前客户端与房间之间的连接状态，建议在加入房间之前，先对连接状态进行监听，根据当前状态处理相关逻辑。

    
    
    mClient.on('connection-state-changed', function(connectionState) {
        console.log('connection-state-changed', connectionState);
    });
    

其中，[connectionState](https://developer.qiniu.com/rtc/9080/WebQNConnectionState)
表示当前所处状态，每个状态均与相应行为操作相关，例如：

  * 初始情况下，状态为 `DISCONNECTED`
  * 与房间建立连接过程中，状态变为 `CONNECTING`
  * 与房间连接成功后，状态变为 `CONNECTED`
  * 与房间连接断开后重连中，状态变为 `RECONNECTING`
  * 与房间重连成功后，状态变为 `RECONNECTED`
  * 与房间断开连接后，状态再次变为 `DISCONNECTED`

这里需要注意，状态与操作行为相关，如果发生某种操作与当前状态不符的情况，如正处在 `CONNECTED` 中却又一次执行加入房间的行为，则会收到 SDK
抛出的错误。

# 加入房间

在创建房间对象 [QNRTCClient](https://developer.qiniu.com/rtc/9090/WebQNRTCClient)
完成之后，可以调用 [join](https://developer.qiniu.com/rtc/api/9090/WebQNRTCClient#join)
方法来加入房间。

    
    
    const roomToken = "xxx";
    await mClient.join(roomToken);
    

> 关于 roomToken 在服务端的生成可查阅 [RoomToken
> 的签算](https://developer.qiniu.com/rtc/8813/roomToken)。

当本地加入房间，其他正在房间中的远端用户可以通过监听 [user-
joined](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#user-joined)
事件获取该信息。

    
    
    mClient.on('user-joined', function(user){
        console.log('user-joined', user);
    });
    

# 离开房间

本地调用 [leave](https://developer.qiniu.com/rtc/api/9090/WebQNRTCClient#leave)
方法，可以退出房间。

    
    
    await mClient.leave();
    

本地退出房间，正在房间中的远端用户可以通过监听 [user-
left](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#user-left) 事件获取该信息。

    
    
    mClient.on('user-left', function(user) {
        console.log('user-left', user);
    });
    

# 异常退出房间

在网络发生异常等情况下，如果 SDK 与服务端的连接断开，SDK
内部会尝试主动重连。如果重连成功，[connectionState](https://developer.qiniu.com/rtc/9080/WebQNConnectionState)
的状态会变为 `RECONNECTED`。

但是，如果经过多种重连逻辑均无法恢复正常连接时，SDK 会主动退出房间，房间连接状态变为 `DISCONNECTED`。

此时的事件回调中可以获取到第二个参数
[info](https://developer.qiniu.com/rtc/9071/WebQNConnectionDisconnectedInfo)
对象，该对象中包含了异常退出房间的信息。

    
    
    import { QNConnectionState, QNConnectionDisconnectedReason } from "qnweb-rtc";
    
    mClient.on('connection-state-changed', function(connectionState, info) {
        if (connectionState === QNConnectionState.DISCONNECTED && 
        info.reason === QNConnectionDisconnectedReason.ERROR) {
            console.warning("网络异常，请检查网络后重试");
        }
    });
    

此时建议提示用户网络异常，请用户检查网络后重试。

导致异常退出房间的所有场景和相关错误码

  * 用户token错误 `错误码10001`
  * 用户token过期 `错误10002`
  * 断线重连失败 `错误码10007`
  * 用户在其他页面或终端登录 `错误码10022`
  * 房间人数已满 `错误码10011`
  * 房间已关闭 `错误码10012`
  * 重连超时或房间销毁 `错误码21003`

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频发布和订阅

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >发布和订阅

#  发布和订阅

最近更新时间: 2022-07-14 15:45:25

本部分介绍能够实现向房间发布媒体流或取消发布，订阅媒体流或停止订阅等操作。

# 发布本地 Track

发布 Track 前，需要对 Track
进行配置和创建，详情请见[音视频采集](https://developer.qiniu.com/rtc/9387/audio-and-video-
collection-web)。

创建好 Track 后即可将该 Track 通过
[publish](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#publish)
方法向房间内进行发布。

    
    
    await mClient.publish(tracks);
    

发布 Track 成功后，远端用户在监听 [user-
published](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#user-published)
后会收到如下事件通知：

    
    
    mClient.on('user-published', function(userID, track){
        console.log('user-published', userID, track)
    });
    

# 取消发布本地 Track

调用 [unpublish](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#unpublish)
取消发布本地媒体流。

    
    
    await mClient.unpublish(tracks);
    

取消发布成功后，远端用户在监听 [user-
unpublished](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#user-
unpublished) 后会收到如下事件通知：

    
    
    mClient.on('user-unpublished', function(userID, track) {
        console.log('user-unpublished', userID, track);
    });
    

# 订阅远端 Track

当收到远端用户发布的信息后，可以调用
[subscribe](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#subscribe)
方法订阅该 track。

    
    
    mClient.on('user-published', async function(userID, track) {
        const subscribedTrack = await mClient.subscribe(track)
    });
    

与本地 track 相同，成功订阅远端 track 后，即可通过
[play](https://developer.qiniu.com/rtc/9076/WebQNTrack#play) 方法播放。

# 取消订阅远端 Track

调用
[unsubscribe](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#unsubscribe)
方法取消订阅远端 track。

    
    
    await mClient.unsubscribe(tracks);
    

# 自动订阅逻辑

    
    
    /**
     *  用生成的roomToken加入房间
     */
    async function joinRoom(roomToken) {
      // 创建QNRTCClient对象
      const client = QNRTC.createClient();
      // 需要先监听对应事件再加入房间
      autoSubscribe(client);
      // 传入RoomToken，加入房间
      await client.join(roomToken);
      console.log("joinRoom success!");
    }
    
    /**
     * 订阅远端用户发布的音视频轨道
     */
    async function subscribe(client, tracks) {
      // 传入远端用户发布的音视频轨道执行订阅操作。
      // 订阅成功后异步返回订阅成功的远端音视频轨道
      const remoteTracks = await client.subscribe(tracks);
      // 选择页面上的一个元素作为父元素，播放远端的音视频轨
      const remoteElement = document.getElementById("remotetracks");
      // 遍历返回的远端 Track，调用 play 方法完成在页面上的播放
      for (const remoteTrack of [...remoteTracks.videoTracks, ...remoteTracks.audioTracks]) {
          remoteTrack.play(remoteElement);
      }
    }
    
    // 这里的参数 client 是指刚刚初始化的 QNRTCClient 对象, 同上
    function autoSubscribe(client) {
        // 添加事件监听，当房间中出现新的 Track 时就会触发，参数是 trackInfo 列表
        client.on("user-published", (userId,tracks) => {
            console.log("user-published!", userId,tracks);
            subscribe(client, tracks)
            .then(() => console.log("subscribe success!"))
            .catch(e => console.error("subscribe error", e));
        });
    }
    

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频设备管理

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >设备管理

#  设备管理

最近更新时间: 2022-07-14 15:45:42

桌面电脑中可能使用多个媒体设备，本篇文档介绍如何在 SDK 中管理媒体设备。

# 摄像头

可以通过
[QNRTC.getCameras](https://developer.qiniu.com/rtc/9070/WebQNRTC#getCameras)
方法来获取当前所有的摄像头信息。该方法返回值是一个数组，每个元素是一个
[MediaDeviceInfo](https://developer.mozilla.org/en-
US/docs/Web/API/MediaDeviceInfo) 对象，包含了一个摄像头设备的详细信息。获取该对象之后，就可以通过该对象的 label
属性获取设备的名称，通过 deviceId 属性获取设备的唯一标识。

该方法获取是调用时所有的摄像头信息，有些外接摄像头可能存在频繁插入、拔出的情况，因此需要通过监听事件来获取最新的设备信息。代码举例如下：

    
    
    // 监听摄像头设备变化
    QNRTC.onCameraChanged = function(info) {
    
      // 获取到摄像头变化的信息
      console.log('camera changed!', info);
    
      // 获取变化后当前所有的摄像头信息
      const cameras = await QNRTC.getCameras();
    };
    

获取到 deviceId 后，就可以在采集摄像头 Track 时，传入该参数，指定特定的摄像头采集了。代码举例如下：

    
    
    const mCameraTrack = await QNRTC.createCameraVideoTrack({
      cameraId: "xxx", // 传入前面获取到的 deviceId 值
    });
    

# 麦克风

麦克风的处理逻辑与摄像头类似。首先通过
[QNRTC.getMicrophones](https://developer.qiniu.com/rtc/9070/WebQNRTC#getMicrophones)
方法来获取到所有的麦克风设备，返回数据同样是 [MediaDeviceInfo](https://developer.mozilla.org/en-
US/docs/Web/API/MediaDeviceInfo) 对象数组，然后通过监听事件来获取麦克风设备的变化信息。

代码举例如下：

    
    
    // 监听麦克风设备变化
    QNRTC.onMicrophoneChanged = function(info) {
    
      // 获取到麦克风变化的信息
      console.log('microphone changed!', info);
    
      // 获取变化后当前所有的麦克风信息
      const microphones = await QNRTC.getMicrophones();
    };
    
    // 指定 microphone 采集
    const mMicrophoneTrack = await QNRTC.createMicrophoneAudioTrack({
      microphoneId: "xxx" // 传入前面获取到的 deviceId 值
    });
    

# 扬声器

扬声器也可能有多个，获取的逻辑与摄像头、麦克风类似。主要区别是，我们不会指定扬声器采集，而是指定扬声器来播放指定的音频 Track。

首先通过
[QNRTC.getPlaybackDevices](https://developer.qiniu.com/rtc/9070/WebQNRTC#getPlaybackDevices)
方法来获取所有的扬声器设备，返回数据同样是 [MediaDeviceInfo](https://developer.mozilla.org/en-
US/docs/Web/API/MediaDeviceInfo) 对象数组，然后通过监听事件来获取扬声器设备的变化信息。代码举例如下：

    
    
    // 监听扬声器设备变化
    QNRTC.onPlaybackDeviceChanged = function(info) {
    
      // 获取到扬声器变化的信息
      console.log('playback device changed!', info);
    
      // 获取变化后当前所有的扬声器信息
      const playbackDevices = await QNRTC.getPlaybackDevices();
    };
    

获取到扬声器的设备信息后，就可以通过
[setPlaybackDevice](https://developer.qiniu.com/rtc/9087/WebQNRemoteAudioTrack#setPlaybackDevice)
方法来指定特定的扬声器来播放音频。代码举例如下：

    
    
    // 传入前面获取到的扬声器的 deviceId
    await remoteAudioTrack.setPlaybackDevice("xxx");
    

# 设备权限

前面介绍了三个获取设备信息的方法，分别是：

  * getCameras
  * getMicrophones
  * getPlaybackDevices

这里需要注意的是，浏览器对媒体设备做了权限管理，当还没有获取对应的媒体权限时，获取到的媒体设备信息可能不完整。

因此，这三个方法都可以设置一个
[skipPermissionCheck](https://developer.qiniu.com/rtc/9070/WebQNRTC#getCameras)
参数。当该参数值为 false 时，SDK 在请求媒体设备信息前，先请求对应的媒体设备权限。当用户授予权限后，SDK
就可以请求到完整的媒体设备信息并返回。如果此时用户没有授权，则方法会抛出错误。

# 示例代码

设备管理场景示例代码可参考 [API-Examples-Web/switchMediaDevices](https://github.com/pili-
engineering/QNRTC-Web/tree/master/API-Examples-Web/switchMediaDevices)

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频背景音乐混音（旧版）

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >背景音乐混音（旧版）

#  背景音乐混音（旧版）

最近更新时间: 2022-12-01 18:12:15

本部分介绍背景音乐混音功能的使用

> 注意，自 SDK 4.2.0
> 版本开始，发布了新版本的混音功能，新版本混音功能支持多重音效且功能更强大，具体接入参考[混音功能（新版）](https://developer.qiniu.com/rtc/12357/background-
> music-mix-web-new)。

用户可在连麦过程中通过混音功能添加背景音乐，支持 MP3、AAC 等格式的本地或在线音乐，使用方式如下：

# 创建 QNAudioMixer

SDK 当前仅支持基于
[QNMicrophoneAudioTrack](https://developer.qiniu.com/rtc/api/9064/WebQNMicrophoneAudioTrack)
的混音功能，因此，可以通过
[QNMicrophoneAudioTrack](https://developer.qiniu.com/rtc/api/9064/WebQNMicrophoneAudioTrack)
创建 [QNAudioMixer](https://developer.qiniu.com/rtc/api/9066/WebQNAudioMixer)
对象。

    
    
    const filePath = "/sdcard/music/example.mp3";
    const mAudioMixer = mMicrophoneAudioTrack.createAudioMixer(filePath)
    

`createAudioMixer` 不仅支持文件地址，同时还支持 AudioBuffer 与 File 类型。

# 混音控制

在创建了 [QNAudioMixer](https://developer.qiniu.com/rtc/api/9066/WebQNAudioMixer)
实例后，可以通过该实例提供的混音控制接口进行混音操作的控制，使用代码参考如下：

    
    
    // 开始混音
    mAudioMixer.start();
    // 停止混音
    mAudioMixer.stop();
    // 恢复混音
    mAudioMixer.resume();
    // 暂停混音
    mAudioMixer.pause();
    // 设置混音音量，默认值1
    // 0表示静音 1表示原始音量 
    // 建议设置范围：0-10 之间的浮点数
    mAudioMixer.setPlayingVolume(volume);
    

上述为混音基本流程的控制，更多控制方式请参考
[QNAudioMixer](https://developer.qiniu.com/rtc/api/9066/WebQNAudioMixer)。

> 当前**仅支持一个麦克风 track 混一路音频** ，重复针对同一个麦克风 track 创建不同的
> [QNAudioMixer](https://developer.qiniu.com/rtc/api/9066/WebQNAudioMixer) 并执行
> start 操作，后面的会覆盖前面的，即以后执行 start 的音频混音控制器为准进行混音。

## 示例代码

背景音乐混音场景的示例代码可参考 [API-Examples-Web/audioMixing](https://github.com/pili-
engineering/QNRTC-Web/tree/master/API-Examples-Web/audioMixing)

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频视频大小流（新版）

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >视频大小流（新版）

#  视频大小流（新版）

最近更新时间: 2022-11-22 15:27:59

本部分介绍视频大小流的使用方式。

> 注意，自 SDK 4.0.9 版本开始，增加了新版本的大小流功能，本篇文档介绍新版本大小流的用法。如果想要查看旧版本大小流的用法，可以参考
> [视频大小流（旧版）](https://developer.qiniu.com/rtc/9472/video-size-flow-web)。

# 功能介绍

![大小流示意图](https://docs.qnsdk.com/multistream_new.png)

当用户 A 开启大小流时，会发送两个不同分辨率的视频码流到服务端；此时，不同的用户需要订阅 A
的视频流时可以根据自己的需要或者服务端的策略来订阅到不同质量的视频流。

> 新版本大小流功能开启后，会在原视频流的基础上创建一路小流，大流和小流共享同一个 Track，一并发布到房间。

# 开启大小流

在创建视频 track 时，可以通过传入配置参数 lowStreamConfig 来指定小流的配置，该参数接口类型如下：

    
    
    interface QNLowStreamConfig {
      scaleResolutionDownBy: number; // 小流缩放比例
      bitrate: number; // 小流码率（kbps）
    }
    

下面是一个实际发送大小流的例子：

    
    
    // 创建一个摄像头 track
    const cameraTrack = await QNRTC.createCameraVideoTrack({
      encoderConfig: {
        width: 640, // 大流的宽
        height: 480, // 大流的高
        lowStreamConfig: {
          scaleResolutionDownBy: 2, // 小流缩放比例，值为 2 表示小流分辨率是大流配置的 1/2
          bitrate: 100 // 小流码率
        }
      }
    });
    

# 订阅大小流

在选择订阅小流前，首先需要知道目前 track 是否开启了大小流。这个信息可以从
[QNRemoteVideoTrack](https://developer.qiniu.com/rtc/9060/WebQNRemoteVideoTrack)
的 [isLowStreamEnabled](https://developer.qiniu.com/rtc/10566/video-size-flow-
web-new/rtc/9060) 属性中获取。

当确认该路流开启了大小流后，可以通过接口 `QNRemoteVideoTrack.setLowStream` 接口来决定是否切换大流和小流。

当调用接口指定切换小流后，因为各种原因（发布方网络差等）可能发生没有成功切换的情况。如果需要明确知道是否切换成功，可以通过监听 `low-stream-
state-changed` 获取该信息。

代码举例如下：

    
    
    // 监听远端用户发布 track
    mClient.on('user-published', async function(userID, remoteTracks){
    
        // 订阅该 track
        const {videoTracks, audioTracks} = await client.subscribe(remoteTracks);
        
        for (const track of videoTracks) {
            
            // 检查该 track 是否开启了大小流
            if (track.isLowStreamEnabled) {
    
                // 监听事件，判断当前使用的是大流还是小流。回调布尔值，true 表示正在使用小流，false 表示使用的是大流
                track.on("low-stream-state-changed", (state: boolean) => { });
    
                // 传入布尔值，true 表示切换成小流，false 表示切换成大流
                track.setLowStream(true);
            }
        }
    });
    

# 注意事项

  * 浏览器兼容性：目前仅桌面版 Chrome（78 及以上）和 Safari（14 及以上） 支持
  * 发布多路 video track 时，同一时间仅支持其中一路开启大小流
  * 小流的分辨率不可太低，否则浏览器编码无法支持。实际测试，Chrome 下当小流分辨率小于 200*150 时，小流会生成失败

# 新旧版本兼容

大小流新版本和旧版本在使用上主要的区别有下面几点：

  * 旧版本大小流会发布三路流，新版本发送两路
  * 旧版本接口和新版本接口完全不同，两套接口并行

如果完全使用旧版本的大小流，或者完全使用新版本的大小流，均没有问题。但是如果需要在使用旧版本的大小流的客户端和新版本的大小流的客户端之间沟通，则需要注意如下几点：

  * 不可在同一个客户端内同时使用新旧两套接口
  * 一个客户端使用旧版本接口发布大小流，另一个客户端可以使用新版本接口订阅（只能指定小流，MEDIUM 流无法指定）
  * 一个客户端使用新版本接口发布大小流，另一个客户端可以使用旧版本接口订阅（此时没有 MEDIUM 流，不可指定该选项）

# 示例代码

视频大小流示例代码可参考 [API-Examples-Web/videoDualStream](https://github.com/pili-
engineering/QNRTC-Web/tree/master/API-Examples-Web/videoDualStream)

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频视频大小流（旧版）

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >视频大小流（旧版）

#  视频大小流（旧版）

最近更新时间: 2022-03-14 11:40:00

本部分介绍视频大小流的使用方式。

> 注意，自 SDK 4.0.9 版本开始，发布了新版本的大小流功能，新版本大小流功能更加丰富，使用更加简单，推荐使用新版本，具体接入参考
> [视频大小流（新版）](https://developer.qiniu.com/rtc/10566/video-size-flow-web-new)。

# 功能介绍

![大小流示意图](http://docs.qnsdk.com/multistream.png)

当用户 A 开启大小流时，会发送多个不同分辨率的视频码流到服务端；此时，不同的用户需要订阅 A
的视频流时可以根据自己的需要或者服务端的策略来订阅到不同质量的视频流。

> 旧版本大小流功能开启后，会在原视频流的基础上，创建一个一路中流，一路小流，三路流共享同一个 Track，一并发布到房间。

# 开启大小流

在创建音视频 track 时，可以通过 track config 提供的 `isMultiProfileEnabled` 接口来启用大小流功能，以
QNCameraVideoTrack 为例，其启用方式如下：

    
    
    QNRTC.createCameraVideoTrack({
        encoderConfig: {
            isMultiProfileEnabled: true
        }
    });
    

# 订阅大小流

订阅端可以通过
[QNRemoteVideoTrack.isMultiProfileEnabled](https://developer.qiniu.com/rtc/api/9060/WebQNRemoteVideoTrack#isMultiProfileEnabled)
属性判断远端用户是否发布大小流。若接口返回 true，则可通过
[QNRemoteVideoTrack.setProfile](https://developer.qiniu.com/rtc/api/9060/WebQNRemoteVideoTrack#setProfile)
来订阅指定的 QNTrackProfile。

示例代码如下：

    
    
    if (remoteVideoTrack.isMultiProfileEnabled) {
        remoteVideoTrack.setProfile(QNTrackProfile.MEDIUM);
    }
    

> **注意：setProfile 接口仅是设置预期的流等级，并不代表实际的订阅等级，若实际发送端还未发送指定等级的流，则将无法订阅到指定的
> profile**

可以监听 [QNRemoteVideoTrack.profile-
changed](https://developer.qiniu.com/rtc/api/9060/WebQNRemoteVideoTrack#profile-
changed) 当订阅指定 profile 生效后，将通过事件告知，具体使用方式如下：

    
    
    track.on('profile-changed',function(profile){
         // 当订阅的 profile 发生改变时触发，该 profile 为当前实际订阅到的 profile
        console.log('profile-changed',profile)
    })
    

# 注意事项

  * **开启大小流功能设置编码宽高最低为 1280 x 720**
  * **目前仅支持在发送端发布单路视频 track 的场景下，使用大小流功能**
  * **对于开启大小流的用户，建议保证有良好的网络环境，保证多流发送质量**

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频跨房媒体转发

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >跨房媒体转发

#  跨房媒体转发

最近更新时间: 2022-07-14 15:46:31

自 v4.1.0 版本，Web SDK 新增跨房媒体转发功能。

跨房媒体转发允许主播不离开自己的所在的房间，仅通过信令的操作，转发自己的音视频到其他的房间。七牛 RTC SDK
支持同时转发多路至多个房间（具体按照设备状况以及网络状况决定）。依赖此功能，可以很方便的实现直播过程中的连麦，小班课等业务。

# 场景角色配置

场景 [QNClientMode](https://developer.qiniu.com/rtc/11357/QNClientMode-Web)：

  * `QNClientMode.LIVE`: 用于互动直播场景，可以通过设置角色来控制权限。主播可以发布和订阅音视频，观众仅能订阅音视频。
  * `QNClientMode.RTC`: 用于通信场景，所有人都可以发布自己的音视频，不可设置角色。

角色 [QNClientRole](https://developer.qiniu.com/rtc/11358/QNClientRole-Web)：

  * `QNClientRole.BROADCASTER`: 主播角色，拥有发布和订阅音视频的权限。
  * `QNClientRole.AUDIENCE`: 观众角色，仅有订阅音视频的权限。

    
    
    const client = QNRTC.createClient();
    
    await client.setClientMode(QNClientMode.LIVE);
    await client.setClientRole(QNClientRole.BROADCASTER)
    
    await client.join("xxx");
    

注意，场景仅可在加入房间之前设置，角色在加入房间之前或者之后均可设置。

# 跨房媒体转发

针对跨房媒体转发，SDK
提供了开始（[startMediaRelay](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#startMediaRelay)）、更新（[updateMediaRelay](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#updateMediaRelay)）和停止（[stopMediaRelay](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#stopMediaRelay)）三个接口。

    
    
    // 转发目标房间名称及房间 token
    const relayConfig = { destRoomInfos: [
        { roomName: "destRoomName1"; roomToken: "destRoomToken1"; },
        { roomName: "destRoomName2"; roomToken: "destRoomToken2"; },
    ]}
    
    // 开始转发
    const relayResult = await client.startMediaRelay(relayConfig);
    

开始转发成功后，会自动将自己在原房间发布的所有媒体流发布到目标房间中。目标房间的用户会正常收到新用户加入和新用户发布新媒体流的通知。

更新转发的接口使用方法类似，只需要指定想要转发的目标房间信息即可。此方法为全量更新，正在跨房媒体转发中却未被包含在参数中的房间，将停止媒体转发。

    
    
    const relayConfig = { destRoomInfos: [
        { roomName: "destRoomName2"; roomToken: "destRoomToken2"; },
        { roomName: "destRoomName3"; roomToken: "destRoomToken3"; },
    ]}
    
    // 更新转发
    const relayResult = await client.updateMediaRelay(relayConfig);
    

最后就是停止转发。

    
    
    const relayResult = await client.stopMediaRelay();
    

# 转发状态通知

除了在调用媒体转发接口后的 promise 返回后，如果转发过程中发生各种情况，可以通过监听 [media-relay-state-
changed](https://developer.qiniu.com/rtc/9090/WebQNRTCClient#media-relay-
state-changed) 事件获取转发状态通知。

    
    
    client.on("media-relay-state-changed", (roomName: string, state: QNMediaRelayState) => {
        // ...
    });
    

跨房媒体转发状态[QNMediaRelayState](https://developer.qiniu.com/rtc/11353/QNMediaRelayState-
Web)

  * 成功 SUCCESS(0)
  * 主动退出 STOPPED(1)
  * 无效token INVALID_TOKEN(2)
  * 目标房间不存在 NO_ROOM(3)
  * 目标房间已关闭 ROOM_CLOSED(4)
  * 目标房间存在相同用户名的用户 PLAYER_EXISTED(5)

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频错误码

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Web >错误码

#  错误码

最近更新时间: 2022-09-06 15:02:03

本文主要介绍 QNRTC SDK 各端相关的错误码及其建议的处理方式。

> 若返回的错误码本文未提及，请[提交工单](https://support.qiniu.com/tickets/new)或者联系七牛技术支持同学协助解决

# 房间相关错误码

枚举值| 错误码| 说明| 处理方式  
---|---|---|---  
SUCCESS| 0| 无错误| 无  
JOIN_ROOM_ERROR| 10001| 房间 Token 错误| 表示您提供的房间 token 不符合七牛 token 签算规则，详情请参考
[RoomToken 签发服务](https://developer.qiniu.com/rtc/8813/roomToken)  
JOIN_ROOM_ERROR| 10002| 房间 Token 过期| 表示您的房间 token 过期，需要重新生成 token 再加入  
JOIN_ROOM_ERROR| 10022| 房间内已经有同名用户| 后台如果配置为开启“禁止自动踢人”，则同一用户重复加入/未正常退出再加入会触发此错误  
JOIN_ROOM_ERROR| 10054| 媒体协商失败| 表示该设备不支持指定的音视频格式，无法进行连麦的操作  
ERROR_AUTH_FAILED| 21001| 加入房间认证失败| 服务验证时出错，可能为服务网络异常，也可能是 token 验证失败，建议检查签算
token 的信息是否异常，若 token 无误，可重新尝试加入房间  
ERROR_RECONNECT_FAILED| 21003| 30s 内未能重连成功或者重连时房间已被销毁| 建议检查网络并重新申请 token
加入房间。当发生该错误时，之前创建的转推任务将被服务销毁，如有需要，应在下次成功加入房间后按业务需要恢复  
ERROR_FATAL| 21005| 非预期错误| 需要检查接口调用、设备状态、网络状态等是否正常  
  
# 设备采集相关错误码

枚举值| 错误码| 说明| 处理方式  
---|---|---|---  
ERROR_NOT_SUPPORT| 21006| 设备原因，对当前操作涉及的接口、媒体格式等不兼容| 更新浏览器版本或者调整输入的媒体数据格式  
ERROR_PLUGIN_NOT_AVAILABLE| 23003| 指定了 Chrome 插件采集，但是浏览器未安装该插件|
提示用户安装浏览器[插件](https://chrome.google.com/webstore/detail/qnrtc-screen-
capture/kelbkaklgngbpjmfopeiclhfmpgnkkpe?hl=zh-CN)  
ERROR_DEVICE_NOT_ALLOWED| 23004| 采集时请求媒体设备未获得用户授权| 提示用户同意授权  
CREATE_SCREEN_AUDIO_ERROR| 23005| 屏幕采集时指定了要求采集系统声音，但是用户未选择系统声音选项| 提示用户选择系统声音选项  
  
# Track 相关错误码

枚举值| 错误码| 说明| 处理方式  
---|---|---|---  
ERROR_INVALID_PARAMETER| 10053| 非法参数| 请检查待发布 Track 是否为本地 Track，并且不为空  
ERROR_FATAL| 21005| 非预期错误| 需要检查接口调用、设备状态、网络状态等是否正常  
ERROR_PLAY_NOT_ALLOWED| 21007| 自动播放失败|
参考[最佳实践文档](https://developer.qiniu.com/rtc/10266/we-best-practices)处理  
  
# 混音相关错误码

枚举值| 错误码| 说明| 处理方式  
---|---|---|---  
ERROR_AUDIO_DECODE_ERROR| 22011| 媒体文件解码错误| 检查媒体文件是否正常  
  
# CDN 转推相关错误码

枚举值| 错误码| 说明| 处理方式  
---|---|---|---  
ERROR_INVALID_PARAMETER| 10053| 参数错误| 请检查操作的参数是否合法  
ERROR_FATAL| 21005| 服务端错误| 请重新尝试操作或者联系七牛技术支持同学协助定位  
  
以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频初始化

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Windows >初始化

#  初始化

最近更新时间: 2022-03-24 13:58:58

本部分介绍了实时音视频的初始化方式及其配置项。

在加入房间前，SDK 提供了一系列的方法用来进行初始化配置。在配置好后通过 QNRTC::CreateClient 创建 QNRTCClient对象 即可。

## 初始化

    
    
    qiniu::QNRTCSetting setting;
    qiniu::QNRTC::Init(setting, this);
    

## 设置日志等级

通过调用 `QNRTC::SetLogFile` 设置 SDK 的日志等级

    
    
    static int32_t SetLogFile(QNLogLevel level,const std::string& dir_name,const std::string& file_name);
    

以上内容是否对您有帮助？
human: 如何处理七牛云的实时音视频房间管理

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > Windows >房间管理

#  房间管理

最近更新时间: 2022-03-24 14:16:17

房间表示一个多人的视频会话，本部分介绍如何进行房间管理，获取房间信息以及用户信息等常见功能。

## 加入房间

本地调用 [QNRTCClient.Join(String
token)](https://developer.qiniu.com/rtc/api/9446/QNRTCClient#Join) 通过
roomToken 加入房间。

    
    
    virtual void Join(const std::string& token, const std::string& user_data = "") = 0;
    

示例代码如下：

    
    
    client->Join(room_token);
    

>   1. 请确保在 `QNConnectionState.kDisconnected` 状态下调用该接口加入房间，否则接口调用无效
>   2. 加入房间时根据业务需求，每个用户可通过 `user_data` 携带自定义数据
>

关于 roomToken 在服务端的生成可查阅 [RoomToken
的签算](https://doc.qnsdk.com/rtn/docs/rtn_startup)。

本地加入房间成功后，会触发如下回调：

**本地用户收到的回调：**

当成功加入房间后，会通过
[QNClientEventListener.OnConnectionStateChanged](https://developer.qiniu.com/rtc/api/9407/QNClientEventListener#OnConnectionStateChanged)
接收到房间状态改变的通知

    
    
    class QNClientEventListener
    {
    public:
        // 当房间状态改变时会触发此回调，成功加入房间后，回调状态为 QNConnectionState.kConnected
        virtual void OnConnectionStateChanged(QNConnectionState state, const QNConnectionDisconnectedInfo& info) = 0;
    }
    

**远端用户收到的回调：**

    
    
    class QNClientEventListener
    {
    public:
        // 当远端用户加入房间时会触发此回调
        virtual void OnUserJoined(const std::string& remote_user_id, const std::string& user_data) = 0;
    }
    

* * *

## 离开房间

本地调用
[QNRTCClient.Leave()](https://developer.qiniu.com/rtc/api/9446/QNRTCClient#Leave)
退出房间。本地退出房间成功后，会触发如下回调：

**本地用户收到的回调：**

    
    
    class QNClientEventListener
    {
    public:
        // 当房间状态改变时会触发此回调，成功离开房间后，回调状态为 QNConnectionState.kDisconnected，QNConnectionDisconnectedInfo 回调 Reason 为 kLeave
        void OnConnectionStateChanged(QNConnectionState state, const QNConnectionDisconnectedInfo& info) = 0;
    }
    

**远端用户收到的回调：**

    
    
    class QNClientEventListener
    {
    public:
        // 当远端用户离开房间时会触发此回调
        virtual void OnUserLeft(const std::string& remote_user_id) = 0;
    }
    

* * *

## 房间信息

### 获取房间内远端用户信息

本地可调用 [QNRTCClient.GetRemoteUsers(const std::string&
userId)](https://developer.qiniu.com/rtc/api/9446/QNRTCClient#GetRemoteUsers%5B1/2%5D)
接口获取音视频通话房间中的指定用户。

    
    
    virtual QNRemoteUser& GetRemoteUsers(const std::string& userId) = 0;
    

本地可调用
[QNRTCClient.GetRemoteUsers()](https://developer.qiniu.com/rtc/api/9446/QNRTCClient#GetRemoteUsers%5B2/2%5D)
接口获取音视频通话房间中的远端用户列表。

    
    
    virtual RemoteUserList& GetRemoteUsers() = 0;
    

其中，[QNRemoteUser](https://developer.qiniu.com/rtc/api/9441/QNRemoteUser)
代表远端用户的信息，通过该对象可以获取指定 user 发布的音视频列表以及本地对其的订阅情况。

以上内容是否对您有帮助？