Options
All
  • Public
  • Public/Protected
  • All
Menu

Interface Client

Client 接口提供音视频通话的核心功能,例如加入房间、发布和订阅音视频流等。

请使用 NERTC.createClient 创建 Client 对象,Client 对象指通话中的本地或远程用户,提供云信 NERTC SDK 的核心功能。

Hierarchy

  • Client

Index

Methods

addTasks

  • addTasks(options: { rtmpTasks: RTMPTask[] }): Promise<undefined>
  • 添加房间推流任务。

    成功调用该方法后,当前用户可以收到该直播流的状态通知 Client.on("rtmp-state")

    • 该方法仅适用直播场景。
    • 请在房间内调用该方法,该方法在通话中有效。
    • 该方法每次只能增加一路旁路推流地址。如需推送多路流,则需多次调用该方法。同一个音视频房间(即同一个 channelid)可以创建 3 个不同的推流任务。
    example
    // 配置推流任务
    let rtmpTasks = [{
      taskId:'12345',
      streamUrl:'rtmp://xxxx',
      record:'true',
      layout:{
        canvas:{width:1280, height:720, color:16777215},
        users:[{adaption:1, uid:123, width:640, height:480, x:640, y:0, zOrder:2, pushAudio:true, pushVideo:true}]
      }
    }]
    // 推流
    client.addTasks({
       rtmpTasks
     }).then((obj) => {
       console.info('添加推流任务成功...')
     }).catch(err => {
       console.error('添加推流任务失败: ', err)
     })
    

    Parameters

    • options: { rtmpTasks: RTMPTask[] }
      • rtmpTasks: RTMPTask[]

        推流任务信息。

    Returns Promise<undefined>

cleanMediaRecording

  • cleanMediaRecording(): Promise<undefined>
  • 清除内存中的录制的音视频数据

    since

    V4.6.10

    note
    • 客户端录制,数据是保持在内存中,需要主动调用该接口进行释放内存资源。
    example
     // await client.startMediaRecording() 开启录制之后
     await client.cleanMediaRecording();
    

    Returns Promise<undefined>

deleteTasks

  • deleteTasks(options: { taskIds: string[] }): Promise<void>
  • 删除房间推流任务。

    • 该方法仅适用直播场景。
    • 请在房间内调用该方法,该方法在通话中有效。
    example
    // 删除推流任务
    let taskIds = ['123456']
    client.deleteTasks({
       taskIds
     }).then((obj) => {
       console.info('删除推流任务成功...')
     }).catch(err => {
       console.error('删除推流任务失败: ', err)
     })
    

    Parameters

    • options: { taskIds: string[] }
      • taskIds: string[]

        推流任务 ID。

    Returns Promise<void>

destroy

  • destroy(): void
  • 销毁客户端对象。

    example
    // 1. 创建client
    client = NERTC.createClient({appkey: "<您的appkey>", debug: true});
    // 2. 加入频道
    await client.join({
      channelName: 'channel163',
      uid: 123,
      token: '<您的token>', // 如关闭了安全模式,则不需要该参数。
    });
    // 3. 通话结束后退出房间
    await client.leave()
    // 4. 若后续再不使用该 client,则可以销毁该 client 实例
    client.destroy()
    

    Returns void

disableDualStream

  • disableDualStream(): void
  • 关闭双流模式

    双流模式默认为关闭状态。如如开启双流模式后需关闭,请在 Client.unpublish 后、再次 Client.publish 之前调用该方法。

    example
    await client.unpublish(localStream)
    // 需要在 unpublish 之后调用
    client.disableDualStream()
    

    Returns void

downloadMediaRecording

  • downloadMediaRecording(): Promise<undefined>
  • 下载录制的音视频数据,生成录制文件

    since

    V4.6.10

    note
    • 客户端录制,数据是保持在内存中,如果没有执行cleanMediaRecording释放,可以多次调用该接口生产录制文件。
    • 下载地址为浏览器默认地址
    example
    // await client.startMediaRecording() 开启录制之后
    await client.downloadMediaRecording();
    

    Returns Promise<undefined>

enableCustomTransform

  • enableCustomTransform(): void
  • 启用自定义加密 需要在加入频道前调用client.enableCustomTransform()方法。调用后,可收到两个事件:sender-transformreceiver-transform,应在这两个方法中实现加密和解密操作。 自定义加密功能依赖 encodedInsertableStreams 接口。目前仅支持桌面端Chrome 94及以上版本。

    H264加密注意事项:

    1. 加密后的rtp分包环节会依赖nalu位置。建议只对关键帧和参考帧进行加密,保留其他帧类型,并且加密时沿naluType向后再保留至少三个字节。
    2. 不同设备编码后的定位符既可能出现0,0,0,10,0,1,也可能两种定位符交替出现。
    3. 加密算法可能会破坏rbsp的语法,容易在内容里引入和rbsp冲突的字段,造成nalu划分失败,表现为低概率性的绿屏。建议先转成sodb,再加密,再转回rbsp。
    example
    // 开启自定义加密
    client.enableCustomTransform()
    // 加入频道
    await client.join({
      channelName: 'channel163',
      uid: 123,
      token: '<您的token>', // 如关闭了安全模式,则不需要该参数。
    });
    //监听 sender-transform 事件,操作加密
    rtc.client.on('sender-transform', processSenderTransform)
    const processSenderTransform = function (evt) {
      // 加密操作
    }
    //监听 receiver-transform 事件,操作解密
    rtc.client.on('receiver-transform', processReceiverTransform)
    const processReceiverTransform = function (evt) {
      // 解密操作
    }
    

    Returns void

enableDualStream

  • enableDualStream(dualStreamSetting?: { screen: boolean; video: boolean }): void
  • 开启双流模式

    双流为视频大流和视频小流,其中视频大流指高分辨率、高码率的视频流,视频小流指低分辨率、低码率的视频流。

    since

    V4.6.0

    note

    注意事项

    • 该方法在 Publish 端,即发送端调用。该方法建议在 Client.join 后、Client.publish 前调用。
    • 接收端大小流通过 Client.subscribeClient.setRemoteStreamType 进行调用和切换。
    • 视频小流的目标码率为100kbps,屏幕共享小流的目标码率为200kbps。
    • SDK会尝试使用接近 180p(240x180) 的低分辨率进行重新采集以提高编解码效率。浏览器会尽量在保证长宽比的情况下使小流的采集接近180p。但由于浏览器和摄像头的限制,小流的分辨率也会出现240p、480p甚至与大流一致的情况,这些都为正常现象。
    • 部分H5设备开启小流异常时,建议在Client.subscribe时选择订阅大流,再通过Client.setRemoteStreamType切换为小流。
    example
    // 加入频道后
    rtc.localStream = NERTC.createStream({
      audio: true,
      video: true,
      uid: 1234,
      client: rtc.client,
    })
    await rtc.localStream.init()
    rtc.client.enableDualStream()
    await rtc.client.join({
      channelName: "channelName",
      token: "token",
      uid: 1234
    });
    

    Parameters

    • Optional dualStreamSetting: { screen: boolean; video: boolean }
      • screen: boolean
      • video: boolean

    Returns void

getChannelInfo

  • getChannelInfo(): { channelName: string; cid: number; token: string; uid: string | number }
  • 获取当前通话信息。

    example
    const channelInfo = rtc.client.getChannelInfo()
    

    Returns { channelName: string; cid: number; token: string; uid: string | number }

    • channelName: string

      用户输入的频道名。

    • cid: number

      频道ID,可用于服务端API调用。

    • token: string

      用户输入的token。

    • uid: string | number

      用户输入的id。当用户输入的uid为0时,则可获取服务端随机分配的uid。

