移动端特殊场景优化

更新时间: 2024/10/29 15:38:02

在移动端使用 RTC 时,面临着许多特殊场景,如锁屏,下拉通知栏,接听电话等场景。这些场景可能会导致音视频流产生异常,因此需要进行一定的处理。本文介绍了如何通过监听 RTC SDK 事件,处理各种异常场景。

前提条件

根据本文操作前,请确保您已经完成了以下设置:

实现步骤

  1. 创建 client 实例,参考 createClient

    JavaScript//创建 client 实例
    rtc.client = NERTC.createClient({
    appkey: '<yourAppKey>', //您的应用密钥(App Key)
    debug: true, //是否开启调试日志
    });
    
  2. 监听 TrackEnded 事件,当 track 异常关闭时,会触发该事件,此时可以关闭 track 对应的 mediaType,并重新开启。

    • TrackEndedvideoTrackEndedaudioTrackEndedstopScreenSharingstopScreenAudio 四个事件的聚合事件,当监听 TrackEnded 后,可以不再具体地监听四个事件。
    • mediaType 与四个事件的对应关系为:
      • video <--> videoTrackEnded
      • audio <--> audioTrackEnded
      • screen <--> stopScreenSharing
      • screenAudio <--> stopScreenAudio
    JavaScriptrtc.client.on('TrackEnded', async (mediaType) => {
        console.warn(`===== ${mediaType}轨道已停止, 尝试重新发布${mediaType}`)
        await rtc.localStream.close({
        type: mediaType
        })
        if (mediaType === 'video') {
        await rtc.localStream.open({ type: mediaType })
        //请注意,是否需要 play 视具体业务而定
        await rtc.localStream.play(localContainer, { video: true, screen: false })
        } else if (mediaType === 'screen') {
        await rtc.localStream.open({ type: mediaType })
        //请注意,是否需要 play 视具体业务而定
        await rtc.localStream.play(localContainer, { video: false, screen: true })
        } else if (mediaType === 'audio') {
        await rtc.localStream.open({ type: mediaType })
        } else if (mediaType === 'screenAudio') {
        await rtc.localStream.open({ type: 'screen', screenAudio: true })
        }
    })
    
  3. 监听 TrackMuted 事件,当无法采集到媒体数据时,会触发该事件,此时可以关闭 track 对应的 mediaType,并重新开启。

    JavaScriptrtc.client.on('TrackMuted', async (mediaType) => {
        console.warn(`===== ${mediaType}轨道已 Mute, 尝试重新发布${mediaType}`)
        await rtc.localStream.close({
        type: mediaType
        })
        if (mediaType === 'video') {
        await rtc.localStream.open({ type: mediaType })
        //请注意,是否需要 play 视具体业务而定
        await rtc.localStream.play(localContainer, { video: true, screen: false })
        } else if (mediaType === 'screen') {
        await rtc.localStream.open({ type: mediaType })
        //请注意,是否需要 play 视具体业务而定
        await rtc.localStream.play(localContainer, { video: false, screen: true })
        } else if (mediaType === 'audio') {
        await rtc.localStream.open({ type: mediaType })
        } else if (mediaType === 'screenAudio') {
        await rtc.localStream.open({ type: 'screen', screenAudio: true })
        }
    })
    
  4. 监听 local-track-state 事件。当页面从隐藏状态变成显示状态时,会通过该事件抛出每个 trackmute 状态(上一步的 TrackMuted 事件在某些特殊场景下无法触发,此时需要通过该事件处理)。通过判断每一个 track 的状态,当 muted 属性为 true 时,重新打开对应音视频流。

    JavaScriptrtc.client.on('local-track-state', async (trackStates) => {
        console.warn(`本地 track 状态:`, trackStates)
        for (let mediaType in trackStates) {
        const trackState = trackStates[mediaType]
        if (trackState.muted) {
            console.warn('尝试恢复播放', mediaType)
            if (mediaType === 'video') {
            await rtc.localStream.open({ type: mediaType })
            //请注意,是否需要 play 视具体业务而定
            await rtc.localStream.play(localContainer, { video: true, screen: false })
            } else if (mediaType === 'screen') {
            await rtc.localStream.open({ type: mediaType })
            //请注意,是否需要 play 视具体业务而定
            await rtc.localStream.play(localContainer, { video: false, screen: true })
            } else if (mediaType === 'audio') {
            await rtc.localStream.open({ type: mediaType })
            } else if (mediaType === 'screenAudio') {
            await rtc.localStream.open({ type: 'screen', screenAudio: true })
            }
        }
        }
    })
    }
    
此文档是否对你有帮助?
有帮助
去反馈
  • 前提条件
  • 实现步骤