应用场景
班课场景
在班课场景中,学员通常需要同时观看课件内容和老师视频画面。课件内容一般是 PPT、Word 等第三方窗口,在上课时,课件一般会全屏显示或者最大化显示,采集的时候可以基于窗口句柄采集,也可以采集整个屏幕画面。
除了使用后台混流方案,还可将本地摄像头的画面悬浮在屏幕的最顶层,然后对整个屏幕区域进行采集。这种方法的界面处理逻辑需要业务方自己开发实现,实现较为复杂,同时也因为采集的是整个屏幕区域,容易把其他程序的窗口误采集进去。误采集的窗口,可能会泄露老师隐私,同时也会使学员的注意力分散,影响上课效果。
相比悬浮视频窗口的方案,使用客户端本地合流方案会更好。采集课件窗口不采集整个屏幕区域,同时采集摄像头视频不用悬浮显示,这样就不会遮挡老师的课件区域,通过 TRTC SDK 在本地把课件内容和摄像头视频合为一路视频流。


会议直播场景
在会议直播场景中,存在多个摄像机机位一起直播的场景。业务方可以根据需要展示的机位数量开发不同的布局模板,例如左右并列、九宫格、一大多小等布局。
除了使用后台混流方案可以实现,还可使用客户端合流方案。客户端通过采集卡等外部设备,获得摄像机的视频流,加上 PPT 分享窗口,以及会议主办方 Logo 图片等,在本地合成一路视频流,再推流到 TRTC 后台。
如果中途需要切换摄像机画面,又不想改变布局时,则可以重新构造本地混流参数,修改视频源更新混流参数即可。


游戏直播场景
在 PC 端游戏直播场景中,除了游戏操作画面需要直播,还需要加上主播自己的摄像头画面。后台混流方案的实现是推两路流,一路桌面分享流、一路摄像头流,然后调用后台混流接口合为一路视频流。如果本地电脑的配置高,则可以使用客户端合流方案,在本地电脑把桌面分享流和摄像头流合为一路视频流,再推流到 TRTC 后台。


后台混流方案和客户端合流方案对比
以上三个场景用后台混流方案和客户端合流方案均能实现,各有优势,详情如下:
后台混流方案
后台可以针对单流录制。
可以对单流进行二次处理,例如 AI 语音识别等。
对客户端配置要求不高。
客户端合流方案
业务方可以做出各种灵活的合流模板供主播自己选择。
费用低,没有后台混流成本。
对客户端电脑配置要求比较高。
后台混流方案与客户端合流方案的架构对比:


方案原理
合流的处理过程,可以理解为视频流的输出画面最下方有一层“幕布”,在“幕布”上一层叠加子画面。
输出画面的宽高、背景色、码率这几个参数需要特别注意:
画面宽高选择:输出画面通常可以使用横屏模式,宽高比例可以选择 16:9,这个比例在手机和 PC 上播放的效果都不错。需要注意的是,如果严格按照16:9 的比例,有可能跟 PC 采集端屏幕分辨率比例不一致,导致“幕布”左右两边留有空白,这时则需要业务方进行处理,用纯色或者图片填充。还可以使用 PC 采集端的屏幕分辨率作为输出画面的宽高,这样屏幕层可以把整个“幕布”占满。
背景色的选择:当子画面铺不满“幕布”时,可以设置输出画面的背景色。背景色可以根据具体业务需求设定,例如可以设置为播放器窗口背景色一样的颜色,在播放器播放视频时,视频铺不满播放器窗口的地方,视频背景色和播放器背景色融合在一起,看不出边界。
混流输出码率的选择:可以根据分辨率、帧率设置对应的输出码率,输出过大会浪费带宽,输出过小则会导致视频模糊,具体可以参考 码率设置。
1. 设置输出画面的背景色和宽高,这里的背景色只是参考,具体选择根据业务需求决定。