getConnectionState

  • getConnectionState(): ConnectionState
  • 主动获取网络连接状态。

    example
    let connectionState = rtc.client.getConnectionState()
    

    推荐用于以下场景:

    • 在 App 异常重启时,可以调用本接口主动获取当前客户端与服务器的连接状态,以做到本地与服务器状态的对齐。
    • 在实时音视频通话等业务场景中,主动获取房间的网络连接状态,以此完成上层业务逻辑。

    SDK 与服务器的连接状态,共有以下 4 种:

    • DISCONNECTED:网络连接断开。该状态表示 SDK 处于:

      1. 调用 Client.join 加入房间前的初始化阶段。
      2. 调用 Client.leave 离开房间之后。
    • CONNECTING:建立网络连接中。该状态表示 SDK 处于:

      1. 调用 Client.join 之后正在与指定房间建立连接。
      2. 通话过程中,连接中断自动重连。
    • CONNECTED:已连接。该状态表示用户已经成功加入房间,可以在房间内发布或订阅媒体流。

    • DISCONNECTING:正在断开连接。

      1. 在调用 Client.leave 的时候为此状态。

    Returns ConnectionState

getLocalAudioStats

  • getLocalAudioStats(): Promise<any>
  • 获取本地发布流的音频统计数据。

    note

    注意事项

    • 仅在chrome内核的浏览器上支持。
    example
    setInterval(async () => {
      const localAudioStats = await rtc.client.getLocalAudioStats();
      if (localAudioStats[0]){
        console.log(`===== localAudioStats =====`);
        console.log(`Audio CodecType: ${localAudioStats[0].CodecType}`);
        console.log(`Audio MuteState: ${localAudioStats[0].MuteState}`);
        console.log(`Audio RecordingLevel: ${localAudioStats[0].RecordingLevel}`);
        console.log(`Audio SamplingRate: ${localAudioStats[0].SamplingRate}`);
        console.log(`Audio SendBitrate: ${localAudioStats[0].SendBitrate}`);
        console.log(`Audio SendLevel: ${localAudioStats[0].SendLevel}`);
        console.log(`Audio SendLevel: ${localAudioStats[0].rtt}`);
      }
    }, 1000)
    

    Returns Promise<any>

getLocalVideoStats

  • getLocalVideoStats(mediaType?: "video" | "screen"): Promise<any>
  • 获取本地发布流的视频统计数据。

    note

    注意事项

    • 仅在chrome内核的浏览器上支持。
    example
    setInterval(async () => {
      const localVideoStats = await rtc.client.getLocalVideoStats();
      for (var i in localVideoStats){
        let mediaType = (i === 0 ? "video" : "screen")
        console.log(`===== localVideoStats ${mediaType} =====`);
        console.log(`${mediaType} CaptureFrameRate: ${localVideoStats[i].CaptureFrameRate}`);
        console.log(`${mediaType} CaptureResolutionHeight: ${localVideoStats[i].CaptureResolutionHeight}`);
        console.log(`${mediaType} CaptureResolutionWidth: ${localVideoStats[i].CaptureResolutionWidth}`);
        console.log(`${mediaType} EncodeDelay: ${localVideoStats[i].EncodeDelay}`);
        console.log(`${mediaType} MuteState: ${localVideoStats[i].MuteState}`);
        console.log(`${mediaType} SendBitrate: ${localVideoStats[i].SendBitrate}`);
        console.log(`${mediaType} SendFrameRate: ${localVideoStats[i].SendFrameRate}`);
        console.log(`${mediaType} SendResolutionHeight: ${localVideoStats[i].SendResolutionHeight}`);
        console.log(`${mediaType} SendResolutionWidth: ${localVideoStats[i].SendResolutionWidth}`);
        console.log(`${mediaType} TargetSendBitrate: ${localVideoStats[i].TargetSendBitrate}`);
        console.log(`${mediaType} TotalDuration: ${localVideoStats[i].TotalDuration}`);
        console.log(`${mediaType} TotalFreezeTime: ${localVideoStats[i].TotalFreezeTime}`);
      }
    }, 1000)
    

    Parameters

    • Optional mediaType: "video" | "screen"

      媒体流类型。"video"为视频流,"screen"为屏幕共享流。如不填,则一起返回

    Returns Promise<any>

getRemoteAudioStats

  • getRemoteAudioStats(): Promise<any>
  • 获取远端订阅流的音频统计数据。

    note

    注意事项

    • 仅在chrome内核的浏览器上支持。
    example
    setInterval(async () => {
      const remoteAudioStatsMap = await rtc.client.getRemoteAudioStats();
      for(var uid in remoteAudioStatsMap){
          console.log(`Audio CodecType from ${uid}: ${remoteAudioStatsMap[uid].CodecType}`);
          console.log(`Audio End2EndDelay from ${uid}: ${remoteAudioStatsMap[uid].End2EndDelay}`);
          console.log(`Audio MuteState from ${uid}: ${remoteAudioStatsMap[uid].MuteState}`);
          console.log(`Audio PacketLossRate from ${uid}: ${remoteAudioStatsMap[uid].PacketLossRate}`);
          console.log(`Audio RecvBitrate from ${uid}: ${remoteAudioStatsMap[uid].RecvBitrate}`);
          console.log(`Audio RecvLevel from ${uid}: ${remoteAudioStatsMap[uid].RecvLevel}`);
          console.log(`Audio TotalFreezeTime from ${uid}: ${remoteAudioStatsMap[uid].TotalFreezeTime}`);
          console.log(`Audio TotalPlayDuration from ${uid}: ${remoteAudioStatsMap[uid].TotalPlayDuration}`);
          console.log(`Audio TransportDelay from ${uid}: ${remoteAudioStatsMap[uid].TransportDelay}`);
      }
    }, 1000)
    

    Returns Promise<any>

getRemoteVideoStats

  • getRemoteVideoStats(mediaType?: "video" | "screen"): Promise<any>
  • 获取远端订阅流的视频统计数据。

    note

    注意事项

    • 仅在chrome内核的浏览器上支持。
    example
    setInterval(async () => {
      const remoteVideoStatsMap = await rtc.client.getRemoteVideoStats();
       for(var uid in remoteVideoStatsMap){
         console.log(`Video End2EndDelay from ${uid}: ${remoteVideoStatsMap[uid].End2EndDelay}`);
         console.log(`Video MuteState from ${uid}: ${remoteVideoStatsMap[uid].MuteState}`);
         console.log(`Video PacketLossRate from ${uid}: ${remoteVideoStatsMap[uid].PacketLossRate}`);
         console.log(`Video RecvBitrate from ${uid}: ${remoteVideoStatsMap[uid].RecvBitrate}`);
         console.log(`Video RecvResolutionHeight from ${uid}: ${remoteVideoStatsMap[uid].RecvResolutionHeight}`);
         console.log(`Video RecvResolutionWidth from ${uid}: ${remoteVideoStatsMap[uid].RecvResolutionWidth}`);
         console.log(`Video RenderFrameRate from ${uid}: ${remoteVideoStatsMap[uid].RenderFrameRate}`);
         console.log(`Video RenderResolutionHeight from ${uid}: ${remoteVideoStatsMap[uid].RenderResolutionHeight}`);
         console.log(`Video RenderResolutionWidth from ${uid}: ${remoteVideoStatsMap[uid].RenderResolutionWidth}`);
         console.log(`Video TotalFreezeTime from ${uid}: ${remoteVideoStatsMap[uid].TotalFreezeTime}`);
         console.log(`Video TotalPlayDuration from ${uid}: ${remoteVideoStatsMap[uid].TotalPlayDuration}`);
         console.log(`Video TransportDelay from ${uid}: ${remoteVideoStatsMap[uid].TransportDelay}`);
      }
    }, 1000)
    

    Parameters

    • Optional mediaType: "video" | "screen"

      媒体流类型。"video"为视频流,"screen"为屏幕共享流。默认为"video"。

    Returns Promise<any>

