TRTCPublishBigStreamToCdn
或者 TRTCPublishSubStreamToCdn
,其中前者是指发布当前用户的主路画面(一般是摄像头),后者是指发布当前用户的辅路画面(一般是屏幕分享)。rtmp://
作为 URL 的前缀)。如果您指定的 url 是腾讯云的直播 CDN 推流地址,需要将 isInternalLine 设置为 true,否则请将其设置为 false。TRTCStreamEncoderParam
和 TRTCStreamMixingConfig
两个参数为空。```// 发布当前用户的音视频流到直播CDNTRTCCloudDef.TRTCPublishTarget target = new TRTCCloudDef.TRTCPublishTarget();target.mode = TRTC_PublishBigStream_ToCdn;TRTCCloudDef.TRTCPublishCdnUrl cdnUrl= new TRTCCloudDef.TRTCPublishCdnUrl();cdnUrl.rtmpUrl = "rtmp://tencent/live/bestnews";cdnUrl.isInternalLine = true;target.cdnUrlList.add(cdnUrl);mTRTCCloud.startPublishMediaStream(target, null, null);```
```// 发布当前用户的音视频流到直播CDNTRTCPublishTarget* target = [[TRTCPublishTarget alloc] init];target.mode = TRTCPublishBigStreamToCdn;TRTCPublishCdnUrl* cdnUrl = [[TRTCPublishCdnUrl alloc] init];cdnUrl.rtmpUrl = @"rtmp://tencent/live/bestnews";cdnUrl.isInternalLine = YES;NSMutableArray* cdnUrlList = [NSMutableArray new];[cdnUrlList addObject:cdnUrl];target.cdnUrlList = cdnUrlList;[_trtcCloud startPublishMediaStream:target encoderParam:nil mixingConfig:nil];```
```// 发布当前用户的音视频流到直播CDNTRTCPublishTarget target;target.mode = TRTCPublishMode::TRTCPublishBigStreamToCdn;TRTCPublishCdnUrl* cdn_url_list = new TRTCPublishCdnUrl[1];cdn_url_list[0].rtmpUrl = "rtmp://tencent/live/bestnews";cdn_url_list[0].isInternalLine = true;target.cdnUrlList = cdn_url_list;target.cdnUrlListSize = 1;trtc->startPublishMediaStream(&target, nullptr, nullptr);delete[] cdn_url_list;```
TRTCPublishTarget target = TRTCPublishTarget();target.mode = TRTCPublishMode.TRTCPublishBigStreamToCdn;TRTCPublishCdnUrl cdnUrlEntity = new TRTCPublishCdnUrl();cdnUrlEntity.rtmpUrl = "rtmp://tencent/live/bestnews";cdnUrlEntity.isInternalLine = true;target.cdnUrlList.add(cdnUrlEntity);trtcCloud.startPublishMediaStream(target: target);
TRTCStreamEncoderParam
和 TRTCStreamMixingConfig
两个参数对混流和转码的细节进行控制。TRTCStreamMixingConfig
)进行混合,最终再通过您指定的参数(TRTCStreamEncoderParam
)进行二次编码,最终才能合成一路音视频流并发布到直播 CDN 上,因此该模式下的转推服务需要额外的转码费用。TRTCPublishMixStreamToCdn
。rtmp://
作为 URL 的前缀)。如果您指定的 url 是腾讯云的直播 CDN 推流地址,需要将 isInternalLine 设置为 true,否则请将其设置为 false。TRTCStreamEncoderParam
设置转码后的音视频流的编码参数:
视频编码参数:需要您指定混合后画面的分辨率、帧率、码率和编码的 GOP 大小,其中 GOP 推荐设置为 3s 即可,FPS 推荐设置为 15,码率和分辨率有一定的映射关系,如下表格列出了几种常用的分辨率以及其对应的推荐码率。
音频编码参数:需要您指定混合后音频的编码格式、编码码率、采样率和声道数。这一步首先需要您先确认一下您在调用 startLocalAudio 时第二个参数 AudioQuality 所指定的音质类型,然后根据您指定的音质类型填写此处的参数。videoEncodedWidth | videoEncodedHeight | videoEncodedFPS | videoEncodedGOP | videoEncodedKbps |
640 | 360 | 15 | 3 | 800kbps |
960 | 540 | 15 | 3 | 1200kbps |
1280 | 720 | 15 | 3 | 1500kbps |
1920 | 1080 | 15 | 3 | 2500kbps |
TRTCAudioQuality | audioEncodedSampleRate | audioEncodedChannelNum | audioEncodedKbps | audioEncodedCodecType |
TRTCAudioQualitySpeech | 48000 | 1 | 50 | 0 |
TRTCAudioQualityDefault | 48000 | 1 | 50 | 0 |
TRTCAudioQualityMusic | 48000 | 2 | 60 | 2 |
TRTCStreamMixingConfig
设置音频混流参数和画面排版模式:
音频混流参数(audioMixUserList):默认情况下填空值即可,代表会混合房间中的所有音频,如果您只希望混合方面中某几个用户的声音,才需要指定该参数。
画面布局参数(videoLayoutList):画面布局是由一个数组所定义的,数组中的每一个 TRTCVideoLayout 对象都代表了一块区域的位置、大小、背景颜色等等。如果您指定了 TRTCVideoLayout 中的 fixedVideoUser 字段,意味着这个 layout 对象所定义的区域被固定用来显示某个用户的画面。您也可以将 fixedVideoUser 设置为 null,这意味着您只是指定了该区域会有视频画面,但画面中的用户具体是谁是不确定的,交由 TRTC 混流服务器根据一定的规则来决定。案例一:四个用户的画面被混合在了同一个画面中,我们还使用了一张图片作为背景画布layout1:定义了用户 jerry 的摄像头画面的大小和位置,画面大小为 640x480,位置在画面的中上部。layout2、 layout3、 layout4:均没有指定具体的用户 Id,因此 TRTC 会根据一定的规则选择房间中 3 路用户的画面安置在这三个位置。 案例二:四位用户的摄像头画面和一路屏幕分享的画面被混合在了同一个画面中layout1: 定义了用户 jerry 的屏幕分享画面的大小和位置,画面大小为 1280x720,填充模式为可能有黑边的 Fit 模式,背景填充色为黑色,位置在画面的左侧。layout2: 定义了用户 jerry 的摄像头画面的大小和位置,画面大小为 300x200,填充模式为 Fill 模式,位置在画面的右上角。layout3、layout4、layout5:均没有指定具体的用户 Id,因此 TRTC 会根据一定的规则选择房间中 3 路用户的画面安置在这三个位置。
```// 指定发布模式为 TRTC_PublishMixedStream_ToCdnTRTCCloudDef.TRTCPublishTarget target = new TRTCCloudDef.TRTCPublishTarget();target.mode = TRTC_PublishMixedStream_ToCdn;// 指定发布的 CDN 推流地址TRTCCloudDef.TRTCPublishCdnUrl cdnUrl= new TRTCCloudDef.TRTCPublishCdnUrl();cdnUrl.rtmpUrl = "rtmp://tencent/live/bestnews";cdnUrl.isInternalLine = true;target.cdnUrlList.add(cdnUrl);// 设置混合后的音视频流的二次编码参数TRTCCloudDef.TRTCStreamEncoderParam encoderParam= new TRTCCloudDef.TRTCStreamEncoderParam();encoderParam.videoEncodedWidth = 1280;encoderParam.videoEncodedHeight = 720;encoderParam.videoEncodedFPS = 15;encoderParam.videoEncodedGOP = 3;encoderParam.videoEncodedKbps = 1000;encoderParam.audioEncodedSampleRate = 48000;encoderParam.audioEncodedChannelNum = 1;encoderParam.audioEncodedKbps = 50;encoderParam.audioEncodedCodecType = 0;// 设置画面的布局参数TRTCCloudDef.TRTCStreamMixingConfig mixingConfig =new TRTCCloudDef.TRTCStreamMixingConfig();TRTCCloudDef.TRTCVideoLayout layout1 = new TRTCCloudDef.TRTCVideoLayout();layout1.zOrder = 0;layout1.x = 0;layout1.y = 0;layout1.width = 720;layout1.height = 1280;layout1.fixedVideoStreamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB;layout1.fixedVideoUser.intRoomId = 1234;layout1.fixedVideoUser.userId = "mike";TRTCCloudDef.TRTCVideoLayout layout2 = new TRTCCloudDef.TRTCVideoLayout();layout2.zOrder = 0;layout2.x = 1300;layout2.y = 0;layout2.width = 300;layout2.height = 200;layout2.fixedVideoStreamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG;layout2.fixedVideoUser.intRoomId = 1234;layout2.fixedVideoUser.userId = "mike";TRTCCloudDef.TRTCVideoLayout layout3 = new TRTCCloudDef.TRTCVideoLayout();layout3.zOrder = 0;layout3.x = 1300;layout3.y = 220;layout3.width = 300;layout3.height = 200;layout3.fixedVideoStreamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB;layout3.fixedVideoUser = null;mixingConfig.videoLayoutList.add(layout1);mixingConfig.videoLayoutList.add(layout2);mixingConfig.videoLayoutList.add(layout3);mixingConfig.audioMixUserList = null;// 发起混流mTRTCCloud.startPublishMediaStream(target, encoderParam, mixingConfig);```
```// 指定发布模式为 TRTCPublishMixStreamToCdnTRTCPublishTarget* target = [[TRTCPublishTarget alloc] init];target.mode = TRTCPublishMixStreamToCdn;// 指定发布的 CDN 推流地址TRTCPublishCdnUrl* cdnUrl = [[TRTCPublishCdnUrl alloc] init];cdnUrl.rtmpUrl = @"rtmp://tencent/live/bestnews";cdnUrl.isInternalLine = YES;NSMutableArray* cdnUrlList = [NSMutableArray new];[cdnUrlList addObject:cdnUrl];target.cdnUrlList = cdnUrlList;// 设置混合后的音视频流的二次编码参数TRTCStreamEncoderParam* encoderParam = [[TRTCStreamEncoderParam alloc] init];encoderParam.videoEncodedWidth = 1280;encoderParam.videoEncodedHeight = 720;encoderParam.videoEncodedFPS = 15;encoderParam.videoEncodedGOP = 3;encoderParam.videoEncodedKbps = 1000;encoderParam.audioEncodedSampleRate = 48000;encoderParam.audioEncodedChannelNum = 1;encoderParam.audioEncodedKbps = 50;encoderParam.audioEncodedCodecType = 0;// 设置画面的布局参数TRTCStreamMixingConfig* config = [[TRTCStreamMixingConfig alloc] init];NSMutableArray* videoLayoutList = [NSMutableArray new];TRTCVideoLayout* layout1 = [[TRTCVideoLayout alloc] init];layout1.zOrder = 0;layout1.rect = CGRectMake(0, 0, 720, 1280);layout1.fixedVideoStreamType = TRTCVideoStreamTypeSub;layout1.fixedVideoUser.intRoomId = 1234;layout1.fixedVideoUser.userId = @"mike";TRTCVideoLayout* layout2 = [[TRTCVideoLayout alloc] init];layout2.zOrder = 0;layout2.rect = CGRectMake(1300, 0, 300, 200);layout2.fixedVideoStreamType = TRTCVideoStreamTypeBig;layout2.fixedVideoUser.intRoomId = 1234;layout2.fixedVideoUser.userId = @"mike";TRTCVideoLayout* layout3 = [[TRTCVideoLayout alloc] init];layout3.zOrder = 0;layout3.rect = CGRectMake(1300, 220, 300, 200);layout3.fixedVideoStreamType = TRTCVideoStreamTypeSub;layout3.fixedVideoUser = nil;[videoLayoutList addObject:layout1];[videoLayoutList addObject:layout2];[videoLayoutList addObject:layout3];config.videoLayoutList = videoLayoutList;config.audioMixUserList = nil;// 发起混流[_trtcCloud startPublishMediaStream:target encoderParam:encoderParam mixingConfig:config];```
```// 指定发布模式为 TRTCPublishMixStreamToCdnTRTCPublishTarget target;target.mode = TRTCPublishMode::TRTCPublishMixStreamToCdn;// 指定发布的 CDN 推流地址TRTCPublishCdnUrl* cdn_url = new TRTCPublishCdnUrl[1];cdn_url[0].rtmpUrl = "rtmp://tencent/live/bestnews";cdn_url[0].isInternalLine = true;target.cdnUrlList = cdn_url;target.cdnUrlListSize = 1;// 设置混合后的音视频流的二次编码参数TRTCStreamEncoderParam encoder_param;encoder_param.videoEncodedWidth = 1280;encoder_param.videoEncodedHeight = 720;encoder_param.videoEncodedFPS = 15;encoder_param.videoEncodedGOP = 3;encoder_param.videoEncodedKbps = 1000;encoder_param.audioEncodedSampleRate = 48000;encoder_param.audioEncodedChannelNum = 1;encoder_param.audioEncodedKbps = 50;encoder_param.audioEncodedCodecType = 0;// 设置画面的布局参数TRTCStreamMixingConfig config;TRTCVideoLayout* video_layout_list = new TRTCVideoLayout[3];TRTCUser* fixedVideoUser0 = new TRTCUser();fixedVideoUser0->intRoomId = 1234;fixedVideoUser0->userId = "mike";video_layout_list[0].zOrder = 0;video_layout_list[0].rect.left = 0;video_layout_list[0].rect.top = 0;video_layout_list[0].rect.right = 720;video_layout_list[0].rect.bottom = 1280;video_layout_list[0].fixedVideoStreamType =TRTCVideoStreamType::TRTCVideoStreamTypeSub;video_layout_list[0].fixedVideoUser = fixedVideoUser0;TRTCUser* fixedVideoUser1 = new TRTCUser();fixedVideoUser1->intRoomId = 1234;fixedVideoUser1->userId = "mike";video_layout_list[1].zOrder = 0;video_layout_list[1].rect.left = 1300;video_layout_list[1].rect.top = 0;video_layout_list[1].rect.right = 300;video_layout_list[1].rect.bottom = 200;video_layout_list[1].fixedVideoStreamType =TRTCVideoStreamType::TRTCVideoStreamTypeBig;video_layout_list[1].fixedVideoUser = fixedVideoUser1;video_layout_list[2].zOrder = 0;video_layout_list[2].rect.left = 1300;video_layout_list[2].rect.top = 220;video_layout_list[2].rect.right = 300;video_layout_list[2].rect.bottom = 200;video_layout_list[2].fixedVideoStreamType =TRTCVideoStreamType::TRTCVideoStreamTypeSub;video_layout_list[2].fixedVideoUser = nullptr;config.videoLayoutList = video_layout_list;config.videoLayoutListSize = 3;config.audioMixUserList = nullptr;// 发起混流trtc->startPublishMediaStream(&target, &encoder_param, &config);delete fixedVideoUser0;delete fixedVideoUser1;delete[] video_layout_list;```
TRTCPublishTarget target = TRTCPublishTarget();target.mode = TRTCPublishMode.TRTCPublishMixStreamToCdn;TRTCPublishCdnUrl cdnUrlEntity = new TRTCPublishCdnUrl();cdnUrlEntity.rtmpUrl = "rtmp://tencent/live/bestnews";cdnUrlEntity.isInternalLine = true;target.cdnUrlList.add(cdnUrlEntity);TRTCStreamMixingConfig config = TRTCStreamMixingConfig();TRTCUser selfUser = TRTCUser();selfUser.userId = localUserId;selfUser.intRoomId = localRoomId;TRTCVideoLayout selfVideoLayout = TRTCVideoLayout();selfVideoLayout.fixedVideoStreamType = TRTCVideoStreamType.TRTCVideoStreamTypeBig;selfVideoLayout.rect = Rect(originX: 0, originY: 0, sizeWidth: 1080, sizeHeight: 1920);selfVideoLayout.zOrder = 0;selfVideoLayout.fixedVideoUser = selfUser;selfVideoLayout.fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fit;config.videoLayoutList.add(selfVideoLayout);TRTCUser remoteUser = TRTCUser();remoteUser.userId = remoteUserId;remoteUser.intRoomId = remoteRoomId;TRTCVideoLayout remoteVideoLayout = TRTCVideoLayout();remoteVideoLayout.fixedVideoStreamType = TRTCVideoStreamType.TRTCVideoStreamTypeBig;remoteVideoLayout.rect = Rect(originX: 100, originY: 50, sizeWidth: 216, sizeHeight: 384);remoteVideoLayout.zOrder = 1;remoteVideoLayout.fixedVideoUser = remoteUser;remoteVideoLayout.fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fit;config.videoLayoutList.add(remoteVideoLayout);TRTCStreamEncoderParam param = TRTCStreamEncoderParam();param.videoEncodedWidth = 1080;param.videoEncodedHeight = 1920;param.videoEncodedKbps = 5000;param.videoEncodedFPS = 30;param.videoEncodedGOP = 3;param.audioEncodedSampleRate = 48000;param.audioEncodedChannelNum = 2;param.audioEncodedKbps = 128;param.audioEncodedCodecType = 2;trtcCloud.startPublishMediaStream(target: target, config: config, params: param);
onCdnStreamStateChanged
回调获取最新的后台任务状态更新回调。更多细节可参考 API 文档。taskid
发起 updatePublishMediaStream
推流任务变更即可。但是为了确保推流链接稳定,从单路推流切换到混流推流无法切换到纯音频或者纯视频模式。单路推流默认是音视频模式,切换后的混流也需要是音视频模式。TRTCStreamEncodeParam
里音频相关参数不要设置且 TRTCStreamMixingConfig
里 audioMixUserList
设置为空。TRTCStreamMixingConfig
的 watermarkList
进行设置。更多细节可参考 API 文档。TRTCVideoLayout
的 fixedVideoStreamType
为 TRTCVideoStreamTypeSub
即可。startPublishMediaStream
)的主播退出了房间stopPublishMediaStream
主动停止混流
本页内容是否解决了您的问题?