2. 设置第一层子画面,通常是屏幕采集到的画面,例如整个游戏的画面。
第一层子画面的层级为一,坐标点的参数为
RECT{left,top,right,bottom},坐标原点相对于“幕布”的左上角。如果第一层子画面跟“幕布”大小一致,则可以跟“幕布”的坐标一致。如果不一致,可以适应最短边,长边按比例拉伸后居中。

3. 设置第二层子画面,通常是主播自己的摄像头采集画面。
为了提升体验,业务方可以在客户端实现一个子画面拖动摆放位置的功能,让主播自己调整子画面的大小和位置,这样就不会挡住上一层画面的重要内容。


4. 设置第三层子画面,通常可以加个业务方 Logo 图片,可以设置一张静态图片或者动态图片。第三层子画面的位置不一定要叠在第二层的位置上,二层和三层表示层级关系,没有从属关系。


注意:
这里的图片地址是本地图片的绝对路径,如果是网络地址图片,需要业务方提前下载到本地。
实现逻辑
客户端合流及推流流程


实现步骤
1. 设置输出画面的分辨率
videoEncoderParams.videoResolution、帧率videoEncoderParams.videoFps和背景色canvasColor。2. 设置第一层子画面的类型
sourceType为MediaSourceScreen,设置需要采集的屏幕screenSourceId、子画面区域rect和子画面层级zOrder。3. 设置第二层子画面的类型
sourceType为MediaSourceCamera,设置需要采集的摄像头cameraDeviceId、子画面区域rect和子画面层级zOrder。4. 设置第三层子画面的类型
sourceType为MediaSourceImage,设置图片的本地路径imagePath、子画面区域rect和子画面层级zOrder。5. 计算所有子画面的层级数量,设置输出画面的总层级数
inputSourceListSize和所有层级信息inputSourceList。6. 设置 SDK 合流状态和错误码回调
setTranscodingCallback。7. 开始本地合流并推流
startTranscoding。8. 中途如果需要变更布局可以使用
updateTranscodingParams。9. 结束本地合流和推流
stopTranscoding。示例代码
1. 引入 ITXLocalMediaTranscoding.h 头文件,获取
ITXLocalMediaTranscoding实例。#include "ITXLocalMediaTranscoding.h"// 创建合流实例tx_local_media_transcoding_ = createTXLocalMediaTranscoding();
2. 设置输出画面相关参数:大小、颜色等。
auto canvas = std::make_shared<LocalMediaTranscodingParams>();// 将输出画面大小设置为 1080PTRTCVideoEncParam enc_params;enc_params.videoResolution = TRTCVideoResolution_1920_1080;enc_params.videoFps = 30;canvas->videoEncoderParams = enc_params;// 设置输出画面默认颜色canvas->canvasColor = 0xFF0000;
3. 给输出画面添加源。
std::vector<LocalMediaTranscodingSource> sources;TRTCRenderParams render_params;// 设置渲染模式render_params.fillMode = TRTCVideoFillMode_Fill;// 添加屏幕分享源LocalMediaTranscodingSource screen;// 先通过 TRTC 接口获取到可分享的窗口列表auto screen_capture_list = getTRTCShareInstance()->getScreenCaptureSources(thumb_size, icon_size);// 添加第一个源screen.screenSourceId = screen_capture_list->getSourceInfo(0).sourceId;screen.rect = {0, 0, 1920, 1080};// 目前支持 摄像头源、屏幕分享源、图片源screen.sourceType = MediaSourceScreen;screen.zOrder = 0;sources.push_back(screen);
4. 绑定 TRTC 推流。
// 绑定 TRTC,需要在 TRTC 进房后绑定tx_local_media_transcoding_->attachTRTC(getTRTCShareInstance());// 开启采集// 注意这里跟 TRTC 的 startScreenCapture 是互斥的,不能同时使用// 摄像头也一样互斥tx_local_media_transcoding_->startScreenSource(screen_capture_list->getSourceInfo(0),{0, 0, 0, 0});// 开启合流, 并推流tx_local_media_transcoding_->startTranscoding(TRTCVideoStreamTypeBig, *sources);