HarmonyOS 直播连麦实战:从开播端解码到看播端合流完整方案
场景与价值连麦是直播中的一种常见场景指两位及以上主播或主播与粉丝进行实时音视频交互实现跨空间共同直播的模式广泛应用于娱乐互动、电商带货、在线教育等领域。应用场景娱乐场景主播PK、合唱互动提升观众参与感电商场景品牌主播与达人连麦能整合双方流量扩大商品曝光教育场景师生连麦可实现实时答疑模拟线下课堂体验对于直播应用开发者而言客户端开播侧的核心技术为音视频采集与编码在直播连麦场景下新增对连麦方主播/粉丝音视频流的解码与渲染开发。本文聚焦于客户端开播侧的音视频流解码播放详细介绍对应的技术实现方案。直播连麦架构以两路主播连麦场景为例直播连麦的整个流程可以分为发起连麦、连麦建立和观众观看三个主要阶段。第一阶段发起连麦主播1通过其应用客户端发起连麦申请云端业务服务器接收到连麦申请后向主播2发送连麦请求主播2通过其应用客户端向云端业务服务器发送同意连麦申请。第二阶段连麦建立主播1的客户端应用SDK采集主播1的音视频信息编码后发送至云端信令服务器同时从云端服务器拉取主播2的音视频码流在本地客户端进行解码和渲染后根据应用业务层设计的连麦UI布局在本端手机屏幕上合成画面后同时展示主播1和主播2的连麦画面。主播2的流程与此类似。第三阶段观众观看云端信令服务器接收到主播1和主播2的音视频信息后在云端进行合流操作包括根据连麦UI布局合成主播1和主播2的画面为视频帧以及将两路音频流混音为一路音频流。合流后最终通过CDN分发至各观众客户端观众客户端依据传输协议拉取连麦后的音视频码流并通过本地播放器解码播放。业务调度、信令通信等云端服务是可以跨端通用的。与基础单播场景相比连麦场景的主要差异在于开播端需要新增音频和视频的解码播放能力该能力可通过系统底座的Audio Kit、AVCodec Kit、Graphic Kit等接口进行开发实现。看播端拉流的音频和视频数据来源于云端并在云端完成了合流操作因此连麦场景看播端解决方案与单播场景一致。开播端解决方案以两路主播连麦场景为例主播1在录制的过程中设备从云端服务器拉取主播2的音频和视频码流并与主播1的预览画面同步播放。实现原理主播1客户端从云端拉取主播2的视频码流通常为H.264或H.265格式并解码与连麦UI布局XComponent创建的Surface ID关联后即可直接渲染上屏显示。本端开播录制开播端本端主播连麦录制的场景与单播场景解决方案一致可以参考媒体直播单播场景的开播端解决方案。对端解码播放创建视频解码器实例int32_tVideoDecoder::Create(conststd::stringvideoCodecMime){// Create a video decoder instancedecoderOH_VideoDecoder_CreateByMime(videoCodecMime.c_str());CHECK_AND_RETURN_RET_LOG(decoder!nullptr,AVCODEC_SAMPLE_ERR_ERROR,Create failed);returnAVCODEC_SAMPLE_ERR_OK;}配置视频解码器int32_tVideoDecoder::Configure(constSampleInfosampleInfo){// Configure the video decoderOH_AVFormat*formatOH_AVFormat_Create();CHECK_AND_RETURN_RET_LOG(format!nullptr,AVCODEC_SAMPLE_ERR_ERROR,AVFormat create failed);OH_AVFormat_SetIntValue(format,OH_MD_KEY_ROTATION,sampleInfo.videoInfo.videoRotation);OH_AVFormat_SetIntValue(format,OH_MD_KEY_HEIGHT,sampleInfo.videoInfo.videoHeight);OH_AVFormat_SetIntValue(format,OH_MD_KEY_WIDTH,sampleInfo.videoInfo.videoWidth);OH_AVFormat_SetDoubleValue(format,OH_MD_KEY_FRAME_RATE,sampleInfo.videoInfo.frameRate);OH_AVFormat_SetIntValue(format,OH_MD_KEY_PIXEL_FORMAT,sampleInfo.videoInfo.pixelFormat);intretOH_VideoDecoder_Configure(decoder,format);CHECK_AND_RETURN_RET_LOG(retAV_ERR_OK,AVCODEC_SAMPLE_ERR_ERROR,Config failed, ret: %{public}d,ret);OH_AVFormat_Destroy(format);formatnullptr;returnAVCODEC_SAMPLE_ERR_OK;}注册解码回调函数int32_tVideoDecoder::SetCallback(CodecUserData*codecUserData){int32_tretAV_ERR_OK;// Register the decoding callback functionretOH_VideoDecoder_RegisterCallback(decoder,{SampleCallback::OnCodecError,SampleCallback::OnCodecFormatChange,SampleCallback::OnNeedInputBuffer,SampleCallback::OnNewOutputBuffer},codecUserData);CHECK_AND_RETURN_RET_LOG(retAV_ERR_OK,AVCODEC_SAMPLE_ERR_ERROR,Set callback failed, ret: %{public}d,ret);returnAVCODEC_SAMPLE_ERR_OK;}绑定解码器SurfaceIDint32_tVideoDecoder::Config(constSampleInfosampleInfo,CodecUserData*codecUserData){// ...// SetSurface from video decoderif(sampleInfo.videoInfo.window!nullptr){intretOH_VideoDecoder_SetSurface(decoder,sampleInfo.videoInfo.window);CHECK_AND_RETURN_RET_LOG(retAV_ERR_OKsampleInfo.videoInfo.window,AVCODEC_SAMPLE_ERR_ERROR,Set surface failed, ret: %{public}d,ret);}// ...returnAVCODEC_SAMPLE_ERR_OK;}启动解码器后上屏显示int32_tVideoDecoder::Start(){CHECK_AND_RETURN_RET_LOG(decoder!nullptr,AVCODEC_SAMPLE_ERR_ERROR,Decoder is null);// Start the decoderintretOH_VideoDecoder_Start(decoder);CHECK_AND_RETURN_RET_LOG(retAV_ERR_OK,AVCODEC_SAMPLE_ERR_ERROR,Start failed, ret: %{public}d,ret);returnAVCODEC_SAMPLE_ERR_OK;}看播端解决方案看播端拉流的音频和视频数据来源于云端并在云端完成了合流操作。因此看播端解决方案与基础单播场景一致开发者可参考媒体直播单播场景的看播端解决方案。技术要点连麦场景与单播场景的差异连麦场景的主要差异在于开播端需要新增音频和视频的解码播放能力开播端本端采集编码推流与单播一致开播端对端拉流解码渲染新增能力看播端拉流播放与单播一致云端已完成合流核心技术栈系统底座提供的能力Audio Kit音频解码播放AVCodec Kit视频解码Graphic Kit渲染上屏开发流程完整的开发流程包括本端开播录制参考单播方案创建视频解码器实例配置视频解码器参数旋转、高度、宽度、帧率、像素格式注册解码回调函数错误、格式变化、输入缓冲区、输出缓冲区绑定解码器SurfaceID关联XComponent启动解码器上屏显示云端合流云端信令服务器负责接收主播1和主播2的音视频信息根据连麦UI布局合成画面为视频帧将两路音频流混音为一路音频流通过CDN分发至各观众客户端实际应用场景娱乐互动场景主播PK、合唱互动提升观众参与感。两位主播实时音视频交互观众可以看到合流后的画面。电商带货场景品牌主播与达人连麦能整合双方流量扩大商品曝光。主播之间实时互动观众可以同时看到两位主播的推荐。在线教育场景师生连麦可实现实时答疑模拟线下课堂体验。老师和学生实时音视频交互实现更好的教学效果。