Files
featherVoice/QXLive/Manager/QXAgoraEngine.m
2025-11-04 09:13:09 +08:00

865 lines
35 KiB
Objective-C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// LNAgoraEngine.m
// SoundRiver
//
// Created by ln007 on 2019/8/29.
//
#import "QXAgoraEngine.h"
#import "QXRoomMessageManager.h"
#import "QXAgoraEngineEx.h"
#import <ReplayKit/ReplayKit.h>
@interface QXAgoraEngine ()<AgoraRtcEngineDelegate,AgoraMusicContentCenterEventDelegate,AgoraRtcMediaPlayerDelegate>
@property (nonatomic , strong) NSString *currentChannel;
@property (nonatomic , assign) NSUInteger currentUid;
@property (nonatomic , assign) NSInteger page;
@property (nonatomic , strong) QXSongListModel* songModel;
@property (nonatomic , strong)NSMutableArray *bgMusicArray;
@property (nonatomic , strong)AgoraScreenCaptureParameters2 *screenParams;
@property (nonatomic , strong)RPSystemBroadcastPickerView *systemBroadcastPicker;
@property (nonatomic , strong)AgoraRtcChannelMediaOptions *option;
@property (nonatomic , assign) BOOL isOpenMic;
@property(nonatomic, assign) double renshengRatio;
@property(nonatomic, assign) double playerRatio;
@property (nonatomic, assign)AgoraAudioEffectPreset currentVoiceStyle;
@end
@implementation QXAgoraEngine
+(instancetype)sharedEngine {
static dispatch_once_t onceToken;
static QXAgoraEngine *instance;
dispatch_once(&onceToken, ^{
instance = [[QXAgoraEngine alloc] init];
});
if (!instance.agoraKit) {
[instance initializeAgoraEngine];
}
return instance;
}
//初始化
- (void)initializeAgoraEngine {
self.renshengRatio = 0.5;
self.playerRatio = 0.5;
self.currentVoiceStyle = AgoraAudioEffectPresetOff;
self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:AgoraAuthId delegate:self];
[self.agoraKit enableAudioVolumeIndication:200 smooth:3 reportVad:NO];
[self.agoraKit getCurrentMonotonicTimeInMs];
[self.agoraKit setAudioProfile:AgoraAudioProfileMusicHighQualityStereo];
[self.agoraKit setAudioScenario:AgoraAudioScenarioChorus];
[self setChannelProfile];
self.agoraKit.delegate = self;
[self.agoraKit setParameters:@"{\"che.audio.custom_payload_type\":73}"];
[self.agoraKit setParameters:@"{\"che.audio.custom_bitrate\":128000}"];
[self.agoraKit setParameters:@"{\"rtc.enable_nasa2\": true}"];
[self.agoraKit setParameters:@"{\"rtc.use_audio4\": true}" ];
[self.agoraKit enableVideo];
[self.agoraKit enableAudio];
AgoraVideoEncoderConfiguration *encoderConfig = [[AgoraVideoEncoderConfiguration alloc] initWithSize:CGSizeMake(960, 540)
frameRate:(AgoraVideoFrameRateFps15)
bitrate:AgoraVideoBitrateStandard
orientationMode:(AgoraVideoOutputOrientationModeFixedPortrait)
mirrorMode:(AgoraVideoMirrorModeAuto)];
[self.agoraKit setVideoEncoderConfiguration:encoderConfig];
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurError:(AgoraErrorCode)errorCode{
QXLOG(@"声网状态---%ld",errorCode)
}
//设置频道模式为直播
- (void)setChannelProfile {
[self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
}
//加入直播频道
- (void)joinChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString*)agora_token agora_rtm_token:(NSString*)agora_rtm_token isUpSeat:(BOOL)isUpSeat successBock:(nonnull void (^)(void))successBock{
if (isUpSeat) {
self.option.clientRoleType = AgoraClientRoleBroadcaster;
}else{
self.option.clientRoleType = AgoraClientRoleAudience;
}
if (_currentChannel.length > 0) {
if (![_currentChannel isEqualToString:channelId]) {
[self switchToChannel:channelId withRoom:chatRoom agora_token:agora_token agora_rtm_token:agora_rtm_token isUpSeat:isUpSeat successBock:successBock];
}
}else{
__weak typeof(self)weakSelf = self;
[self.agoraKit joinChannelByToken:agora_token channelId:channelId uid:QXGlobal.shareGlobal.loginModel.user_id.longLongValue mediaOptions:self.option joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
[weakSelf onInitKTVCenterWithToken:agora_rtm_token];
[weakSelf muteLocalAudioStream:YES];
[weakSelf muteAllRemoteAudioStreams:NO];
self.option.publishMicrophoneTrack = YES;
self.option.publishMediaPlayerAudioTrack = YES;
self.option.enableAudioRecordingOrPlayout = YES;
self.option.publishMediaPlayerId = [self->_ktvPlayer getMediaPlayerId];
[self.agoraKit updateChannelWithMediaOptions:self.option];
// 当远端用户加入频道后,显示指定 uid 的远端视频流
if (successBock) {
successBock();
}
}];
}
}
//- (void)joinExChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString*)agora_token agora_rtm_token:(NSString*)agora_rtm_token successBock:(void(^)(void))successBock{
// [self.agoraKit joinChannelExByToken:<#(NSString * _Nullable)#> channelId:<#(NSString * _Nonnull)#> userAccount:<#(NSString * _Nonnull)#> delegate:<#(id<AgoraRtcEngineDelegate> _Nullable)#> mediaOptions:<#(AgoraRtcChannelMediaOptions * _Nonnull)#> joinSuccess:<#^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed)joinSuccessBlock#>]
//}
//切换用户角色
/*
该方法在加入频道前后都可以调用:
加入直播频道前,调用该方法将用户设置为主播或观众。
直播过程中,调用该方法将用户角色由观众切换为主播(上麦),或由主播切换为观众。
*/
- (void)setClientRoleBroadcaster:(BOOL)isBroadcaster {
[self.agoraKit setClientRole:isBroadcaster ? AgoraClientRoleBroadcaster : AgoraClientRoleAudience];
}
- (void)rtcEngine:(AgoraRtcEngineKit * _Nonnull)engine tokenPrivilegeWillExpire:(NSString *_Nonnull)token{
// [self.agoraKit renewToken:<#(NSString * _Nonnull)#>]
}
//离开频道
-(void)leaveChannel {
int result = [self.agoraKit leaveChannel:^(AgoraChannelStats * _Nonnull stat) {
QXLOG(@"声网进入退出频道回调");
}];
QXLOG(@"声网退出频道result---------%@",result);
//需要退出聊天室
self.chatRoom = nil;
self.currentChannel = nil;
}
//切换频道
- (void)switchToChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString *)agora_token agora_rtm_token:(NSString *)agora_rtm_token isUpSeat:(BOOL)isUpSeat successBock:(void (^)(void))successBock{
__weak typeof(self)weakSelf = self;
[self.agoraKit leaveChannel:^(AgoraChannelStats * _Nonnull stat) {
[self.agoraKit joinChannelByToken:agora_token channelId:channelId uid:QXGlobal.shareGlobal.loginModel.user_id.longLongValue mediaOptions:self.option joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
[weakSelf onInitKTVCenterWithToken:agora_rtm_token];
[weakSelf muteLocalAudioStream:YES];
[weakSelf muteAllRemoteAudioStreams:NO];
AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
option.publishMicrophoneTrack = YES;
option.publishMediaPlayerAudioTrack = YES;
option.enableAudioRecordingOrPlayout = YES;
option.publishMediaPlayerId = [self->_ktvPlayer getMediaPlayerId];
[self.agoraKit updateChannelWithMediaOptions:option];
if (successBock) {
successBock();
}
}];
}];
}
//销毁
- (void)destroyEngine
{
if (!self.agoraKit) {
return;
}
[AgoraRtcEngineKit destroy];
self.agoraKit = nil;
[self.ktvAmcc destroyMusicPlayer:_ktvPlayer];
_ktvPlayer = nil;
[self.ktvAmcc registerEventDelegate:nil];
[AgoraMusicContentCenter destroy];
self.ktvAmcc = nil;
self.isOpenMic = NO;
}
//禁麦
- (void)muteLocalAudioStream:(BOOL)mute
{
// [self.agoraKit enableLocalAudio:!mute];
// if ([self.songModel.user_id isEqualToString:QXGlobal.shareGlobal.loginModel.user_id]) {
// /// 当前唱歌者为自己时 只是停止声音监听
// [self.agoraKit muteRecordingSignal:mute];
// }else{
// [self.agoraKit muteRecordingSignal:mute];
// [self.agoraKit muteLocalAudioStream:mute];
// }
int result = [self.agoraKit muteLocalAudioStream:mute];
QXLOG(@"音频模块禁麦---%d",result);
// [self setClientRoleBroadcaster:!mute];
// [self.agoraKit muteRecordingSignal:mute];
}
-(void)enableAudio:(BOOL)enble{
self.isOpenMic = enble;
int result = [self.agoraKit enableLocalAudio:enble];
QXLOG(@"音频模块启动---%d",result);
}
//切换为耳机播放
- (int)setEnableSpeakerphone:(BOOL)enableSpeaker
{
return [self.agoraKit setEnableSpeakerphone:enableSpeaker];
}
- (BOOL)isSpeakerphoneEnabled
{
return [self.agoraKit isSpeakerphoneEnabled];
}
- (int)muteAllRemoteAudioStreams:(BOOL)mute
{
return [self.agoraKit muteAllRemoteAudioStreams:mute];
}
- (int)startAudioMixing:(NSString * _Nonnull)filePath
loopback:(BOOL)loopback
replace:(BOOL)replace
cycle:(NSInteger)cycle
{
// self.isPlay = YES;
return [self.agoraKit startAudioMixing:filePath loopback:loopback cycle:cycle startPos:0];
}
- (int)paseAudioMixing{
// self.isPlay = NO;
return [self.agoraKit pauseAudioMixing];
}
- (int)stopAudioMixing{
// self.isPlay = NO;
return [self.agoraKit stopAudioMixing];
}
- (int)resumeAudioMixing{
// self.isPlay = YES;
return [self.agoraKit resumeAudioMixing];
}
- (int)adjustAudioMixingVolume:(NSInteger)volume{
return [self.agoraKit adjustAudioMixingVolume:volume];
}
- (double)getEffectsVolume{
return [self.agoraKit getEffectsVolume];
}
#pragma mark-用户信息管理
- (void)registerLocalUserAccount
{
[self.agoraKit registerLocalUserAccount:@"" appId:AgoraAuthId];
}
- (void)RequestMusicURLData:(NSString *)MusicID{
// LNNetworkAPI *api = [[LNNetworkAPI alloc] initWithUrl:@"api/Song/index" parameters:@{@"input":MusicID,@"filter":@"name",@"type":@"netease",@"page":@"1"}];
// [api startRequestWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request, NSDictionary * _Nonnull result) {
// if ([result[@"status"] integerValue] == 1) {
//
// NSArray *DataDic = result[@"data"];
// NSDictionary *dic = DataDic[0];
//
// NSString * filePath = [dic objectForKey:@"url"];
//
// BOOL loopback = NO;
// BOOL replace = NO;
// NSInteger cycle = 1;
//
//
// // 开始播放混音
// [self.agoraKit startAudioMixing: filePath loopback: loopback replace: replace cycle: cycle];
//
// }else{
// [SRToastTool showTips:result[@"info"]];
// }
// } failure:^(__kindof YTKBaseRequest * _Nonnull request, NSString * _Nonnull errorInfo) {
// [SRToastTool showError:errorInfo];
// }];
}
#pragma mark-Enginedelegate
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didLeaveChannelWithStats:(AgoraChannelStats *)stats
{
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine localAudioStateChanged:(AgoraAudioLocalState)state reason:(AgoraAudioLocalReason)reason{
QXLOG(@"%lu",(unsigned long)state);
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine audioMixingStateChanged:(AgoraAudioMixingStateType)state reasonCode:(AgoraAudioMixingReasonCode)reasonCode{
QXLOG(@"音乐播放状态改变%lu",(long)state);
switch (state) {
case AgoraAudioMixingStateTypePlaying:
{
}
break;
case AgoraAudioMixingStateTypePaused:
{
}
break;
case AgoraAudioMixingStateTypeStopped:
{
// if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineLocalAudioMixingDidFinish)]) {
// [self.delegate rtcEngineLocalAudioMixingDidFinish];
// return;
// }
}
break;
default:
break;
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid reason:(AgoraUserOfflineReason)reason{
// NSDictionary *parm = @{
// @"user_id":[NSNumber numberWithInteger:uid],
// @"is_online":[NSNumber numberWithBool:NO],
// };
// [[NSNotificationCenter defaultCenter] postNotificationName:noticeRoomUserOnlineStatusDidChanged object:parm];
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed{
// NSDictionary *parm = @{
// @"user_id":[NSNumber numberWithInteger:uid],
// @"is_online":[NSNumber numberWithBool:YES],
// };
// [[NSNotificationCenter defaultCenter] postNotificationName:noticeRoomUserOnlineStatusDidChanged object:parm];
}
/// 说话声音大小
-(void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray<AgoraRtcAudioVolumeInfo *> *)speakers totalVolume:(NSInteger)totalVolume{
// NSMutableDictionary *usersSoundLevels = [NSMutableDictionary dictionary];
// for (AgoraRtcAudioVolumeInfo *info in speakers) {
// if (info.uid == 0) {
// [usersSoundLevels setValue:@(info.volume) forKey:QXGlobal.shareGlobal.loginModel.user_id];
// }else{
// [usersSoundLevels setValue:@(info.volume) forKey:[NSString stringWithFormat:@"%lu",info.uid]];
// }
// }
// if (self.delegate && [self.delegate respondsToSelector:@selector(onRTCEngineRoomPublishSoundLevelUpdate:)]) {
// [self.delegate onRTCEngineRoomPublishSoundLevelUpdate:speakers];
// }
for (AgoraRtcAudioVolumeInfo *info in speakers) {
[[NSNotificationCenter defaultCenter] postNotificationName:noticeUserSpeak object:info];
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine remoteVideoStats:(AgoraRtcRemoteVideoStats *)stats{
NSLog(@"uid=%ld直播远端视频状态",stats.uid);
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoFrameOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed{
NSLog(@"uid=%ld直播远端视频首次加载",uid);
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoFirstLoadWithUid:size:)]) {
[self.delegate rtcEngineVideoFirstLoadWithUid:uid size:size];
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine videoSizeChangedOfSourceType:(AgoraVideoSourceType)sourceType uid:(NSUInteger)uid size:(CGSize)size rotation:(NSInteger)rotation{
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine remoteVideoStateChangedOfUid:(NSUInteger)uid state:(AgoraVideoRemoteState)state reason:(AgoraVideoRemoteReason)reason elapsed:(NSInteger)elapsed{
NSLog(@"uid=%ld---直播远端视频状态发生变化status=%ld",uid,state);
if (state == AgoraVideoRemoteStateStopped) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoDidStop:)]) {
[self.delegate rtcEngineVideoDidStop:uid];
}
}else if (state == AgoraVideoRemoteStateStarting) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoDidStart:)]) {
[self.delegate rtcEngineVideoDidStart:uid];
}
}else{
// if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoDidStart:)]) {
// [self.delegate rtcEngineVideoDidStart:uid];
// }
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine channelMediaRelayStateDidChange:(AgoraChannelMediaRelayState)state error:(AgoraChannelMediaRelayError)error{
NSLog(@"channelMediaRelayStateDidChange");
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine localVideoStateChangedOfState:(AgoraVideoLocalState)state reason:(AgoraLocalVideoStreamReason)reason sourceType:(AgoraVideoSourceType)sourceType{
NSLog(@"localVideoStateChangedOfState");
if (state == AgoraVideoLocalStateCapturing && sourceType == AgoraVideoSourceTypeScreen) {
self.option.publishScreenCaptureAudio = YES;
self.option.publishScreenCaptureVideo = YES;
self.option.publishCameraTrack = NO;
[self.agoraKit updateChannelWithMediaOptions:self.option];
}else if (state == AgoraVideoLocalStateStopped && sourceType == AgoraVideoSourceTypeScreen) {
[self.agoraKit stopScreenCapture];
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine audioMixingPositionChanged:(NSInteger)position{
}
//- (void)rtcEngineLocalAudioMixingDidFinish:(AgoraRtcEngineKit *_Nonnull)engine{
// if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineLocalAudioMixingDidFinish)]) {
// [self.delegate rtcEngineLocalAudioMixingDidFinish];
// return;
// }
// NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
// NSString *filePath = [cachePath stringByAppendingPathComponent:@"testPlist.plist"];
//
// NSMutableArray *MusicListArray = [NSMutableArray arrayWithContentsOfFile:filePath];
//
// NSInteger index = self.index;
// switch (self.playType) {
// case 0:
//
// break;
// case 1:
//
// index = MusicListArray.count - 1;
//
// index = arc4random() % index;
//
// break;
// case 2:
//
// if (index == MusicListArray.count - 1) {
// index = 0;
// }//如果不是最后一首下标加1
// else{
// index++;
// }
// break;
// default:
// break;
// }
//
// NSDictionary *dic = MusicListArray[index];
// NSString * filePathstr = [dic objectForKey:@"songid"];
// [self RequestMusicURLData:filePathstr];
//}
-(void)addBgMusic:(QXSongListModel *)music{
if (self.bgMusicArray.count == 0 && self.songModel == nil) {
[self.bgMusicArray addObject:music];
[self nextBgMusic];
}else{
[self.bgMusicArray addObject:music];
}
}
-(void)nextBgMusic{
if (self.bgMusicArray.count > 0) {
QXSongListModel *music = self.bgMusicArray.firstObject;
[self ktv_EndSing];
[self ktv_StartSing:YES withSong:music];
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineBackgroundMusicNextSong:)]) {
[self.delegate rtcEngineBackgroundMusicNextSong:music];
}
[self.bgMusicArray removeObject:self.songModel];
}else{
dispatch_async(dispatch_get_main_queue(), ^{
showToast(@"已经是最后一首了");
});
}
}
-(void)pausePlayMusic{
[self.ktvPlayer pause];
}
-(void)resumePlayMusic{
[self.ktvPlayer resume];
}
- (void)setUseMicrophone:(BOOL)useMicrophone {
_useMicrophone = useMicrophone;
[self.agoraKit adjustRecordingSignalVolume:useMicrophone ? 100 : 0];
}
- (void)onInitKTVCenterWithToken:(NSString*)token{
// 1.注册曲库并初始化 AgoraMusicContentCenter。
AgoraMusicContentCenterConfig *config = [AgoraMusicContentCenterConfig new];
// 填入已开启音乐内容中心项目的 App ID
config.appId = AgoraAuthId;
// 用户 ID该 ID 可以和你加入 RTC 频道时使用的 uid 一致,但不能为 0。
config.mccUid = QXGlobal.shareGlobal.loginModel.user_id.integerValue;
// 填入用于鉴权的 Token。
config.token = token;
// AgoraRtcEngineKit 实例。
config.rtcEngine = self.agoraKit;
_ktvAmcc = [AgoraMusicContentCenter sharedContentCenterWithConfig:config];
[_ktvAmcc registerEventDelegate:self];
//创建音乐播放器。如果你需要播放音乐内容中心的音乐资源,需要使用此播放器进行播放。
_ktvPlayer = [_ktvAmcc createMusicPlayerWithDelegate:self];
[self ktv_resetVoice];
}
- (void)ktv_DestoryKtvPlayer{
[_ktvPlayer stop];
self.songModel = nil;
// if (self.ktv_UpdatePlayBtnStatusBlock) {
// self.ktv_UpdatePlayBtnStatusBlock(NO);
// }
}
-(void)searchSongWithKeyword:(NSString *)keywords page:(NSInteger)page resultBlock:(nonnull SearchSongBlock)resultBlock{
self.searchSongBlock = resultBlock;
[_ktvAmcc searchMusicWithKeyWord:keywords page:page pageSize:20 jsonOption:nil];
}
//预加载回调
-(void)onPreLoadEvent:(NSString *)requestId songCode:(NSInteger)songCode percent:(NSInteger)percent lyricUrl:(NSString *)lyricUrl state:(AgoraMusicContentCenterPreloadState)state reason:(AgoraMusicContentCenterStateReason)reason{
if (state == AgoraMusicContentCenterPreloadStateOK) {
[_ktvPlayer stop];
NSInteger code = [_ktvPlayer openMediaWithSongCode:songCode startPos:0];
QXLOG(code==0?@"播放器打开成功":@"播放器打开失败");
}
}
//打开音乐资源回调
-(void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol>)playerKit didChangedToState:(AgoraMediaPlayerState)state reason:(AgoraMediaPlayerReason)reason{
if (state == AgoraMediaPlayerStateOpenCompleted) {
// [_ktvPlayer play];
if (self.isPlayBgMusic) {
/// 背景音乐无需获取歌词
return;
}
[_ktvAmcc getLyricWithSongCode:_songModel.song_code lyricType:1];
[_ktvAmcc getSongSimpleInfoWithSongCode:_songModel.song_code];
}else if (state == AgoraMediaPlayerStatePlayBackCompleted || state == AgoraMediaPlayerStatePlayBackAllLoopsCompleted || state == AgoraMediaPlayerStateStopped) {
}
}
//播放进度回调
-(void)AgoraRtcMediaPlayer:(id<AgoraRtcMediaPlayerProtocol>)playerKit didChangedToPosition:(NSInteger)positionMs atTimestamp:(NSTimeInterval)timestampMs{
if (playerKit.getPlayerState == AgoraMediaPlayerStatePlaying) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineSongProgress:)]) {
[self.delegate rtcEngineSongProgress:positionMs];
}
if (self.isPlayBgMusic) {
return;
}
self.playPosition = positionMs;
NSDictionary *dict = @{
@"position":[NSNumber numberWithInteger:positionMs],
};
NSString *jsonStr = [dict jsonStringEncoded];
[[QXRoomMessageManager shared] sendChatMessage:jsonStr messageType:(QXRoomMessageTypeSongLrc) needInsertMessage:NO];
// if (self.roomInfo.is_xiangqin == 1){
// NSDictionary *body = @{@"messageType":@(BJIMMsgType_UpdateLyricPosition).stringValue,
// @"position":@(positionMs).stringValue
// };
// [[V2TIMManager sharedInstance] sendGroupCustomMessage:body.mj_JSONData to:_roomInfo.roomId priority:V2TIM_PRIORITY_NORMAL succ:^{
//
// } fail:^(int code, NSString *msg) {
// // 群聊文本消息发送失败
// }];
// }
}else if (playerKit.getPlayerState == AgoraMediaPlayerStatePlayBackAllLoopsCompleted) {
if (self.isPlayBgMusic) {
[self nextBgMusic];
return;
}
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine receiveStreamMessageFromUid:(NSUInteger)uid streamId:(NSInteger)streamId data:(NSData *)data{
NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *dict = [jsonStr jsonValueDecoded];
NSInteger positionMs = [[dict objectForKey:@"position"] integerValue];
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineSongProgress:)]) {
[self.delegate rtcEngineSongProgress:positionMs];
}
}
/// 收藏音乐
- (void)onMusicChartsResult:(NSString *)requestId result:(NSArray<AgoraMusicChartInfo *> *)result reason:(AgoraMusicContentCenterStateReason)reason{
}
/// 搜索回调
-(void)onMusicCollectionResult:(NSString *)requestId result:(AgoraMusicCollection *)result reason:(AgoraMusicContentCenterStateReason)reason{
if (self.searchSongBlock) {
self.searchSongBlock(result.musicList,result.page == 1);
}
}
/// 歌曲信息
-(void)onSongSimpleInfoResult:(NSString *)requestId songCode:(NSInteger)songCode simpleInfo:(NSString *)simpleInfo reason:(AgoraMusicContentCenterStateReason)reason{
}
-(void)onLyricResult:(NSString *)requestId songCode:(NSInteger)songCode lyricUrl:(NSString *)lyricUrl reason:(AgoraMusicContentCenterStateReason)reason{
NSLog(@"歌词地址回调-----%ld", reason);
dispatch_async(dispatch_get_main_queue(),^{
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineSongLrc:)]) {
[self.delegate rtcEngineSongLrc:lyricUrl];
}
});
}
-(void)ktv_LoadLrcWithSong:(QXSongListModel *)songModel{
// if ([_ktvAmcc isPreloadedWithSongCode:_songModel.song_code] < 0) {//未预加载
// [_ktvAmcc preloadWithSongCode:_songModel.song_code];
// }
_songModel = songModel;
if ([_ktvAmcc isPreloadedWithSongCode:_songModel.song_code] < 0) {//未预加载
[_ktvAmcc preloadWithSongCode:_songModel.song_code];
}else{
NSInteger result = [_ktvPlayer openMediaWithSongCode:_songModel.song_code startPos:0];
QXLOG(@"歌词---%ld",result);
}
}
-(void)ktv_StartSing:(BOOL)isStart withSong:(nonnull QXSongListModel *)songModel{
// if (_songModel) {
// [_ktvPlayer stop];
// }
if (songModel == nil) {
return;
}
_songModel = songModel;
if (isStart) {
if ([_ktvAmcc isPreloadedWithSongCode:_songModel.song_code] < 0) {//未预加载
[_ktvAmcc preloadWithSongCode:_songModel.song_code];
// [SVProgressHUD showWithStatus:@"歌曲预加载中,请稍候"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self ktv_StartSing:YES withSong:self->_songModel];
// [SVProgressHUD dismiss];
});
}else {
NSLog(@"getPlayerState : %ld",(long)[_ktvPlayer getPlayerState]);
if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStatePaused) {
NSInteger tag = [_ktvPlayer resume];
NSLog(@"内容中心继续---%ld", tag);
}else if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStateIdle) {
NSInteger tag = [_ktvPlayer openMediaWithSongCode:_songModel.song_code startPos:0];
// [SVProgressHUD showWithStatus:@"正在打开,请稍候"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self ktv_StartSing:YES withSong:self->_songModel];
// [SVProgressHUD dismiss];
});
NSLog(@"未打开---%ld", tag);
}else if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStateOpenCompleted) {
if (self.isPlayBgMusic) {
[self ktv_OriginalSingSetting:1];
}
NSInteger tag = [_ktvPlayer play];
NSLog(@"内容中心播放---%ld", tag);
}else if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStateStopped) {
NSInteger tag = [_ktvPlayer openMediaWithSongCode:_songModel.song_code startPos:0];
NSLog(@"内容中心播放---%ld", tag);
}else if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStatePlayBackAllLoopsCompleted) {
NSInteger tag = [_ktvPlayer openMediaWithSongCode:_songModel.song_code startPos:0];
NSLog(@"内容中心播放---%ld", tag);
}
}
} else {
NSInteger tag = [_ktvPlayer pause];
NSLog(@"内容中心暂停---%ld", tag);
}
if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStatePlaying) {
AgoraRtcChannelMediaOptions *options = [AgoraRtcChannelMediaOptions new];
options.autoSubscribeAudio = YES;
options.autoSubscribeVideo = YES;
options.publishMediaPlayerId = [_ktvPlayer getMediaPlayerId];
options.publishMediaPlayerAudioTrack = YES;
[self.agoraKit updateChannelWithMediaOptions:options];
}
}
-(void)ktv_EndSing{
// if ([_ktvPlayer getPlayerState] == AgoraMediaPlayerStatePlaying) {
// [_ktvPlayer stop];
// }
[_ktvPlayer stop];
_songModel = nil;
}
-(void)ktv_OriginalSingSetting:(BOOL)isOriginal {
//原唱0 伴奏1
[self.ktvPlayer selectAudioTrack:!isOriginal];
}
-(BOOL)ktv_GetErfan {
return self.isErfan;
}
-(void)ktv_SetErfan:(BOOL)isErfan {
self.isErfan = isErfan;
[self.agoraKit enableInEarMonitoring:isErfan];
}
//-(void)ktv_setVoiceEffert{
// [self.agoraKit setAudioEffectPreset:(AgoraAudioEffectPreset)];
//}
-(void)ktv_SetRenshengVolume:(float)ratio {
int volume = ratio*200;
self.renshengRatio = ratio;
// if (self.useMicrophone) {
[self.agoraKit adjustRecordingSignalVolume:volume];
// }
}
-(void)ktv_SetBanzouVolume:(float)ratio {
int volume = ratio*200;
self.playerRatio = ratio;
[self.ktvPlayer adjustPlayoutVolume:volume];
[self.ktvPlayer adjustPublishSignalVolume:volume/2];
}
-(float)ktv_GetBanzouVolume {
int volume = [self.ktvPlayer getPlayoutVolume];
// [self.agoraKit getAudioMixingPlayoutVolume];
return volume/100.0;
}
-(int)ktv_setAudioEffectPreset:(AgoraAudioEffectPreset)prese{
self.currentVoiceStyle = prese;
return [[QXAgoraEngine sharedEngine].agoraKit setAudioEffectPreset:prese];
}
-(void)ktv_resetVoice{
[self ktv_SetRenshengVolume:0.5];
[self ktv_SetBanzouVolume:0.5];
[self ktv_setAudioEffectPreset:AgoraAudioEffectPresetOff];
}
-(NSMutableArray *)bgMusicArray{
if (!_bgMusicArray) {
_bgMusicArray = [NSMutableArray array];
}
return _bgMusicArray;
}
- (AgoraScreenCaptureParameters2 *)screenParams {
if (_screenParams == nil) {
_screenParams = [[AgoraScreenCaptureParameters2 alloc] init];
_screenParams.captureAudio = YES;
_screenParams.captureVideo = YES;
AgoraScreenAudioParameters *audioParams = [[AgoraScreenAudioParameters alloc] init];
audioParams.captureSignalVolume = 50;
_screenParams.audioParams = audioParams;
AgoraScreenVideoParameters *videoParams = [[AgoraScreenVideoParameters alloc] init];
videoParams.dimensions = [self screenShareVideoDimension];
videoParams.frameRate = AgoraVideoFrameRateFps15;
videoParams.bitrate = AgoraVideoBitrateStandard;
// _screenParams.videoParams = videoParams;
}
return _screenParams;
}
- (CGSize)screenShareVideoDimension {
CGSize screenSize = UIScreen.mainScreen.bounds.size;
CGSize boundingSize = CGSizeMake(540, 960);
CGFloat mW = boundingSize.width / screenSize.width;
CGFloat mH = boundingSize.height / screenSize.height;
if (mH < mW) {
boundingSize.width = boundingSize.height / screenSize.height * screenSize.width;
} else if (mW < mH) {
boundingSize.height = boundingSize.width / screenSize.width * screenSize.height;
}
return boundingSize;
}
-(void)startScreenCapture{
// /// 更新
//// [self prepareSystemBroadcaster];
//
// AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
// option.publishMicrophoneTrack = YES;
// option.publishMediaPlayerAudioTrack = YES;
// option.enableAudioRecordingOrPlayout = YES;
// option.publishScreenCaptureVideo = YES;
// option.publishScreenCaptureAudio = YES;
// option.publishCameraTrack = NO;
// option.clientRoleType = AgoraClientRoleBroadcaster;
// [self.agoraKit updateChannelWithMediaOptions:option];
// [self.agoraKit startScreenCapture:self.screenParams];
// [self.agoraKit muteLocalVideoStream:NO];
// [self.agoraKit enableVideo];
// [self.agoraKit enableLocalVideo:YES];
// [self prepareSystemBroadcaster];
// for (UIView *view in self.systemBroadcastPicker.subviews) {
// if ([view isKindOfClass:[UIButton class]]) {
// [((UIButton *)view) sendActionsForControlEvents:(UIControlEventAllEvents)];
// break;
// }
// }
// AgoraVideoEncoderConfiguration *encoderConfig = [[AgoraVideoEncoderConfiguration alloc] initWithSize:CGSizeMake(960, 540)
// frameRate:(AgoraVideoFrameRateFps15)
// bitrate:AgoraVideoBitrateStandard
// orientationMode:(AgoraVideoOutputOrientationModeFixedPortrait)
// mirrorMode:(AgoraVideoMirrorModeAuto)];
// [self.agoraKit setVideoEncoderConfiguration:encoderConfig];
//
// // set up local video to render your local camera preview
// AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
// videoCanvas.uid = QXGlobal.shareGlobal.loginModel.user_id.longLongValue;
// // the view to be binded
//// videoCanvas.view = self.localView.videoView;
// videoCanvas.renderMode = AgoraVideoRenderModeHidden;
// [self.agoraKit setupLocalVideo:videoCanvas];
// // you have to call startPreview to see local video
// [self.agoraKit startPreview];
// [self.agoraKit enableAudio];
// [self.agoraKit enableVideo];
[self.agoraKit setScreenCaptureScenario:AgoraScreenScenarioVideo];
self.option.clientRoleType = AgoraClientRoleBroadcaster;
[self.agoraKit updateChannelWithMediaOptions:self.option];
[self.agoraKit startScreenCapture:self.screenParams];
[self prepareSystemBroadcaster];
for (UIView *view in self.systemBroadcastPicker.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
[((UIButton *)view) sendActionsForControlEvents:(UIControlEventAllEvents)];
break;
}
}
}
- (void)prepareSystemBroadcaster {
CGRect frame = CGRectMake(0, 0, 60, 60);
self.systemBroadcastPicker = [[RPSystemBroadcastPickerView alloc]initWithFrame:frame];
self.systemBroadcastPicker.showsMicrophoneButton = NO;
self.systemBroadcastPicker.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
self.systemBroadcastPicker.preferredExtension = [NSString stringWithFormat:@"%@.QXLiveScreen",bundleId];
}
-(void)startPreViewWithUid:(NSInteger)uid view:(nonnull UIView *)view{
AgoraRtcVideoCanvas* videoCanvas = [[AgoraRtcVideoCanvas alloc]init];
videoCanvas.uid = uid;
videoCanvas.view = view;
videoCanvas.renderMode = AgoraVideoRenderModeFit;
videoCanvas.setupMode = AgoraVideoViewSetupAdd;
[self.agoraKit setupRemoteVideo:videoCanvas];
}
- (AgoraRtcChannelMediaOptions *)option {
if (_option == nil) {
_option = [[AgoraRtcChannelMediaOptions alloc] init];
_option.clientRoleType = AgoraClientRoleAudience;
_option.publishCameraTrack = NO;
_option.publishMicrophoneTrack = YES;
_option.publishScreenCaptureVideo = NO;
_option.publishScreenCaptureAudio = NO;
}
return _option;
}
@end