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;
const options = {target: {publishMode: PublishMode.PublishMainStreamToCDN}}try {await trtc.startPlugin('CDNStreaming', options);} catch (error) {console.error('CDNStreaming start failed', error);}
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 | 视频码率 |
640 | 360 | 15 | 3 | 800kbps |
960 | 540 | 15 | 3 | 1200kbps |
1280 | 720 | 15 | 3 | 1500kbps |
1920 | 1080 | 15 | 3 | 2500kbps |
TRTC音频质量类型 | 音频采样率 | 音频声道数 | 音频码率 |
TRTCAudioQualitySpeech | 48000 | 1 | 50kbps |
TRTCAudioQualityDefault | 48000 | 1 | 50kbps |
TRTCAudioQualityMusic | 48000 | 2 | 60kbps |
TRTCStreamMixingConfig
设置音频混流参数和画面排版模式:// 指定发布模式为 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);
// 指定发布模式为 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);
true
,则为混流转推,若设置为false
,则为旁路转推。字段名称 | 描述 | 必选 |
SdkAppId | TRTC 的 SdkAppId | 是 |
RoomId | 主房间信息 RoomId | 是 |
RoomIdType | 主房间信息 RoomType | 是 |
WithTranscoding | 是否转码 | 是 |
字段名称 | 描述 | 必选 |
AgentParams.UserId | 转推服务在 TRTC 房间使用的 UserId,请勿与房间内正常用户使用的 UserId 一致 | 是 |
AgentParams.UserSig | 转推服务加入TRTC房间的用户签名 | 是 |
AgentParams.MaxIdleTime | 空闲等待时间 | 否 |
字段名称 | 描述 | 必选 |
AudioParams.AudioEncode | 混流-音频输出编码参数 | 否 |
AudioParams.SubscribeAudioList | 混流-音频用户白名单 | 否 |
字段名称 | 描述 | 必选 |
VideoParams.VideoEncode | 混流-视频输出编码参数 | 否 |
VideoParams.LayoutParams | 混流-布局参数 | 否 |
VideoParams.BackGroundColor | 混流-画布背景颜色 | 否 |
VideoParams.BackgroundImageUrl | 混流-画布背景图 URL | 否 |
VideoParams.WaterMarkList | 混流-水印参数 | 否 |
字段名称 | 描述 | 必选 |
SingleSubscribeParams.UserMediaStream.UserInfo | TRTC 用户参数 | 否 |
SingleSubscribeParams.UserMediaStream.StreamType | 主辅路流类型 | 否 |
字段名称 | 描述 | 必选 |
PublishCdnParams.N.PublishCdnUrl | CDN 转推 URL | 是 |
PublishCdnParams.N.IsTencentCdn | 是否是腾讯云 CDN,0为转推非腾讯云 CDN,1为转推腾讯 CDN,不携带该参数默认为1。 注意: 1:为避免误产生转推费用,该参数建议明确填写,转推非腾讯云 CDN 时会产生转推费用,详情参见接口文档说明 2:国内站默认只支持转推腾讯云 CDN,如您有转推第三方 CDN 需求,请联系腾讯云技术支持 | 否 |
字段名称 | 描述 | 必选 |
FeedBackRoomParams.N.RoomId | 回推房间的RoomId | 是 |
FeedBackRoomParams.N.RoomIdType | 回推房间的类型,0为整形房间号,1为字符串房间号 | 否 |
FeedBackRoomParams.N.UserId | 回推房间使用的UserId 注意: 这个UserId不能与其他TRTC或者转推服务等已经使用的UserId重复,建议可以把房间ID作为UserId的标识的一部分。 | 是 |
FeedBackRoomParams.N.UserSig | 是 |
字段名称 | 描述 | 必选 |
McuSeiParams.LayoutVolume | 音量布局 SEI,内容是固定的 JSON 结构,具体见下面说明。 | 否 |
McuSeiParams.PassThrough | 透传 SEI。 | 否 |
{"app_data": "test","canvas": {"w": 1280,"h": 720},"regions": [{"uid": "test1","zorder": 1,"volume": 60,"x": 0,"y": 0,"w": 640,"h": 360},{"uid": "test2","zorder": 1,"volume": 80,"x": 640,"y": 0,"w": 640,"h": 360}],"ver": "1.0","ts": 1648544726}
字段名称 | 描述 |
SdkAppId | TRTC 的 SdkAppId |
TaskId | 转推任务唯一的 String Id |
xxxxx.livepush.myqcloud.com
,其中 xxxxx 是一个数字,叫做 bizid。.liveplay.myqcloud.com
为后缀)。CNAME 域名不能直接访问,您需要在域名服务提供商处完成 CNAME 配置,配置生效后,即可享受云直播服务。具体操作请参见 CNAME 配置。xxxxx.livepush.myqcloud.com
的推流域名,该域名为腾讯云直播服务和 TRTC 服务之间约定的一个默认推流域名。enterRoom
函数的参数 TRTCParams
中指定。enterRoom
函数的参数 TRTCParams
中指定。拼装 | 2020年01月09日及此后新建的应用 | 2020年01月09日前创建且使用过的应用 |
拼装规则 | streamId = urlencode(sdkAppId_roomId_userId_streamType) | streamId = bizid_MD5(roomId_userId_streamType) |
计算样例 | 例如:sdkAppId = 12345678,roomId = 12345,userId = userA,用户当前使用了摄像头。那么:streamId = 12345678_12345_userA_main | 例如:bizid = 1234,roomId = 12345,userId = userA,用户当前使用了摄像头。那么:streamId = 1234_MD5(12345_userA_main) = 1234_8D0261436C375BB0DEA901D86D7D70E8 |
Application
/ - [AppDelegate application:didFinishLaunchingWithOptions:]
中)进行如下设置:public class MApplication extends Application {@Overridepublic void onCreate() {super.onCreate();String licenceURL = ""; // 获取到的 licence urlString licenceKey = ""; // 获取到的 licence keyV2TXLivePremier.setLicence(this, licenceURL, licenceKey);V2TXLivePremier.setObserver(new V2TXLivePremierObserver() {@Overridepublic void onLicenceLoaded(int result, String reason) {Log.i(TAG, "onLicenceLoaded: result:" + result + ", reason:" + reason);}});}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {NSString * const licenceURL = @"<获取到的licenseUrl>";NSString * const licenceKey = @"<获取到的key>";// V2TXLivePremier 位于 "V2TXLivePremier.h" 头文件中[V2TXLivePremier setLicence:licenceURL key:licenceKey];[V2TXLivePremier setObserver:self];NSLog(@"SDK Version = %@", [V2TXLivePremier getSDKVersionStr]);return YES;}#pragma mark - V2TXLivePremierObserver- (void)onLicenceLoaded:(int)result Reason:(NSString *)reason {NSLog(@"onLicenceLoaded: result:%d reason:%@", result, reason);}@end
http://播放域名/AppName(默认live)/StreamName(流ID).flv
rtmp 协议的播放地址:rtmp://example.myhost.com/AppName_example/StreamName_exampleflv 协议的播放地址:http://example.myhost.com/AppName_example/StreamName_example.flvhls 协议的播放地址:http://example.myhost.com/AppName_example/StreamName_example.m3u8
旁路流类型 | V2TXLivePlayer 的播放模式 | 平均延时 | 实测效果 |
独立画面 | 极速模式(推荐) | 2s - 3s | 下图中左侧对比图(橙色) |
混合画面 | 极速模式(推荐) | 4s - 5s | 下图中右侧对比图(蓝色) |
//自动模式[_txLivePlayer setCacheParams:1 maxTime:5];//极速模式[_txLivePlayer setCacheParams:1 maxTime:1];//流畅模式[_txLivePlayer setCacheParams:5 maxTime:5];//设置完成之后再启动播放
startPublishMediaStream
)的主播退出了房间stopPublishMediaStream
主动停止混流onCdnStreamStateChanged
回调获取最新的后台任务状态更新回调。更多细节可参考 API 文档。taskid
发起 updatePublishMediaStream
推流任务变更即可。但是为了确保推流链接稳定,从单路推流切换到混流推流无法切换到纯音频或者纯视频模式。单路推流默认是音视频模式,切换后的混流也需要是音视频模式。TRTCStreamEncodeParam
里音频相关参数不要设置且 TRTCStreamMixingConfig
里 audioMixUserList
设置为空。TRTCStreamMixingConfig
的 watermarkList
进行设置。更多细节可参考 API 文档。TRTCVideoLayout
的 fixedVideoStreamType
为 TRTCVideoStreamTypeSub
即可。
本页内容是否解决了您的问题?