鸿蒙端实现RTS推流

更新时间:
复制为 MD 格式

本文介绍在鸿蒙系统基于ARTC SDK如何快速实现超低延时直播推流。

前提条件

请先开通直播服务,配置直播域名,生成直播推拉流地址,请参见:超低延时直播快速入门

集成SDK

在项目中集成鸿蒙版本的ARTC SDK进行RTS推流,请参见:Harmony ARTC SDK集成

功能实现

创建及初始化RTC引擎


private rtcSdk : AliRtcEngine | undefined;
private engineEventListener: AliRtcEngineEventListener | undefined = undefined;


initEngine = () => {

  // 兼容H5模式
  AliRtcEngine.setH5CompatibleMode(true);

  // 创建引擎
  this.rtcSdk = AliRtcEngine.getInstance('', getContext(this));
  if (this.rtcSdk === undefined) {
    // 创建RTC引擎实例失败,一般情况下是上次的直播引擎未能销毁导致,请确保已经销毁完成
    return;
  }

  // [可选]有需要可以开启或关闭日志
  AliRtcEngine.setLogLevel(AliRtcLogLevel.AliRtcLogLevelInfo);

  // 设置需要推送音视频
  this.rtcSdk?.publishLocalVideoStream(true);
  this.rtcSdk?.publishLocalAudioStream(true);

  // 注册回调接口
  this.registerCallback();
  

}

registerCallback = () => {
  this.engineEventListener = new AliRtcEngineEventListener();
  this.engineEventListener
    .onPublishStreamByRtsUrlResult((rtsUrl : string, result : number)=> {
      // 发起推流后的结果回调
      this.onPublishResult(rtsUrl, result);
    })
    .onStopPublishStreamByRtsUrlResult((rtsUrl : string, result : number)=> {
      // 发起停止推流后的结果回调
    })    
    .onConnectionStatusChange((status: number, reason: number) => {
      // 当前推流期间连接状态回调
    })
    .onLocalDeviceException((deviceType: AliRtcLocalDeviceType, exceptionType: AliRtcLocalDeviceExceptionType,
      msg: string) => {
      // 设备出现异常(例如采集等)
    })
    .onNetworkQualityChanged((uid: string, upQuality: AliRtcNetworkQuality, downQuality: AliRtcNetworkQuality) => {
      // 网络状态变化
    })
    .onOccurWarning((warn: number, msg: string) => {
      // 出现相关警告
    })
    .onOccurError((error: number, msg: string) => {
      // 出现严重错误,此时无法进行下去了,需要从新重新创建引擎并进行推流
    })
    .onFirstLocalVideoFrameDrawn((width : number, height : number, elapsed : number)=>{
      // 摄像头采集后预览的首帧的渲染
    });
    
  this.rtcSdk?.setRtcEngineEventListener(this.engineEventListener);
}

设置推流参数及开启预览

一般情况下,在创建引擎后进行设置。

  // 设置音频编码参数
  this.rtcSdk?.setAudioProfile(AliRtcAudioProfile.AliRtcHighQualityMode, AliRtcAudioScenario.AliRtcSceneDefaultMode);
  
  // 设置视频编码参数(分辨率、帧率、码率、关键帧间隔等)
  let dimensions = new AliRtcVideoDimensions();
  dimensions.width = 720;
  dimensions.height = 1280;
  let encoderConfig: AliRtcVideoEncoderConfiguration = new AliRtcVideoEncoderConfiguration();
  encoderConfig.dimensions = dimensions;
  encoderConfig.frameRate = 20;
  this.rtcSdk?.setVideoEncoderConfiguration(encoderConfig);
  // [可选]默认是仅预览镜像,有需要可以设置其他视频镜像模式
  this.rtcSdk?.setVideoMirrorMode(AliRtcVideoPipelineMirrorMode.AliRtcVideoPipelineMirrorModeOnlyPreviewMirror);

   // 开启预览
  const localVideoCanvas: AliRtcVideoCanvas = new AliRtcVideoCanvas();
  localVideoCanvas.surfaceId = this.componentController.getXComponentSurfaceId();
  this.rtcSdk?.setLocalViewConfig(localVideoCanvas, this.componentController,
                                      AliRtcVideoTrack.AliRtcVideoTrackCamera);
  const result = this.rtcSdk?.startPreview()

发布RTS

在获取到推流地址后,调用API进行发布RTS流。注意是否成功发布,SDK会通过onPublishStreamByRtsUrlResult回调告知,参考上面的回调初始化及注册。

publishRtsUrl = (rtsUrl: string) => {
  const result = this.rtcSdk?.publishStreamByRtsUrl(this.publishRtsUrl)
  if (result === 0) {
    // 成功调用接口
  }
}

// 处理发布结果
onPublishResult(rtsUrl : string, result : number) {
  if (result === 0) {
    // 发布rts流成功
  } else {
    // 发布rts流失败
  }
}

成功发布后,可以通过播流工具进行验证,请参见:方法一:使用移动端播RTS

在业务开发中,建议接入播流SDK进行拉流播放,请参见:鸿蒙端实现RTS拉流

控制摄像头及麦克风

在直播过程中,根据主播需求,提供开启/关闭摄像头,开启/关闭麦克风的操作。

onMuteMicBtnClicked = (enable: boolean) => {
  if (enable) {
    this.rtcSdk?.muteLocalMic(enable, AliRtcMuteLocalAudioMode.AliRtcMuteLocalAudioModeMuteOnlyMic);
  }
  else {
    this.rtcSdk?.muteLocalMic(enable, AliRtcMuteLocalAudioMode.AliRtcMuteLocalAudioModeMuteOnlyMic);
  }
}

onMuteCameraBtnClicked = (enable: boolean) => {
  this.rtcSdk?.muteLocalCamera(enable, AliRtcVideoTrack.AliRtcVideoTrackCamera);
}

停止发布RTS

stopPublishRtsUrl = (rtsUrl: string) => {
  const result = this.rtcSdk?.stopPublishStreamByRtsUrl(this.publishRtsUrl);
  if (result === 0) {
    // 停止发布rts流成功
  }
  else {
    // 停止发布rts流失败
}

销毁引擎

停止发布后,如果要结束直播,需要销毁引擎。

destroy = () : void => {
  if (this.rtcSdk === undefined) {
    return;
  }

  AliRtcEngine.destroyInstance();
  this.rtcSdk = undefined
  this.engineEventListener = undefined
}