// // YBLiveRTCManager.m // YBLive // // Created by ybRRR on 2023/1/29. // Copyright © 2023 cat. All rights reserved. // #import "YBLiveRTCManager.h" @interface YBLiveRTCManager () @property(nonatomic,strong)V2TXLiveVideoEncoderParam *txLiveVieoParam; @property(nonatomic,strong)V2TXLivePusher *txLivePusher; @property(nonatomic,strong)TXAudioEffectManager *audioEffect; @end @implementation YBLiveRTCManager static YBLiveRTCManager *_RTCManager = nil; +(instancetype)shareInstance{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _RTCManager = [[super allocWithZone:NULL]init]; }); return _RTCManager; } + (instancetype)allocWithZone:(struct _NSZone *)zone { return [self shareInstance]; } #pragma mark -初始化直播 txsdk -(void)initWithLiveMode:(V2TXLiveMode)liveMode andPushData:(NSDictionary *)pushDic{ //配置推流参数 _txLiveVieoParam = [[V2TXLiveVideoEncoderParam alloc]init]; int videoResolution = [minstr([pushDic valueForKey:@"resolution"]) intValue]; if (videoResolution <= 3) { _txLiveVieoParam.videoResolution =V2TXLiveVideoResolution640x360; } else if (videoResolution == 4){ _txLiveVieoParam.videoResolution =V2TXLiveVideoResolution960x540; } else if (videoResolution >= 5){ _txLiveVieoParam.videoResolution =V2TXLiveVideoResolution1280x720; } _txLiveVieoParam.videoFps = [minstr([pushDic valueForKey:@"fps"]) intValue]; _txLiveVieoParam.videoBitrate = [minstr([pushDic valueForKey:@"bitrate"]) intValue]; _txLiveVieoParam.minVideoBitrate = [minstr([pushDic valueForKey:@"bitrate_min"]) intValue]; _txLivePusher = [[V2TXLivePusher alloc]initWithLiveMode:V2TXLiveMode_RTC]; [_txLivePusher setVideoQuality:_txLiveVieoParam]; [_txLivePusher enableCustomVideoProcess:true pixelFormat:V2TXLivePixelFormatTexture2D bufferType:V2TXLiveBufferTypeTexture]; [_txLivePusher setEncoderMirror:YES]; [_txLivePusher startCamera:YES]; [_txLivePusher startMicrophone]; _audioEffect =[_txLivePusher getAudioEffectManager]; [_txLivePusher setObserver:self]; } #pragma mark -初始化语音聊天室 txsdk -(void)initWithChatLiveMode:(V2TXLiveMode)liveMode{ _txLivePusher = [[V2TXLivePusher alloc]initWithLiveMode:V2TXLiveMode_RTC]; [_txLivePusher startMicrophone]; _audioEffect =[_txLivePusher getAudioEffectManager]; [_txLivePusher setObserver:self]; } #pragma mark -开始推流 -(void)startPush:(NSString *)pusUrl{ [_txLivePusher startPush:pusUrl]; V2TXLiveCode pushCode = [_txLivePusher startPush:pusUrl]; if ([self.delegate respondsToSelector:@selector(ybPushLiveStatus:)]) { [self.delegate ybPushLiveStatus:pushCode]; } } #pragma mark -推流显示界面 -(void)setPushView:(UIView *)pushView{ [_txLivePusher setRenderView:pushView]; } #pragma mark -停止推流 -(void)stopPush{ // [_audioEffect stopPlayMusic:666]; [_txLivePusher stopCamera]; [_txLivePusher stopMicrophone]; [_txLivePusher stopPush]; V2TXLiveCode pushCode = [_txLivePusher stopPush]; if ([self.delegate respondsToSelector:@selector(ybPushLiveStatus:)]) { [self.delegate ybPushLiveStatus:pushCode]; } } #pragma mark -暂停推流 -(void)pausePush { [_txLivePusher pauseVideo]; } #pragma mark -恢复推流 -(void)resumePush { [_txLivePusher resumeVideo]; } #pragma mark -切换摄像头 -(void)changeCamera:(BOOL)isFront{ [_txLivePusher startCamera:isFront]; } #pragma mark -切换镜像 -(void)changeMirror:(BOOL)isMirror{ [_txLivePusher setEncoderMirror:isMirror]; } #pragma mark -闪光灯 -(void)cameraTorch:(BOOL)isTorch{ TXDeviceManager *deviceManager = [_txLivePusher getDeviceManager]; BOOL isTorSupported = [deviceManager isCameraTorchSupported]; if (isTorSupported) { [deviceManager enableCameraTorch:isTorch]; }else{ [MBProgressHUD showError:YZMsg(@"只有后置摄像头才能开启闪光灯")]; } } #pragma mark -设置美颜 -(void)setBeautyLevel:(float)beautyLevel WhitenessLevel:(float)whitenessLevel IsTXfiter:(NSString *)isTXfiter{ TXBeautyManager *beautyManager = [_txLivePusher getBeautyManager]; if ([isTXfiter isEqual:@"1"]) { beautyLevel = 9; whitenessLevel = 3; } [beautyManager setBeautyStyle:0]; [beautyManager setBeautyLevel:beautyLevel]; [beautyManager setWhitenessLevel:whitenessLevel]; [beautyManager setRuddyLevel:0]; } -(void)setBeautyLevel:(float)beautyLevel WhitenessLevel:(float)whitenessLevel { TXBeautyManager *beautyManager = [_txLivePusher getBeautyManager]; [beautyManager setBeautyStyle:0]; [beautyManager setBeautyLevel:beautyLevel]; [beautyManager setWhitenessLevel:whitenessLevel]; [beautyManager setRuddyLevel:0]; } #pragma mark -设置大眼级别 -(void)setYBEyeScaleLevel:(float)eyeScaleLevel{ TXBeautyManager *beautyManager = [_txLivePusher getBeautyManager]; [beautyManager setEyeScaleLevel:eyeScaleLevel]; } #pragma mark -设置瘦脸级别 -(void)setYBFaceScaleLevel:(float)faceSlimLevel{ TXBeautyManager *beautyManager = [_txLivePusher getBeautyManager]; [beautyManager setFaceSlimLevel:faceSlimLevel]; } #pragma mark -设置红润级别 -(void)setYBRuddyLevel:(float)ruddyLevel{ TXBeautyManager *beautyManager = [_txLivePusher getBeautyManager]; [beautyManager setRuddyLevel:ruddyLevel]; } #pragma mark -背景音乐音量 -(void)setYBBGMVolume:(float)bgmVolume{ [_audioEffect setMusicPublishVolume:666 volume:bgmVolume]; } #pragma mark -设置色彩滤镜效果 -(void)setYBFilter:(UIImage *)image{ TXBeautyManager *beautyManager = [_txLivePusher getBeautyManager]; [beautyManager setFilter:image]; } #pragma mark -播放音乐 -(void)playBGMWithPath:(NSString *)musicPath{ TXAudioMusicParam *musicPar = [[TXAudioMusicParam alloc]init]; musicPar.ID = 666; musicPar.path = musicPath; musicPar.publish = YES; [_audioEffect setAllMusicVolume:60];//设置音量大小 [_audioEffect startPlayMusic:musicPar onStart:^(NSInteger errCode) { if(errCode == 0){ if([self.delegate respondsToSelector:@selector(playMusicBegin)]){ [self.delegate playMusicBegin]; } } } onProgress:^(NSInteger progressMs, NSInteger durationMs) { if([self.delegate respondsToSelector:@selector(playMusicProgress:Duration:)]){ [self.delegate playMusicProgress:progressMs Duration:durationMs]; } } onComplete:^(NSInteger errCode) { }]; } #pragma mark -停止播放音乐 -(void)stopBGM{ [_audioEffect stopPlayMusic:666]; } #pragma mark -发起云端混流 -(void)MixTranscoding:(V2TXLiveTranscodingConfig *)config; { V2TXLiveCode hunliuCode = [_txLivePusher setMixTranscodingConfig:config]; NSLog(@"ybliveRtcHunliu----:%ld",hunliuCode); } #pragma mark --直播推流监听 /** * 直播推流器错误通知,推流器出现错误时,会回调该通知 * * @param code 错误码 {@link V2TXLiveCode}。 * @param msg 错误信息。 * @param extraInfo 扩展信息。 */ - (void)onError:(V2TXLiveCode)code message:(NSString *)msg extraInfo:(NSDictionary *)extraInfo; { NSLog(@"rtcManager Error ==:%ld =msg=:%@ =dic=%@",code,msg,extraInfo); } /** * 麦克风采集音量值回调 * * @param volume 音量大小。 * @note 调用 {@link enableVolumeEvaluation} 开启采集音量大小提示之后,会收到这个回调通知。 */ - (void)onMicrophoneVolumeUpdate:(NSInteger)volume{ } /** * 推流器连接状态回调通知 * * @param status 推流器连接状态 {@link V2TXLivePushStatus}。 * @param msg 连接状态信息。 * @param extraInfo 扩展信息。 */ - (void)onPushStatusUpdate:(V2TXLivePushStatus)status message:(NSString *)msg extraInfo:(NSDictionary *)extraInfo; { if([self.delegate respondsToSelector:@selector(ybRTCPushStatusUpdate:message:extraInfo:)]){ [self.delegate ybRTCPushStatusUpdate:status message:msg extraInfo:extraInfo]; } } /** * 直播推流器统计数据回调 * * @param statistics 推流器统计数据 {@link V2TXLivePusherStatistics} */ - (void)onStatisticsUpdate:(V2TXLivePusherStatistics *)statistics; { } -(void)onWarning:(V2TXLiveCode)code message:(NSString *)msg extraInfo:(NSDictionary *)extraInfo { if (code == V2TXLIVE_WARNING_NETWORK_BUSY) { if ([self.delegate respondsToSelector:@selector(ybPushLiveStatus:)]) { [self.delegate ybPushLiveStatus:code]; } } } #pragma mark -美狐回调 -(void)onProcessVideoFrame:(V2TXLiveVideoFrame *)srcFrame dstFrame:(V2TXLiveVideoFrame *)dstFrame { if([self.delegate respondsToSelector:@selector(MHBeautyBlock:dstFrame:)]){ [self.delegate MHBeautyBlock:srcFrame dstFrame:dstFrame]; } } -(void)onGLContextDestroyed { if([self.delegate respondsToSelector:@selector(destoryMHBeauty)]){ [self.delegate destoryMHBeauty]; } } @end