getSessionStats

  • getSessionStats(): Promise<any>
  • 获取与会话的连接状况统计数据。

    note

    注意事项

    • 请在加入房间后调用此方法。
    • 仅在chrome内核的浏览器上支持。
    example
    // 加入房间之后调用
    let sessionStats = await rtc.client.getSessionStats()
    console.log(`===== sessionStats =====`)
    console.log(`Duration: ${sessionStats.Duration}`)
    console.log(`RecvBitrate: ${sessionStats.RecvBitrate}`)
    console.log(`RecvBytes: ${sessionStats.RecvBytes}`)
    console.log(`SendBitrate: ${sessionStats.SendBitrate}`)
    console.log(`SendBytes: ${sessionStats.SendBytes}`)
    console.log(`UserCount: ${sessionStats.UserCount}`)
    

    Returns Promise<any>

getSystemStats

  • getSystemStats(): Promise<any>
  • 获取系统电量信息。

    note

    注意事项

    • 仅在chrome内核的浏览器上支持。
    example
    // 系统电量信息
    let systemStats = await rtc.client.getSystemStats()
    

    Returns Promise<any>

getTransportStats

  • getTransportStats(): Promise<any>
  • 获取与网关的连接状况统计数据。

    note

    注意事项

    • 仅在chrome内核的浏览器上支持。
    example
    setInterval(async () => {
      const transportStats = await rtc.client.getTransportStats();
      if (transportStats){
        // 云信SDK到云信SDK接入节点的平均往返延时(RTT,Round-Trip Time),单位 ms
        console.log(`Current Transport txRtt: ${transportStats.txRtt}`);
        // 网络类型
        console.log(`Current Network Type: ${transportStats.NetworkType}`);
        // 上行可用带宽估计(Kbps)
        console.log(`Current Transport OutgoingAvailableBandwidth: ${transportStats.OutgoingAvailableBandwidth}`);
      }
    }, 1000)
    

    Returns Promise<any>

getUid

  • getUid(): null | string | number
  • 获取本地用户 ID。

    如果在 join 方法中指定了 uid,此处会返回指定的 ID; 如果未指定 uid,此处将返回云信服务器自动分配的 ID。

    since

    V4.4.0

    example
    let uid = client.getUid()
    

    Returns null | string | number

join

  • join(options: JoinOptions): Promise<any>
  • 加入房间。

    加入房间时,如果指定房间尚未创建,云信服务器内部会自动创建一个同名房间。

    调用该方法加入房间时,本地会触发 Client.on("connection-state-change") 回调;通信场景下的用户和直播场景下的主播角色加入房间后,远端会触发 Client.on("peer-online") 回调。

    example
    // 加入房间
    await client.join({
      channelName: 'channel163',
      uid: 123,
      token: '<您的token>', // 如关闭了安全模式,则不需要该参数。
    });
    

    Parameters

    Returns Promise<any>

    错误码包括:

    错误码(code) 错误原因(reason) 说明
    403 netcall.g2 unsafe mode is closed, please contact business! 安全模式下未设置 Token。请通过服务端 getToken 接口获取 NERTC Token,并在加入房间时传入。如果您仍处于测试阶段,可以在控制台切换应用为调试模式,调试模式下加入房间时无需设置 Token。
    414 check checksum error 鉴权失败。通常原因为加入房间时设置的 Token 错误。

leave

  • leave(): Promise<void>
  • 离开房间。

    调用该方法离开房间时,本地会触发 Client.on("connection-state-change") 回调;通信场景下的用户和直播场景下的主播角色离开房间后,远端会触发 Client.on("peer-leave") 回调。

    example
    // 离开房间
    await client.leave()
    

    Returns Promise<void>

off

  • off(event: string, callback: any): void
  • 该回调可以取消监听事件。

    Parameters

    • event: string
    • callback: any

    Returns void

