应用场景
班课场景
在班课场景中,学员通常需要同时观看课件内容和老师视频画面。课件内容一般是 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);