rtc_analysis.md 3.1 KB

Aliyun RTC 推拉流实现分析

1. 主流程概述

graph TD
    A[初始化AliRtcEngine] --> B[生成Token]
    B --> C[加入频道]
    C --> D[设置本地预览]
    D --> E[监听远端用户事件]
    E --> F[处理订阅状态变化]
    F --> G[管理视频元素生命周期]

2. 核心组件说明

  • AliRtcEngine: 阿里云RTC核心引擎,负责音视频通信
    • 主要方法:
    • joinChannel(): 加入音视频频道
    • setLocalViewConfig(): 设置本地视频预览
    • setRemoteViewConfig(): 设置远端视频渲染
    • leaveChannel(): 离开频道
    • 重要枚举:
    • AliRtcSubscribeState: 订阅状态(1:未订阅, 3:已订阅)
    • AliRtcVideoTrack: 视频轨道类型(Camera/Screen)

3. 推流流程

  1. 本地预览设置:

    // 加入频道成功后设置本地预览
    aliRtcEngine.current!.setLocalViewConfig(
    'localPreviewer', 
    AliRtcVideoTrack.AliRtcVideoTrackCamera
    );
    
  2. 视频元素管理:

  3. 使用<video id="localPreviewer">元素显示本地摄像头画面

  4. 通过muted属性静音本地音频避免回声

4. 拉流订阅流程

状态机转换逻辑

stateDiagram-v2
    [*] --> 未订阅: 初始状态
    未订阅 --> 已订阅: videoSubscribeStateChanged(3)
    已订阅 --> 未订阅: videoSubscribeStateChanged(1)
    
    已订阅 --> 创建视频元素: newState=3
    未订阅 --> 移除视频元素: newState=1

视频元素生命周期管理

  1. 创建时机:

    // 当订阅状态变为3(已订阅)时创建视频元素
    if (newState === 3) {
    const video = document.createElement('video');
    video.autoplay = true;
    remoteVideoElMap.current[vid] = video;
    remoteVideoContainer.current?.appendChild(video);
    aliRtcEngine.current!.setRemoteViewConfig(video, userId, trackType);
    }
    
  2. 销毁时机:

    function removeRemoteVideo(userId: string, type: 'camera' | 'screen') {
    aliRtcEngine.current!.setRemoteViewConfig(null, userId, trackType);
    el.pause();
    remoteVideoContainer.current?.removeChild(el);
    delete remoteVideoElMap.current[vid];
    }
    

5. 关键事件处理

remoteUserOnLineNotify

  • 触发条件: 远端用户加入频道
  • 处理逻辑: 显示通知,记录日志

remoteUserOffLineNotify

  • 触发条件: 远端用户离开频道
  • 处理逻辑:

    • 显示通知
    • 移除对应的视频元素

      removeRemoteVideo(userId, 'camera');
      removeRemoteVideo(userId, 'screen');
      

videoSubscribeStateChanged

  • 参数说明:
    • userId: 远端用户ID
    • oldState: 旧状态
    • newState: 新状态(3:订阅成功, 1:取消订阅)
  • 核心逻辑:

    if (newState === 3) {
    // 创建并配置视频元素
    } else if (newState === 1) {
    // 移除视频元素
    }
    

6. 错误处理机制

  1. 加入频道失败:

    try {
    await aliRtcEngine.current.joinChannel(...);
    } catch (error) {
    console.log('加入频道失败', error);
    showToast('error', '加入频道失败');
    }
    
  2. 全局错误监听:

  3. 通过on('bye')事件处理异常退出

  4. 通过Toast组件显示错误信息