on

  • on(event: "client-role-changed", callback: (evt: { role: "host" | "audience" }) => void): void
  • client-role-changed 回调表示本地用户的角色已改变。

    直播场景下,当用户角色切换时会触发此回调,即主播切换为观众,或观众切换为主播时。

    Parameters

    • event: "client-role-changed"
    • callback: (evt: { role: "host" | "audience" }) => void
        • (evt: { role: "host" | "audience" }): void
        • Parameters

          • evt: { role: "host" | "audience" }
            • role: "host" | "audience"

              改变后的角色。

          Returns void

    Returns void

  • on(event: "stream-added", callback: (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }) => void): void
  • stream-added 回调表示远端用户发布了音视频流。

    • 通常收到该事件后需要订阅音视频,即调用 Stream.setSubscribeConfigClient.subscribe
    • 该事件会为每一个音频或视频单独触发一次。evt.mediaType标识了具体的媒体类型。
    • 与该事件相反的事件为 Client.on("stream-removed")
    • 更完整的例子见NERTC.createClient
    example
    rtc.client.on("stream-added", (evt)=>{
      console.log(`远端${evt.stream.getId()}发布了 ${evt.mediaType} 流`)
      rtc.client.subscribe(evt.stream)
    });
    

    Parameters

    • event: "stream-added"
    • callback: (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }) => void
        • (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }): void
        • Parameters

          • evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }
            • mediaType: "video" | "screen" | "audio" | "audioSlave"

              远端流新增的媒体类型

            • stream: Stream

              新增的远端流。

          Returns void

    Returns void

  • on(event: "stream-subscribed", callback: (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }) => void): void
  • stream-subscribed 回调表示应用已接收远端音视频流。

    example
       rtc.client.on("stream-subscribed", (evt)=>{
           evt.stream.play(document.getElementById("remote-video-wrapper", {
             audio: true,
             video: true,
             screen: true,
           });
           evt.stream.setRemoteRenderMode({
             width: 200,
             height: 200
             cut: false
           });
       })
    

    Parameters

    • event: "stream-subscribed"
    • callback: (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }) => void
        • (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }): void
        • Parameters

          • evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }
            • mediaType: "video" | "screen" | "audio" | "audioSlave"

              音视频轨道类型。

            • stream: Stream

              已接收的远端流。

          Returns void

    Returns void

  • on(event: "stream-removed", callback: (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }) => void): void
  • stream-removed 回调表示应用已删除远端音视频流。

    远端用户调用 Client.unpublish 方法之后,会触发此回调。

    注意:

    • 该事件会为远端音频和视频分别触发一次。
    • 如需确认远端离开,可参考 peer-leave 事件。
    • 收到stream-removed时,如果调用不带参数的evt.stream.stop(),会同时关闭音视频渲染。这通常不是预期行为。
    example
    rtc.client.on("stream-removed", (evt)=>{
      // 远端流停止,则关闭渲染
      evt.stream.stop(evt.mediaType);
    });
    

    Parameters

    • event: "stream-removed"
    • callback: (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }) => void
        • (evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }): void
        • Parameters

          • evt: { mediaType: "video" | "screen" | "audio" | "audioSlave"; stream: Stream }
            • mediaType: "video" | "screen" | "audio" | "audioSlave"

              远端流被关闭的媒体类型

            • stream: Stream

              远端流。

          Returns void

    Returns void

  • on(event: "active-speaker", callback: (evt: { uid: string | number }) => void): void
  • active-speaker 事件会返回当前房间内音量最大的用户的 uid(iOS 微信浏览器暂不支持该事件)。

    Parameters

    • event: "active-speaker"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              音量最大的用户的 uid。

          Returns void

    Returns void

  • on(event: "volume-indicator", callback: (userList: { level: number; type: "audio" | "audioSlave"; uid: string | number }[]) => void): void
  • volume-indicator 事件会返回当前房间内除自己以外的用户的音量(iOS 微信浏览器暂不支持该事件)。

    example
    rtc.client.on("volume-indicator", (userList)=>{
      // 远端流停止,则关闭渲染
      userList.forEach((user)=>{
        console.log(`用户 ${user.uid} 音量 ${user.level}`)
      })
    });
    

    Parameters

    • event: "volume-indicator"
    • callback: (userList: { level: number; type: "audio" | "audioSlave"; uid: string | number }[]) => void
        • (userList: { level: number; type: "audio" | "audioSlave"; uid: string | number }[]): void
        • Parameters

          • userList: { level: number; type: "audio" | "audioSlave"; uid: string | number }[]

          Returns void

    Returns void

  • on(event: "peer-online", callback: (evt: { uid: string | number }) => void): void
  • peer-online 事件表示有远端用户或主播加入房间。

    • 通信场景中,该回调提示有远端用户加入了房间,并返回新加入房间的用户 ID。
    • 直播场景中,该回调提示有主播角色加入了房间,并返回该主播的用户 ID。

    以下场景中会触发该回调:

    • 通信场景中,远端用户或直播场景的远端主播角色调用了 Client.join 方法加入房间。
    • 直播场景中,远端观众加入房间后调用 Client.setClientRole 将用户角色改变为主播。
    • 通信场景中,远端用户或直播场景的远端主播网络中断后重新加入房间。

    Parameters

    • event: "peer-online"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户或主播角色的用户 ID。

          Returns void

    Returns void

  • on(event: "peer-leave", callback: (evt: { reason: PEER_LEAVE_REASON_CODE; uid: string | number }) => void): void
  • peer-leave 事件表示远端用户或主播角色离开房间。

    以下场景中会触发该回调:

    • 远端用户离开房间。
    • 用户角色从主播变为观众。
    • 本端进行重连时。(加入房间前调用 NERTC.getParameters().peerLeaveEventOnReconnect = false 可以阻止该事件触发)
    note

    在直播场景中,只有角色为主播的用户会触发该回调。

    Parameters

    Returns void

  • on(event: "mute-audio", callback: (evt: { uid: string | number }) => void): void
  • mute-audio 事件表示远端用户静音其音频,即关掉自己的声音。

    Parameters

    • event: "mute-audio"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "unmute-audio", callback: (evt: { uid: string | number }) => void): void
  • unmute-audio 事件表示远端用户取消静音,即打开自己的声音。

    Parameters

    • event: "unmute-audio"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "mute-audio-slave", callback: (evt: { uid: string | number }) => void): void
  • unmute-audio-slave 事件表示远端用户静音其音频辅流,即关掉自己的系统共享的声音。

    Parameters

    • event: "mute-audio-slave"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "unmute-audio-slave", callback: (evt: { uid: string | number }) => void): void
  • unmute-audio 事件表示远端用户取消静音音频辅流,即打开自己的系统共享的声音。

    Parameters

    • event: "unmute-audio-slave"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "mute-video", callback: (evt: { uid: string | number }) => void): void
  • mute-video 事件表示远端用户在视频通话中关掉自己的视频。

    Parameters

    • event: "mute-video"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "unmute-video", callback: (evt: { uid: string | number }) => void): void
  • unmute-video 事件表示远端用户在视频通话中打开自己的视频。

    Parameters

    • event: "unmute-video"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "mute-screen", callback: (evt: { uid: string | number }) => void): void
  • mute-screen 事件表示远端用户暂停屏幕共享。

    Parameters

    • event: "mute-screen"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "unmute-screen", callback: (evt: { uid: string | number }) => void): void
  • unmute-screen 事件表示远端用户继续屏幕共享。

    Parameters

    • event: "unmute-screen"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "uid-duplicate", callback: () => void): void
  • uid-duplicate 事件表示当前有人使用相同的uid加入了房间,你被提出了。

    Parameters

    • event: "uid-duplicate"
    • callback: () => void
        • (): void
        • Returns void

    Returns void

  • on(event: "client-banned", callback: (evt: { uid: string | number }) => void): void
  • client-banned 事件表示本地用户被踢出房间。

    note

    仅被踢出房间的用户会收到此回调。

    Parameters

    • event: "client-banned"
    • callback: (evt: { uid: string | number }) => void
        • (evt: { uid: string | number }): void
        • Parameters

          • evt: { uid: string | number }
            • uid: string | number

              远端用户 ID。

          Returns void

    Returns void

  • on(event: "channel-closed", callback: () => void): void
  • channel-closed 事件表示房间已关闭。

    Parameters

    • event: "channel-closed"
    • callback: () => void
        • (): void
        • Returns void

    Returns void

  • on(event: "stopScreenSharing", callback: (evt: {}) => void): void
  • stopScreenSharing 表示本地用户停止屏幕共享。这通常是在屏幕共享浮窗上点击关闭触发的。

    Parameters

    • event: "stopScreenSharing"
    • callback: (evt: {}) => void
        • (evt: {}): void
        • Parameters

          • evt: {}

          Returns void

    Returns void

  • on(event: "stopScreenAudio", callback: (evt: {}) => void): void
  • stopScreenAudio事件表示本地用户停止屏幕共享音频。这通常是在屏幕共享浮窗上点击关闭触发的。

    Parameters

    • event: "stopScreenAudio"
    • callback: (evt: {}) => void
        • (evt: {}): void
        • Parameters

          • evt: {}

          Returns void

    Returns void

  • on(event: "connection-state-change", callback: (evt: { curState: ConnectionState; prevState: ConnectionState; reconnect: boolean }) => void): void
  • connection-state-change事件表示 SDK 与服务器的连接状态发生了变化。

    example

    示例代码

    rtc.client.on('connection-state-change', (evt)=>{
      console.log(`connection-state-change ${evt.prevState} => ${evt.curState}。是否重连:${evt.reconnect}`)
    })
    

    Parameters

    Returns void

  • on(event: "error", callback: (type: string) => void): void
  • 客户端遇到错误。错误类型包括:

    • SOCKET_ERROR: 与服务器断开连接,请检查用户网络。
    • RELOGIN_ERROR: 网络重连登录失败,请联系云信技术支持。
    • MEDIA_TRANSPORT_DISCONNECT: 媒体通道一直连接失败,请检查用户网络。
    • AUDIOLEVEL_NOT_SUPPORTED:该浏览器环境不支持音频前处理模块,不能使用伴音、音效、getAudioLevel()、AI音效(原AI降噪)、啸叫检测等功能。
    • no-publish-audio-permission:高级权限token限制您发布自己的音频主流(麦克风)
    • no-publish-audio-slave-permission:高级权限token限制您发布自己的音频辅流(即屏幕共享系统声卡声音)
    • no-publish-video-permission:高级权限token限制您发布自己的视频主流(摄像头)
    • no-publish-screen-permission:高级权限token限制您发布自己的视频辅流(屏幕共享)
    • no-subscribe-audio-permission:高级权限token限制您订阅其他人的音频主流(麦克风)
    • no-subscribe-audio-slave-permission:高级权限token限制您发布订阅其他人的音频辅流(即屏幕共享系统声卡声音)
    • no-subscribe-video-permission:高级权限token限制您发布订阅其他人的视频主流(摄像头)
    • no-subscribe-screen-permission:高级权限token限制您发布订阅其他人的视频辅流(屏幕共享)
    • @example 示例代码
      rtc.client.on('error', (type) => {
      console.error('===== 发生错误事件:', type)
      if (type === 'SOCKET_ERROR') {
      addLog('==== 网络异常,已经退出房间')
      } else if (type === 'no-publish-audio-permission') {
      console.error('permkey控制,没有发布音频的权限')
      } else if (type === 'no-publish-audio-slave-permission') {
      console.error('permkey控制,没有发布音频辅流的权限')
      } else if (type === 'no-publish-video-permission') {
      addLog(`permkey控制,没有发布视频的权限`)
      } else if (type === 'no-publish-screen-permission') {
      console.error('permkey控制,没有发布屏幕共享的权限')
      } else if (type === 'no-subscribe-audio-permission') {
      console.error('permkey控制,没有订阅音频的权限')
      } else if (type === 'no-subscribe-audio-slave-permission') {
      console.error('permkey控制,没有订阅音频辅流的权限')
      } else if (type === 'no-subscribe-video-permission') {
      console.error('permkey控制,没有订阅视频的权限')
      } else if (type === 'no-subscribe-screen-permission') {
      console.error('permkey控制,没有订阅屏幕共享的权限')
      }
      })
      

    Parameters

    • event: "error"
    • callback: (type: string) => void
        • (type: string): void
        • Parameters

          • type: string

          Returns void

    Returns void

  • on(event: "warning", callback: (evt: { code: number; reason: string }) => void): void
  • 客户端遇到警告。可能有:

    • 406:ability not support。当前客户端设备视频编解码能力与房间不匹配,例如设备不支持 VP8 等编码类型。在此房间中可能无法成功进行视频编解码,即本端可能无法正常显示某些远端的视频画面,同样远端也可能无法显示本端画面。

    Parameters

    • event: "warning"
    • callback: (evt: { code: number; reason: string }) => void
        • (evt: { code: number; reason: string }): void
        • Parameters

          • evt: { code: number; reason: string }
            • code: number

              警告码。

            • reason: string

              原因。

          Returns void

    Returns void

  • on(event: "custom-data"): void
  • permkey-will-expire 事件表示房间中有人在join()的时候设置了自定义消息。

    example
    rtc.client.on("custom-data", async evt=>{
      console.warn(`${evt.uid} 发送自定义消息 ${evt.customData}`)
    })
    

    Parameters

    • event: "custom-data"

    Returns void

  • on(event: "permkey-will-expire"): void
  • permkey-will-expire 事件表示高级权限token功能启用后,permkey还有30s就要超时了,需要主动调用updatePermkey()去更新。

    example
    rtc.client.on("permkey-will-expire", async evt=>{
      console.warn(`permKey 即将过期}`)
      const newpermKey = await getPermkey() //自己业务层实现该功能
      rtc.client.updatePermKey(newpermKey).catch((err) => {
        console.error('刷新permKey错误: ', err.message)
      })
    })
    

    Parameters

    • event: "permkey-will-expire"

    Returns void

  • on(event: "permkey-timeout"): void
  • permkey-timeout 事件表示高级权限token功能启用后,permkey已经超时,您被提出房间了。

    Parameters

    • event: "permkey-timeout"

    Returns void

  • on(event: "audioTrackEnded"): void
  • audioTrackEnded 事件表示音频轨道结束。造成的原因可能是设备被拔出。

    Parameters

    • event: "audioTrackEnded"

    Returns void

  • on(event: "audioTrackEnded"): void
  • audioTrackEnded 事件表示音频轨道结束。造成的原因可能是设备被拔出。

    Parameters

    • event: "audioTrackEnded"

    Returns void

  • on(event: "videoTrackEnded"): void
  • videoTrackEnded 事件表示视频频轨道结束。造成的原因可能是设备被拔出。

    Parameters

    • event: "videoTrackEnded"

    Returns void

  • on(event: "TrackEnded", callback: (mediaType: "video" | "screen" | "audio" | "screenAudio") => void): void
  • TrackEnded 事件表示音视频轨道结束。造成的原因可能是设备被拔出。

    Parameters

    • event: "TrackEnded"
    • callback: (mediaType: "video" | "screen" | "audio" | "screenAudio") => void
        • (mediaType: "video" | "screen" | "audio" | "screenAudio"): void
        • Parameters

          • mediaType: "video" | "screen" | "audio" | "screenAudio"

          Returns void

    Returns void

  • on(event: "TrackMuted", callback: (mediaType: "video" | "screen" | "audio" | "screenAudio") => void): void
  • TrackMuted 事件表示音视频轨道处于Muted状态。造成的原因可能是设备被占用。

    Parameters

    • event: "TrackMuted"
    • callback: (mediaType: "video" | "screen" | "audio" | "screenAudio") => void
        • (mediaType: "video" | "screen" | "audio" | "screenAudio"): void
        • Parameters

          • mediaType: "video" | "screen" | "audio" | "screenAudio"

          Returns void

    Returns void

  • on(event: "local-track-state", callback: (trackStats: { audio: { muted: undefined | boolean }; screen: { muted: undefined | boolean }; screenAudio: { muted: undefined | boolean }; video: { muted: undefined | boolean } }) => void): void
  • 当页面从隐藏状态变为显示状态时,会触发此事件。此时track可能处于mute状态,需要重新打开设备。

    Parameters

    • event: "local-track-state"
    • callback: (trackStats: { audio: { muted: undefined | boolean }; screen: { muted: undefined | boolean }; screenAudio: { muted: undefined | boolean }; video: { muted: undefined | boolean } }) => void
        • (trackStats: { audio: { muted: undefined | boolean }; screen: { muted: undefined | boolean }; screenAudio: { muted: undefined | boolean }; video: { muted: undefined | boolean } }): void
        • Parameters

          • trackStats: { audio: { muted: undefined | boolean }; screen: { muted: undefined | boolean }; screenAudio: { muted: undefined | boolean }; video: { muted: undefined | boolean } }
            • audio: { muted: undefined | boolean }
              • muted: undefined | boolean
            • screen: { muted: undefined | boolean }
              • muted: undefined | boolean
            • screenAudio: { muted: undefined | boolean }
              • muted: undefined | boolean
            • video: { muted: undefined | boolean }
              • muted: undefined | boolean

          Returns void

    Returns void

  • on(event: "rtmp-state", callback: (state: RTMPTaskState) => void): void
  • rtmp-state 事件表示RTMP旁路推流状态发生了变化。

    Parameters

    Returns void

  • on(event: "network-quality", callback: (netStatus: NetStatusItem[]) => void): void
  • network-quality 事件展示房间中所有成员的上下行网络质量。

    Parameters

    Returns void

  • on(event: "exception", callback: (exceptionEvent: ClientExceptionEvt) => void): void
  • exception 事件展示了目前房间内的异常事件。

    异常事件不是错误,但是往往会引起通话质量问题。

    Parameters

    Returns void

  • on(event: "crypt-error", callback: (evt: { cryptType: EncryptionMode }) => void): void
  • crypt-error 回调表示本地设置的媒体流加密密钥与房间中其他成员不一致,加入房间失败。

    请通过 Client.setEncryptionSecret 重新设置加密密钥。

    Parameters

    Returns void

  • on(event: "accessDenied", callback: (mediaType: "video" | "screen" | "audio") => void): void
  • accessDenied 事件表示获取设备权限被拒绝。

    Parameters

    • event: "accessDenied"
    • callback: (mediaType: "video" | "screen" | "audio") => void
        • (mediaType: "video" | "screen" | "audio"): void
        • Parameters

          • mediaType: "video" | "screen" | "audio"

          Returns void

    Returns void

  • on(event: "notFound", callback: (mediaType: "video" | "audio") => void): void
  • notFound事件表示获取麦克风或摄像头权限时,无法找到指定设备。

    Parameters

    • event: "notFound"
    • callback: (mediaType: "video" | "audio") => void
        • (mediaType: "video" | "audio"): void
        • Parameters

          • mediaType: "video" | "audio"

          Returns void

    Returns void

  • on(event: "deviceError", callback: (mediaType: "video" | "audio") => void): void
  • deviceError事件表示获取麦克风或摄像头权限时,遭遇未知错误错误。

    Parameters

    • event: "deviceError"
    • callback: (mediaType: "video" | "audio") => void
        • (mediaType: "video" | "audio"): void
        • Parameters

          • mediaType: "video" | "audio"

          Returns void

    Returns void

  • on(event: "beOccupied", callback: (mediaType: "video" | "audio") => void): void
  • beOccupied事件表示获取麦克风或摄像头权限时,设备被占用。

    Parameters

    • event: "beOccupied"
    • callback: (mediaType: "video" | "audio") => void
        • (mediaType: "video" | "audio"): void
        • Parameters

          • mediaType: "video" | "audio"

          Returns void

    Returns void

  • on(event: "audioVideoBanned", callback: (evt: { duration?: number; mediaType: "video" | "audio"; state: boolean; uid: number }) => void): void
  • audioVideoBanned 事件表示音频或视频被服务器禁言

    • state: true 表示被服务器禁言,false 表示服务器解禁
    • duration: 服务器禁言事件,单位为秒

    Parameters

    • event: "audioVideoBanned"
    • callback: (evt: { duration?: number; mediaType: "video" | "audio"; state: boolean; uid: number }) => void
        • (evt: { duration?: number; mediaType: "video" | "audio"; state: boolean; uid: number }): void
        • Parameters

          • evt: { duration?: number; mediaType: "video" | "audio"; state: boolean; uid: number }
            • Optional duration?: number
            • mediaType: "video" | "audio"
            • state: boolean
            • uid: number

          Returns void

    Returns void

  • on(event: "recording-device-changed", callback: (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }) => void): void
  • recording-device-changed 回调通知应用有音频输入设备被添加、更改或移除。

    • ACTIVE: 新增设备
    • INACTIVE: 设备被移除
    • CHANGED: 设备更改

    注意:

    1. 在Chrome浏览器上,部分蓝牙设备关闭后,Chrome会将默认输入设备切换为其他麦克风,此时可能遇到声音异常,需重启设备。
    2. Firefox不支持设备检测
    example
    rtc.client.on("recording-device-changed", async evt=>{
      console.log("麦克风设备变更", evt.state, evt.device.label);
      if (evt.state === "CHANGED" && evt.device.deviceId === "default"){
        console.error("默认麦克风自动切换,如遇到声音异常,需重启设备", evt.device.label);
        // await rtc.localStream.close({type: "audio"})
        // await rtc.localStream.open({type: "audio"})
      }
    })
    

    Parameters

    • event: "recording-device-changed"
    • callback: (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }) => void
        • (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }): void
        • Parameters

          • evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }
            • device: DeviceInfo
            • state: "ACTIVE" | "INACTIVE" | "CHANGED"

          Returns void

    Returns void

  • on(event: "camera-changed", callback: (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }) => void): void
  • camera-changed 回调通知应用有视频输入设备被添加、更改或移除。

    • ACTIVE: 新增设备
    • INACTIVE: 设备被移除
    • CHANGED: 设备更改

    注:Firefox不支持设备检测

    Parameters

    • event: "camera-changed"
    • callback: (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }) => void
        • (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }): void
        • Parameters

          • evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }
            • device: DeviceInfo
            • state: "ACTIVE" | "INACTIVE" | "CHANGED"

          Returns void

    Returns void

  • on(event: "playout-device-changed", callback: (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }) => void): void
  • playout-device-change 回调通知应用有音频输出设备被添加、更改或移除。

    • ACTIVE: 新增设备
    • INACTIVE: 设备被移除
    • CHANGED: 设备更改

    注意:目前仅Chrome浏览器支持扬声器枚举与选择。

    Parameters

    • event: "playout-device-changed"
    • callback: (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }) => void
        • (evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }): void
        • Parameters

          • evt: { device: DeviceInfo; state: "ACTIVE" | "INACTIVE" | "CHANGED" }
            • device: DeviceInfo
            • state: "ACTIVE" | "INACTIVE" | "CHANGED"

          Returns void

    Returns void

  • on(event: "track-low-init-success", callback: (evt: { mediaType: "video" | "screen" }) => void): void
  • track-low-init-success 回调通知小流创建成功

    Parameters

    • event: "track-low-init-success"
    • callback: (evt: { mediaType: "video" | "screen" }) => void
        • (evt: { mediaType: "video" | "screen" }): void
        • Parameters

          • evt: { mediaType: "video" | "screen" }
            • mediaType: "video" | "screen"

          Returns void

    Returns void

  • on(event: "track-low-init-fail", callback: (evt: { mediaType: "video" | "screen" }) => void): void
  • track-low-init-fail 回调通知小流创建失败

    Parameters

    • event: "track-low-init-fail"
    • callback: (evt: { mediaType: "video" | "screen" }) => void
        • (evt: { mediaType: "video" | "screen" }): void
        • Parameters

          • evt: { mediaType: "video" | "screen" }
            • mediaType: "video" | "screen"

          Returns void

    Returns void

  • on(event: "sender-transform", callback: (evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio" }) => void): void
  • sender-transform 回调用于自定义加密,回调编码后的帧

    Parameters

    • event: "sender-transform"
    • callback: (evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio" }) => void
        • (evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio" }): void
        • Parameters

          • evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio" }
            • encodedFrame: any
            • mediaType: "video" | "screen" | "audio"

          Returns void

    Returns void

  • on(event: "receiver-transform", callback: (evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio"; uid: number }) => void): void
  • receiver-transform 回调用于自定义加密,回调解码前的帧

    Parameters

    • event: "receiver-transform"
    • callback: (evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio"; uid: number }) => void
        • (evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio"; uid: number }): void
        • Parameters

          • evt: { encodedFrame: any; mediaType: "video" | "screen" | "audio"; uid: number }
            • encodedFrame: any
            • mediaType: "video" | "screen" | "audio"
            • uid: number

          Returns void

    Returns void

  • on(event: "asr-captions", callback: (result: AsrCaption[]) => void): void
  • asr-captions 回调实时字幕识别结果

    Parameters

    Returns void

  • on(event: "device-open-fail", callback: (constraint: { video: GUMVideoConstraints }) => void): void
  • device-open-fail 摄像头打开失败,当触发该事件时,会使用默认参数{video: true}尝试重新打开摄像头。

    Parameters

    Returns void

  • on(event: "displaySurfaceError", callback: () => void): void
  • displaySurfaceError 屏幕共享选择的区域不合法。(加入房间前修改 NERTC.getParameters().forceDisplaySurface 以选择屏幕共享区域。当触发该事件时,会自动关闭屏幕共享) forceDisplaySurface: 'default' | 'browser' | 'window' | 'monitor', 默认为'default'

    Parameters

    • event: "displaySurfaceError"
    • callback: () => void
        • (): void
        • Returns void

    Returns void

  • on(event: "displaySurfaceUnknown", callback: (value: string) => void): void
  • displaySurfaceUnknown 屏幕共享选择的区域未知。(加入房间前修改 NERTC.getParameters().forceDisplaySurface 以选择屏幕共享区域.当无法判断用户选择的屏幕共享区域时,会触发该事件,可通过该事件回调主动关闭屏幕共享) forceDisplaySurface: 'default' | 'browser' | 'window' | 'monitor', 默认为'default'

    Parameters

    • event: "displaySurfaceUnknown"
    • callback: (value: string) => void
        • (value: string): void
        • Parameters

          • value: string

          Returns void

    Returns void

publish

  • publish(stream: Stream): Promise<undefined>
  • 发布本地音视频流。

    发布音视频流之后,远端会触发 Client.on("stream-added") 回调。

    example
    // 1. 创建本地音视频流
    localStream = NERTC.createStream({
      video: true,
      audio: true,
      uid: 123
    });
    await localStream.init();
    // 2. 发布本地音视频流
    await client.publish(localStream)
    

    Parameters

    • stream: Stream

      需要发布的 Stream。

    Returns Promise<undefined>

setChannelProfile

  • setChannelProfile(options: { mode: "rtc" | "live" }): void
  • 设置房间场景。

    房间场景可设置为通话或直播场景,不同的场景中 QoS 策略不同。

    note

    该方法必须在加入房间前调用,进入房间后无法再设置房间场景。

    example
    // 设置为通信场景
    client.setChannelProfile({ mode: 'rtc' })
    

    Parameters

    • options: { mode: "rtc" | "live" }
      • mode: "rtc" | "live"

        房间场景。

        可设置为:

        • rtc:(默认)通信场景。该场景下,房间内所有用户都可以发布和接收音、视频流。适用于语音通话、视频群聊等应用场景。
        • live:直播场景。该场景有主播和观众两种用户角色,可以通过 setClientRole 设置。主播可以发布和接收音视频流,观众直接接收流。适用于语聊房、视频直播、互动大班课等应用场景。

    Returns void

setClientRole

  • setClientRole(role: "host" | "audience"): Promise<undefined>
  • 设置用户角色。默认情况下用户以主播角色加入房间。

    在加入房间前,用户可以调用本接口设置本端模式为观众或主播模式。在加入房间后,用户可以通过本接口切换用户模式。

    用户角色支持设置为主播(host)或观众(audience),主播和观众的权限不同:

    • 主播:可以操作摄像头等音视频设备、发布流、配置互动直播推流任务、上下线对房间内其他用户可见。
    • 观众:观众只能接收音视频流,不支持操作音视频设备、配置互动直播推流任务、上下线不通知其他用户。
    note

    可以在加入房间之前或者之后设置。

    相关回调:

    如果您在加入房间后调用该方法切换用户角色,调用成功后,会触发以下回调:

    • 主播切换为观众,本地触发 Client.on(client-role-changed) 回调,远端触发 Client.on(peer-leave) 回调。
    • 观众切换为主播,本地触发 Client.on(client-role-changed) 回调,远端触发 Client.on(peer-online) 回调。
    example
    // 设置为主播
    await client.setClientRole('host')
    

    Parameters

    • role: "host" | "audience"

      用户角色。可设置为:

      • host:直播模式中的主播,可以发布和接收音视频流。如果用户之前已经发布了音频或视频,切换到主播时会自动恢复发布音频或视频流。
      • audience: 直播模式中的观众,只能接收音视频流。主播模式切换到观众模式后,会自动停止发送音视频流。

      注意:

      • 用户从观众切换为主播时可能会因房间主播人数到达上限而失败。如需了解如何增加主播上限,请联系技术支持。

    Returns Promise<undefined>

setCodecType

  • setCodecType(type?: "VP8" | "H264"): void
  • 指定编解码类型

    Parameters

    • Optional type: "VP8" | "H264"

      'VP8' | 'H264',可不填,不填写时根据房间能力自动选择编解码类型

    Returns void

setEncryptionMode

  • setEncryptionMode(encryptionMode: EncryptionMode): void
  • 设置媒体流加密模式。

    在金融行业等安全性要求较高的场景下,您可以在加入房间前通过此方法设置媒体流加密模式。

    • 该方法和 Client.setEncryptionSecret 搭配使用,必须在加入房间前先调用 Client.setEncryptionMode 设置媒体流加密方案,再调用 Client.setEncryptionSecret 设置密钥。如果未指定密钥,则无法启用媒体流加密。
    • 用户离开房间后,SDK 会自动关闭加密。如需重新开启加密,需要在用户再次加入房间前调用这两个方法。
    since

    V4.4.0

    note
    • 请在加入房间前调用该方法,加入房间后无法修改加密模式与密钥。
    • 安全起见,建议每次启用媒体流加密时都更换新的密钥。
    • 同一房间内,所有开启媒体流加密的用户必须使用相同的加密模式和密钥,否则使用不同密钥的成员加入房间时会触发 Client.on("crypt-error") 回调。
    example
      // 例如,使用 sm4-128-ecb
      client.setEncryptionMode('sm4-128-ecb');
      client.setEncryptionSecret('abcdefghijklmnop');
      // 然后通过client.join()加入房间
    

    Parameters

    • encryptionMode: EncryptionMode

      媒体流加密方案。详细信息请参考 encryptionMode。

    Returns void

setEncryptionSecret

  • setEncryptionSecret(encryptionSecret: string): void
  • 设置媒体流加密密钥。

    • 该方法和 Client.setEncryptionMode 搭配使用,必须在加入房间前先调用 Client.setEncryptionMode 设置媒体流加密方案,再调用 Client.setEncryptionSecret 设置密钥。如果未指定密钥,则无法启用媒体流加密。
    • 用户离开房间后,SDK 会自动关闭加密。如需重新开启加密,需要在用户再次加入房间前调用这两个方法。
    since

    V4.4.0

    note
    • 请在加入房间前调用该方法,加入房间后无法修改加密模式与密钥。
    • 安全起见,建议每次启用媒体流加密时都更换新的密钥。
    • 同一房间内,所有开启媒体流加密的用户必须使用相同的加密模式和密钥,否则使用不同密钥的成员加入房间时会触发 Client.on("crypt-error") 回调。
    example
    // 例如,使用 sm4-128-ecb
    client.setEncryptionMode('sm4-128-ecb');
    client.setEncryptionSecret('abcdefghijklmnop');
    // 然后通过client.join()加入房间
    

    Parameters

    • encryptionSecret: string

      媒体流加密密钥。字符串格式,长度为 1~128 字节。推荐设置为英文字符串。

    Returns void

setLocalMediaPriority

  • setLocalMediaPriority(options: MediaPriorityOptions): void
  • 设置本地用户的媒体流优先级。

    如果某个用户的优先级为高,那么该用户媒体流的优先级就会高于其他用户,弱网环境下 SDK 会优先保证其他用户收到的、高优先级用户的媒体流的质量。

    note
    • 请在加入房间(join)前调用此方法。
    • 一个音视频房间中只有一个高优先级的用户。建议房间中只有一位用户调用 setLocalMediaPriority 将本端媒体流设为高优先级,否则需要开启抢占模式,保证本地用户的高优先级设置生效。
    example
    client.setLocalMediaPriority({
       priority: 50,
       preemtiveMode: true
     })
    

    Parameters

    Returns void

setPlaybackVolume

  • setPlaybackVolume(volume: number): void
  • 设置整个频道的远端用户的播放音量。

    • 该接口与Stream.setAudioVolume类似:两者都改变播放音量。setPlaybackVolume对频道内所有流生效,setAudioVolume对某个远端流生效。
    • volume 取值范围: [0, 100]
    • active-speaker以及'volume-indicator'事件回调会受该接口的影响。特别的,当使用setPlaybackVolume将音量设置为0时,active-speakervolume-indicator不再有回调。
    • Stream.getAudioLevel不受该接口影响。
    • 由于系统限制,iOS设备不支持调节播放音量,包括微信、Safari等。可使用侧边物理按键调节音量。
    example
    // 设置整个频道的远端用户的播放音量为 50
    client.setPlaybackVolume(50)
    

    Parameters

    • volume: number

    Returns void

setRemoteStreamType

  • setRemoteStreamType(stream: Stream, highOrLow: STREAM_TYPE, mediaType: "video" | "screen"): Promise<void>
  • 动态切换视频大小流。

    如果发送端开启了双流模式,即大小流模式,订阅端默认接收大流,您也可以在订阅端调用此方法选择接收大流还是小流。

    note

    注意事项

    • 该方法是在处于订阅状态时改变订阅的大小流类型时使用的。如您需要指定订阅那一刻的大小流类型,请参考Stream.setSubscribeConfig
    example
    // 在订阅状态下,想将屏幕共享的大流切换为小流。
    rtc.client.setRemoteStreamType(remoteStream, NERTC.STREAM_TYPE.LOW, "screen")
    

    Parameters

    • stream: Stream

      指定音视频流。

    • highOrLow: STREAM_TYPE

      指定大小流类型。可以使用NERTC.STREAM_TYPE.HIGHNERTC.STREAM_TYPE.LOW 指定

    • mediaType: "video" | "screen"

      媒体类型。主流为"video",辅流为"screen"

    Returns Promise<void>

setRemoteVideoStreamType

  • setRemoteVideoStreamType(stream: Stream, highOrLow: STREAM_TYPE): Promise<void>
  • 动态切换视频大小流。可参见Client.setRemoteStreamType方法。

    note

    注意事项

    example
    // 在订阅状态下,想将视频的大流切换为小流。
    rtc.client.setRemoteVideoStreamType(remoteStream, NERTC.STREAM_TYPE.LOW)
    

    Parameters

    • stream: Stream

      指定音视频流。

    • highOrLow: STREAM_TYPE

      指定大小流类型。可以使用NERTC.STREAM_TYPE.HIGHNERTC.STREAM_TYPE.LOW 指定

    Returns Promise<void>

startAsrCaptions

  • startAsrCaptions(): boolean
  • 开启实时字幕 需要在加入频道后调用client.startAsrCaptions()方法。调用后,可收到asr-captions事件。

    example
    // 1.创建client
    client = NERTC.createClient({appkey: "<您的appkey>", debug: true});
    // 2. 加入频道
    await client.join({
      channelName: 'channel163',
      uid: 123,
      token: '<您的token>', // 如关闭了安全模式,则不需要该参数。
    });
    // 3.监听 asr-captions 事件,实现实时字幕展示
    rtc.client.on('asr-captions', (result) => {})
    // 开启实时字幕
    client.startAsrCaptions()
    

    Returns boolean

startMediaRecording

  • startMediaRecording(options: ClientMediaRecordingOptions): Promise<undefined>
  • 客户端录制功能。

    允许用户在浏览器上实现本地录制音视频的功能。

    since

    V4.6.10

    note

    注意事项

    • 需要在加入房间之后调用。
    • 不允许同时录制多个文件。
    • 仅在chrome内核的浏览器上支持。
    • 录制文件的下载地址为浏览器默认下载地址
    • 录制文件的格式是webm,并非所有的播放器都支持(chrome上是可以直接播放的),如果需要转格式,需要开发者自己完成
    • 录制模块没有做内存管理,如果录制的时间过长,到导致内存占用越来越大,需要开发者及时释放
    example
      // client.join()加入房间之后
      const data = {
         recorder: 'all',
         recordConfig: {
         recordType: 'video',
         recordName: '录制文件名称',
         recordVideoQuality: NERTC.RECORD_VIDEO_QUALITY_360p,
         recordVideoFrame: NERTC.RECORD_VIDEO_FRAME_RATE_15
       }
      }
      await client.startMediaRecording(data);
    

    Parameters

    Returns Promise<undefined>

startProxyServer

  • startProxyServer(): void
  • 开启云代理服务。
    在内网环境下,如果用户防火墙开启了网络限制,请参考《使用云代理》将指定 IP 地址和端口号加入防火墙白名单,然后调用此方法开启云代理。

    note

    注意

    • 请在加入房间(join)前调用此方法。
    • 如果需要关闭已设置的云代理,请在加入房间前调用 stopProxyServer
    example
    // 请在进房前开启云代理服务
    client.startProxyServer()
    

    Returns void

    错误码包括:

    错误码(code) 错误原因(reason)
    INVALID_OPERATION 非法操作,请在加入房间之前调用该接口。

stopAsrCaptions

  • stopAsrCaptions(): boolean
  • 关闭实时字幕 需要在开启实时字幕后调用client.stopAsrCaptions()方法。调用后,不再收到asr-captions事件。

    Returns boolean

stopMediaRecording

  • stopMediaRecording(): Promise<undefined>
  • 结束视频录制

    since

    V4.6.10

    example
     // await client.startMediaRecording() 开启录制之后
     await client.stopMediaRecording();
    

    Returns Promise<undefined>

stopProxyServer

  • stopProxyServer(): void
  • 关闭云代理服务。

    note

    请在加入房间(join)前调用此方法。

    example
    // 请在进房前关闭云代理服务
    client.stopProxyServer()
    

    Returns void

subscribe

  • subscribe(stream: Stream, subOptions?: SubscribeOptions): Promise<void>
  • 订阅远端音视频流。

    通常在 Client.on("stream-added")事件回调中处理远端媒体订阅。 订阅远端音视频流之后,本地会触发 Client.on("stream-subscribed") 事件。

    注意事项:

    • 从v4.6.50起,Client.subscribe可以直接指定订阅的媒体类型了
    example
    // 在stream-added里
    
    // 写法1:订阅所有媒体
    remoteStream.setSubscribeConfig({
       audio: true,
       video: true,
       screen: true,
       audioSlave: true,
       highOrLow: NERTC.STREAM_TYPE.HIGH
    })
    rtc.client.subscribe(remoteStream)
    
    // 写法2: 订阅所有媒体
    rtc.client.subscribe(remoteStream, {
       audio: true,
       video: true,
       screen: true,
       audioSlave: true,
       highOrLow: NERTC.STREAM_TYPE.HIGH
    })
    

    Parameters

    Returns Promise<void>

unpublish

  • unpublish(stream: Stream): Promise<undefined>
  • 停止将本地音视频流发布到本房间。

    停止发布音视频流之后,远端会触发 Client.on("stream-removed") 回调。

    example
    // 停止发布本地音视频流
    await client.unpublish(localStream)
    

    Parameters

    • stream: Stream

      需要取消发布的 Stream。

    Returns Promise<undefined>

unsubscribe

  • unsubscribe(stream: Stream, unsubscribeOptions?: UnsubscribeOptions): Promise<void>
  • 取消订阅远端音视频流。

    取消订阅后,SDK 将不再接收远端音视频流。

    注意事项:

    • 从4.6.50起,可以取消订阅部分媒体类型
    example
    // 情况1:当需取消订阅远端所有媒体
    rtc.client.unsubscribe(remoteStream)
    
    // 情况2:当前需取消订阅远端音频,保留远端视频
    rtc.client.unsubscribe(remoteStream, {audio: true})
    

    Parameters

    Returns Promise<void>

updatePermKey

  • updatePermKey(newpermKey: string): Promise<void>
  • 动态更新高级权限token。

    启动高级权限token功能之后,用户可以中途动态更新其权限,以及刷新token超时时间

    note

    注意事项

    • 该方法仅支持加入房间后调用
    example
    // 收到sdk反馈的高级token超时时间快要到的通知后,主动去刷新超时时间,或者中途更新本人的权限
    rtc.client.updatePermKey(newpermKey).catch((err) => {
      console.error('刷新permKey错误: ', err.code, err.message)
    })
    

    Parameters

    • newpermKey: string

      新生成的高级权限token。

    Returns Promise<void>

updateTasks

  • updateTasks(options: { rtmpTasks: RTMPTask[] }): Promise<void>
  • 更新房间推流任务。

    • 该方法仅适用直播场景。
    • 请在房间内调用该方法,该方法在通话中有效。
    example
    // 配置推流任务
    let rtmpTasks = [{
      taskId:'12345',
      streamUrl:'rtmp://xxxx',
      record:'true',
      layout:{
        canvas:{width:1280, height:720, color:16777215},
        users:[{adaption:1, uid:123, width:640, height:480, x:640, y:0, zOrder:2, pushAudio:true, pushVideo:true}]
      }
    }]
    // 更新房间推流任务
    client.updateTasks({
      rtmpTasks
    }).then((obj) => {
      console.info('更新推流任务成功...')
    }).catch(err => {
      console.error('更新推流任务失败: ', err)
    })
    

    Parameters

    • options: { rtmpTasks: RTMPTask[] }
      • rtmpTasks: RTMPTask[]

        推流任务信息。

    Returns Promise<void>