覆盖羽声
This commit is contained in:
@@ -1,195 +0,0 @@
|
||||
//
|
||||
// LNAgoraEngine.h
|
||||
// SoundRiver
|
||||
//
|
||||
// Created by ln007 on 2019/8/29.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "QXSongListModel.h"
|
||||
#import <AgoraRtcKit/AgoraMusicContentCenter.h>
|
||||
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
|
||||
#import <AgoraRtcKit/AgoraRtcEngineKitEx.h>
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSInteger,PlayMusicTyper) {
|
||||
MusicSingle,
|
||||
MUsicRandomPlay,
|
||||
MusicListPlay
|
||||
};
|
||||
|
||||
typedef void(^SearchSongBlock)(NSArray<AgoraMusic *> *songList,BOOL isReload);
|
||||
@protocol QXAgoraEngineMediaPlayerDelegate <NSObject>
|
||||
/// 声浪回调
|
||||
- (void)onRTCEngineRoomPublishSoundLevelUpdate:(NSArray<AgoraRtcAudioVolumeInfo *> *)soundLevels;
|
||||
/// 播放器播放结束回调
|
||||
- (void)rtcEngineLocalAudioMixingDidFinish;
|
||||
/// 歌词回调
|
||||
- (void)rtcEngineSongLrc:(NSString*)lrcUrl;
|
||||
/// 歌曲进度回调
|
||||
- (void)rtcEngineSongProgress:(NSUInteger)progress;
|
||||
/// 背景音乐 下一首回调
|
||||
- (void)rtcEngineBackgroundMusicNextSong:(QXSongListModel*)songModel;
|
||||
/// 小黑屋电影首次加载
|
||||
- (void)rtcEngineVideoFirstLoadWithUid:(NSInteger)uid size:(CGSize)size;
|
||||
/// 小黑屋电影结束
|
||||
- (void)rtcEngineVideoDidStop:(NSInteger)uid;
|
||||
/// 开始
|
||||
- (void)rtcEngineVideoDidStart:(NSInteger)uid;
|
||||
@end
|
||||
|
||||
@interface QXAgoraEngine : NSObject
|
||||
@property (nonatomic , strong) AgoraRtcEngineKit *agoraKit;
|
||||
|
||||
@property (nonatomic,weak) id<QXAgoraEngineMediaPlayerDelegate>delegate;
|
||||
|
||||
@property (nonatomic , strong, nullable) UIViewController *chatRoom;
|
||||
|
||||
|
||||
|
||||
@property (nonatomic,copy)SearchSongBlock searchSongBlock;
|
||||
|
||||
@property (nonatomic , strong,readonly)QXSongListModel *songModel;
|
||||
|
||||
/// 存储已点歌曲
|
||||
@property (nonatomic , strong,readonly)NSMutableArray *bgMusicArray;
|
||||
/// 是否为播放背景音乐状态
|
||||
@property (nonatomic , assign)BOOL isPlayBgMusic;
|
||||
|
||||
// 循环/单曲/随机播放
|
||||
@property (nonatomic,assign)PlayMusicTyper playType;
|
||||
|
||||
@property (nonatomic , strong) AgoraMusicContentCenter *ktvAmcc;
|
||||
@property (nonatomic, strong) id<AgoraMusicPlayerProtocol> ktvPlayer;
|
||||
@property(nonatomic, assign) NSInteger playPosition;//播放进度
|
||||
@property(nonatomic, assign) BOOL isErfan;
|
||||
@property(nonatomic, assign) NSInteger renshengVolume;//采集音量,取值范围为 [0,400],默认100
|
||||
@property(nonatomic, assign) BOOL useMicrophone;
|
||||
|
||||
/// 当前是否为开麦状态
|
||||
@property(nonatomic, assign,readonly) BOOL isOpenMic;
|
||||
|
||||
|
||||
+ (instancetype)sharedEngine;
|
||||
|
||||
//加入频道
|
||||
- (void)joinChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString*)agora_token agora_rtm_token:(NSString*)agora_rtm_token isUpSeat:(BOOL)isUpSeat successBock:(void(^)(void))successBock;
|
||||
|
||||
//切换频道
|
||||
- (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;
|
||||
|
||||
// 点唱初始化
|
||||
- (void)onInitKTVCenterWithToken:(NSString*)token;
|
||||
|
||||
//离开频道
|
||||
-(void)leaveChannel;
|
||||
|
||||
/// 销毁
|
||||
- (void)destroyEngine;
|
||||
|
||||
//切换用户角色
|
||||
/*
|
||||
该方法在加入频道前后都可以调用:
|
||||
|
||||
加入直播频道前,调用该方法将用户设置为主播或观众。
|
||||
直播过程中,调用该方法将用户角色由观众切换为主播(上麦),或由主播切换为观众。
|
||||
*/
|
||||
- (void)setClientRoleBroadcaster:(BOOL)isBroadcaster;
|
||||
|
||||
//禁麦 不发送本地录音
|
||||
- (void)muteLocalAudioStream:(BOOL)mute;
|
||||
|
||||
/// 禁用音频
|
||||
- (void)enableAudio:(BOOL)enble;
|
||||
|
||||
//切换耳机和扬声器
|
||||
- (int)setEnableSpeakerphone:(BOOL)enableSpeaker;
|
||||
|
||||
//是否为扬声器
|
||||
- (BOOL)isSpeakerphoneEnabled;
|
||||
|
||||
//屏蔽远端声音
|
||||
- (int)muteAllRemoteAudioStreams:(BOOL)mute;
|
||||
|
||||
//设置混音效果
|
||||
- (int)startAudioMixing:(NSString * _Nonnull)filePath
|
||||
loopback:(BOOL)loopback
|
||||
replace:(BOOL)replace
|
||||
cycle:(NSInteger)cycle;
|
||||
- (int)paseAudioMixing;
|
||||
- (int)adjustAudioMixingVolume:(NSInteger)volume;
|
||||
|
||||
- (int)resumeAudioMixing;
|
||||
|
||||
- (double)getEffectsVolume;
|
||||
|
||||
- (int)stopAudioMixing;
|
||||
|
||||
|
||||
- (void)RequestMusicURLData:(NSString *)MusicID;
|
||||
|
||||
/// 添加背景音乐
|
||||
- (void)addBgMusic:(QXSongListModel *)music;
|
||||
/// 下一首
|
||||
- (void)nextBgMusic;
|
||||
/// 暂停
|
||||
- (void)pausePlayMusic;
|
||||
/// 重新开始
|
||||
- (void)resumePlayMusic;
|
||||
|
||||
|
||||
|
||||
/// 点歌房 //原唱0 伴奏1
|
||||
-(void)ktv_OriginalSingSetting:(BOOL)isOriginal;
|
||||
/// 销毁播放器
|
||||
- (void)ktv_DestoryKtvPlayer;
|
||||
/// 获取耳返状态
|
||||
-(BOOL)ktv_GetErfan;
|
||||
// 设置耳返
|
||||
-(void)ktv_SetErfan:(BOOL)isErfan;
|
||||
/// 开始播放
|
||||
-(void)ktv_StartSing:(BOOL)isStart withSong:(QXSongListModel*)songModel;
|
||||
/// 结束播放
|
||||
-(void)ktv_EndSing;
|
||||
/// 去加载歌词
|
||||
-(void)ktv_LoadLrcWithSong:(QXSongListModel*)songModel;
|
||||
/// 设置人声
|
||||
-(void)ktv_SetRenshengVolume:(float)ratio;
|
||||
/// 设置伴奏
|
||||
-(void)ktv_SetBanzouVolume:(float)ratio;
|
||||
/// 获取伴奏声音
|
||||
-(float)ktv_GetBanzouVolume;
|
||||
/// 搜索歌曲
|
||||
-(void)searchSongWithKeyword:(NSString *)keywords page:(NSInteger)page resultBlock:(SearchSongBlock)resultBlock;
|
||||
|
||||
//设置原声
|
||||
- (void)setLocalVoiceReverbOrginal;
|
||||
|
||||
//设置大叔
|
||||
- (void)setLocationVoiceChangerIsOldMan;
|
||||
|
||||
//设置正太
|
||||
- (void)setLocationVoiceChangerIsSmallMan;
|
||||
//设置萝莉
|
||||
- (void)setLocationVoiceChangerIsSmallGril;
|
||||
|
||||
//设置空灵
|
||||
- (void)setLocationVoiceChangerIsEmptiness;
|
||||
//设置演唱会
|
||||
|
||||
- (void)setLocalVoiceReverbSongSinger;
|
||||
//设置KTV
|
||||
- (void)setLocalVoiceReverbKTV;
|
||||
//设置录音棚
|
||||
- (void)setLocalVoiceReverbRecordingStudio;
|
||||
//播放音效
|
||||
@property (nonatomic, assign)NSInteger CurrentVoiceStyle;
|
||||
|
||||
|
||||
|
||||
-(void)startScreenCapture;
|
||||
|
||||
-(void)startPreViewWithUid:(NSInteger)uid view:(UIView*)view;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,845 +0,0 @@
|
||||
//
|
||||
// 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;
|
||||
@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.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{
|
||||
|
||||
}
|
||||
//设置频道模式为直播
|
||||
- (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 {
|
||||
[self.agoraKit leaveChannel:^(AgoraChannelStats * _Nonnull stat) {
|
||||
|
||||
}];
|
||||
//需要退出聊天室
|
||||
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];
|
||||
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 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];
|
||||
|
||||
}
|
||||
|
||||
- (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*400;
|
||||
self.renshengVolume = volume;
|
||||
// if (self.useMicrophone) {
|
||||
[self.agoraKit adjustRecordingSignalVolume:volume];
|
||||
// }
|
||||
}
|
||||
-(void)ktv_SetBanzouVolume:(float)ratio {
|
||||
int volume = ratio*100;
|
||||
[self.ktvPlayer adjustPlayoutVolume:volume];
|
||||
[self.ktvPlayer adjustPublishSignalVolume:volume];
|
||||
}
|
||||
-(float)ktv_GetBanzouVolume {
|
||||
int volume = [self.ktvPlayer getPlayoutVolume];
|
||||
// [self.agoraKit getAudioMixingPlayoutVolume];
|
||||
return volume/100.0;
|
||||
}
|
||||
|
||||
|
||||
-(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;
|
||||
}
|
||||
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
|
||||
@@ -1,23 +0,0 @@
|
||||
//
|
||||
// QXAgoraEngineEx.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/7/2.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
|
||||
#import <AgoraRtcKit/AgoraRtcEngineKitEx.h>
|
||||
#import "QXUserModel.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXAgoraEngineEx : NSObject
|
||||
+ (instancetype)sharedEngine;
|
||||
-(void)joinExWithAgora_token:(NSString*)agora_token channel:(NSString*)channel;
|
||||
- (void)muteLocalEXAudioStream:(BOOL)mute fromUserInfo:(QXUserHomeModel *)fromUserInfo;;
|
||||
|
||||
- (void)muteRemoteEXAudioStream:(BOOL)mute;
|
||||
-(void)quitEXChannelWithLastPkRoomId:(NSString*)last_pk_room_id;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,97 +0,0 @@
|
||||
//
|
||||
// QXAgoraEngineEx.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/7/2.
|
||||
//
|
||||
|
||||
#import "QXAgoraEngineEx.h"
|
||||
#import "QXAgoraEngine.h"
|
||||
@interface QXAgoraEngineEx()<AgoraRtcEngineDelegate>
|
||||
@property (nonatomic,strong)NSString*channel;
|
||||
@property (nonatomic,strong)AgoraRtcConnection *connection;
|
||||
@property (nonatomic,strong)AgoraRtcChannelMediaOptions *option;
|
||||
@end
|
||||
@implementation QXAgoraEngineEx
|
||||
|
||||
+(instancetype)sharedEngine {
|
||||
static dispatch_once_t onceToken;
|
||||
static QXAgoraEngineEx *instance;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[QXAgoraEngineEx alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
-(void)joinExWithAgora_token:(NSString*)agora_token channel:(NSString*)channel{
|
||||
// AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
|
||||
// option.publishMicrophoneTrack = YES;
|
||||
// option.publishMediaPlayerAudioTrack = YES;
|
||||
// option.enableAudioRecordingOrPlayout = YES;
|
||||
AgoraRtcConnection *connection = [[AgoraRtcConnection alloc] initWithChannelId:channel localUid:QXGlobal.shareGlobal.loginModel.user_id.longLongValue];
|
||||
_channel = channel;
|
||||
_connection = connection;
|
||||
MJWeakSelf
|
||||
int result = [[QXAgoraEngine sharedEngine].agoraKit joinChannelExByToken:agora_token connection:connection delegate:self mediaOptions:self.option joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
|
||||
[[QXAgoraEngine sharedEngine].agoraKit muteLocalAudioStreamEx:NO connection:connection];
|
||||
[[QXAgoraEngine sharedEngine].agoraKit muteAllRemoteAudioStreamsEx:NO connection:connection];;
|
||||
}];
|
||||
QXLOG(@"声网加入扩展流result---->%d",result)
|
||||
}
|
||||
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinChannel:(NSString *)channel withUid:(NSUInteger)uid elapsed:(NSInteger)elapsed{
|
||||
QXLOG(@"声网加入扩展流channel------ %@",channel);
|
||||
}
|
||||
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurError:(AgoraErrorCode)errorCode{
|
||||
QXLOG(@"声网加入扩展流errorCodel------ %ld",errorCode);
|
||||
}
|
||||
-(void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray<AgoraRtcAudioVolumeInfo *> *)speakers totalVolume:(NSInteger)totalVolume{
|
||||
for (AgoraRtcAudioVolumeInfo *info in speakers) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:noticeUserSpeak object:info];
|
||||
}
|
||||
}
|
||||
-(void)muteLocalEXAudioStream:(BOOL)mute fromUserInfo:(nonnull QXUserHomeModel *)fromUserInfo{
|
||||
// AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
|
||||
// option.publishMicrophoneTrack = mute?NO:YES;
|
||||
// option.publishMediaPlayerAudioTrack = mute?NO:YES;;
|
||||
// option.enableAudioRecordingOrPlayout = mute?NO:YES;;
|
||||
// option.clientRoleType = mute?AgoraClientRoleAudience:AgoraClientRoleBroadcaster;
|
||||
|
||||
// self.option.autoSubscribeAudio = mute?NO:YES;
|
||||
// self.option.autoSubscribeVideo = mute?NO:YES;
|
||||
// self.option.clientRoleType = mute?AgoraClientRoleAudience:AgoraClientRoleBroadcaster;
|
||||
// [[QXAgoraEngine sharedEngine].agoraKit updateChannelExWithMediaOptions:self.option connection:_connection];
|
||||
int result = [[QXAgoraEngine sharedEngine].agoraKit muteLocalAudioStreamEx:mute connection:_connection];
|
||||
// [[QXAgoraEngine sharedEngine].agoraKit muteRemoteAudioStream:fromUserInfo.user_id.integerValue mute:mute];
|
||||
QXLOG(@"声网停止ex频道推流result---->%d",result)
|
||||
}
|
||||
-(void)rtcEngine:(AgoraRtcEngineKit *)engine remoteAudioStateChangedOfUid:(NSUInteger)uid state:(AgoraAudioRemoteState)state reason:(AgoraAudioRemoteReason)reason elapsed:(NSInteger)elapsed{
|
||||
|
||||
}
|
||||
-(void)muteRemoteEXAudioStream:(BOOL)mute{
|
||||
int result = [[QXAgoraEngine sharedEngine].agoraKit muteAllRemoteAudioStreamsEx:mute connection:_connection];;
|
||||
|
||||
QXLOG(@"声网屏蔽远端声音result---->%d",result)
|
||||
|
||||
}
|
||||
|
||||
-(void)quitEXChannelWithLastPkRoomId:(NSString *)last_pk_room_id{
|
||||
if (_connection == nil) {
|
||||
_connection = [[AgoraRtcConnection alloc] initWithChannelId:last_pk_room_id localUid:QXGlobal.shareGlobal.loginModel.user_id.longLongValue];
|
||||
}
|
||||
int result = [[QXAgoraEngine sharedEngine].agoraKit leaveChannelEx:_connection leaveChannelBlock:^(AgoraChannelStats * _Nonnull stat) {
|
||||
|
||||
}];
|
||||
QXLOG(@"声网退出频道result---->%d",result)
|
||||
// [[QXAgoraEngine sharedEngine].agoraKit ];
|
||||
}
|
||||
-(AgoraRtcChannelMediaOptions *)option{
|
||||
if (!_option) {
|
||||
_option = [AgoraRtcChannelMediaOptions new];
|
||||
_option.publishMicrophoneTrack = YES;
|
||||
_option.publishMediaPlayerAudioTrack = YES;
|
||||
_option.enableAudioRecordingOrPlayout = YES;
|
||||
_option.clientRoleType = AgoraClientRoleBroadcaster;
|
||||
}
|
||||
return _option;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
+(UIColor*)themeColor;
|
||||
/// 获取按钮字体色
|
||||
+(UIColor*)btnTextColor;
|
||||
/// 主题色
|
||||
/// 背景图
|
||||
+(NSString*)backgroundImage;
|
||||
/// tabbar
|
||||
+(NSArray*)tabbarArray;
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
config.backgroundImage = @"app_bg";
|
||||
config.placehoulderTextColor = RGB16(0x9b9b9b);
|
||||
/// appstore
|
||||
config.themeColor = RGB16(0x0dffb9);
|
||||
config.btnTextColor = RGB16(0x333333);
|
||||
config.themeColor = RGB16(0x6C49E4);
|
||||
config.btnTextColor = RGB16(0xffffff);
|
||||
|
||||
// config.themeColor = RGB16(0xFC7285);
|
||||
// config.btnTextColor = RGB16(0xFFFFFF);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
//
|
||||
// QXFileManager.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/8.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXFileManager : NSObject
|
||||
///获取Documents目录路径
|
||||
+(NSString*)getDocumentPath;
|
||||
|
||||
///获取Library/Preferences目录路径
|
||||
+(NSString*)getLibraryPreferencesPath;
|
||||
|
||||
///获取Library/Caches路径
|
||||
+(NSString*)getLibraryCachesPath;
|
||||
|
||||
/// 获取tmp路径
|
||||
+(NSString*)getTmpPath;
|
||||
|
||||
/// 搜索历史记录问价写入
|
||||
+(BOOL)writeSearchHistoryWithContent:(NSString*)content;
|
||||
|
||||
///获取搜索历史
|
||||
+(NSArray<NSString*>*)getSearchHistory;
|
||||
|
||||
///删除历史记录
|
||||
+(BOOL)removeSearchHistory;
|
||||
|
||||
// 创建下载文件路径
|
||||
+ (NSString*)createLocalSourceVideoDirectory;
|
||||
// 获取文件下载路径
|
||||
+ (NSString*)getGiftVideoPath:(NSString*)videoName;
|
||||
// 检查文件是否存在
|
||||
+ (BOOL)isExistsFileWithFilePath:(NSString *)filePath;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,141 +0,0 @@
|
||||
//
|
||||
// QXFileManager.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/8.
|
||||
//
|
||||
|
||||
#import "QXFileManager.h"
|
||||
static NSString *separatorStr = @"$&";
|
||||
///导航历史文件
|
||||
static NSString *searhHistory = @"searhHistoty.txt";
|
||||
|
||||
/// path
|
||||
static NSString *QXVideoPlayerDownloadAtPath = @"GiftSource";
|
||||
@implementation QXFileManager
|
||||
+(NSString *)getDocumentPath{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
return documentsDirectory;
|
||||
}
|
||||
|
||||
+(NSString *)getLibraryPreferencesPath{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
|
||||
NSString *PreferenceDirectory = [paths objectAtIndex:0];
|
||||
return PreferenceDirectory;
|
||||
}
|
||||
|
||||
+(NSString *)getLibraryCachesPath{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *cacheDirectory = [paths objectAtIndex:0];
|
||||
return cacheDirectory;
|
||||
}
|
||||
|
||||
+(NSString *)getTmpPath{
|
||||
NSString*tmpPath = NSTemporaryDirectory();
|
||||
return tmpPath;
|
||||
}
|
||||
+ (NSString*)getSearchHistoryPath{
|
||||
NSString *dir = [NSString stringWithFormat:@"%@/Documents/SearchHistory", NSHomeDirectory()];
|
||||
BOOL isDir = NO;
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
BOOL existed = [fileManager fileExistsAtPath:dir isDirectory:&isDir];
|
||||
///文件夹已存在
|
||||
if (existed) {
|
||||
return dir;
|
||||
}
|
||||
BOOL result = NO;
|
||||
if (!(isDir == YES && existed == YES)){
|
||||
result =[fileManager createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
if (result) {
|
||||
return dir;
|
||||
}else{
|
||||
return @"";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+(BOOL)writeSearchHistoryWithContent:(NSString*)content{
|
||||
NSString *path = [QXFileManager getSearchHistoryPath];
|
||||
if (path.length == 0) {
|
||||
NSLog(@"文件夹创建失败");
|
||||
return NO;
|
||||
}
|
||||
NSString *filePath;
|
||||
NSString *str = @"";
|
||||
//获取历史搜索记录
|
||||
NSArray *historyArr = [self getSearchHistory];
|
||||
if ([historyArr containsObject:content]) {
|
||||
QXLOG(@"搜素已存在");
|
||||
return NO;
|
||||
}
|
||||
if (historyArr.count > 0) {
|
||||
//历史搜索记录为空
|
||||
str = [historyArr componentsJoinedByString:separatorStr];
|
||||
}
|
||||
//添加最新的搜索历史
|
||||
if (str.length == 0) {
|
||||
str = content;
|
||||
}else{
|
||||
str = [NSString stringWithFormat:@"%@%@%@",content,separatorStr,str];
|
||||
}
|
||||
|
||||
filePath = [path stringByAppendingPathComponent:searhHistory];
|
||||
|
||||
if (filePath.length == 0) {
|
||||
NSLog(@"文件路径为空");
|
||||
return NO;
|
||||
}
|
||||
|
||||
BOOL result = [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
if (result) {
|
||||
NSLog(@"写入文件成功");
|
||||
}else{
|
||||
NSLog(@"写入文件失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+(NSArray<NSString *> *)getSearchHistory{
|
||||
NSArray *arr;
|
||||
NSString *filePath = [NSString stringWithFormat:@"%@/Documents/SearchHistory", NSHomeDirectory()];
|
||||
filePath = [filePath stringByAppendingPathComponent:searhHistory];
|
||||
NSString *str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
|
||||
if (!str || str.length == 0) {
|
||||
return nil;
|
||||
}
|
||||
arr = [str componentsSeparatedByString:separatorStr];
|
||||
return arr;
|
||||
}
|
||||
|
||||
+(BOOL)removeSearchHistory{
|
||||
NSString *filePath = [NSString stringWithFormat:@"%@/Documents/SearchHistory", NSHomeDirectory()];
|
||||
filePath = [filePath stringByAppendingPathComponent:searhHistory];
|
||||
return [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
|
||||
}
|
||||
+ (NSString*)createLocalSourceVideoDirectory{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *cacheDirectory = [paths objectAtIndex:0];
|
||||
NSString*path = [cacheDirectory stringByAppendingPathComponent:QXVideoPlayerDownloadAtPath];
|
||||
if (![fileManager fileExistsAtPath:QXVideoPlayerDownloadAtPath]) {
|
||||
NSError *error = nil;
|
||||
BOOL ret = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
NSLog(@"文件夹创建是否成功=%u",ret);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
+ (NSString*)getGiftVideoPath:(NSString*)videoName{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *cacheDirectory = [paths objectAtIndex:0];
|
||||
NSString*path = [cacheDirectory stringByAppendingPathComponent:QXVideoPlayerDownloadAtPath];
|
||||
NSString *fileNamePath = [path stringByAppendingPathComponent:videoName];
|
||||
return fileNamePath;
|
||||
}
|
||||
+ (BOOL)isExistsFileWithFilePath:(NSString *)filePath {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
return [fileManager fileExistsAtPath:filePath];
|
||||
}
|
||||
@end
|
||||
@@ -1,61 +0,0 @@
|
||||
//
|
||||
// ManagerMqtt.h
|
||||
// SoundRiver
|
||||
//
|
||||
// Created by apple on 2020/3/19.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MQTTClient.h"
|
||||
#import "MQTTSessionManager.h"
|
||||
#import <CommonCrypto/CommonHMAC.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@protocol MQTTClientModelDelegate <NSObject>
|
||||
@optional
|
||||
- (void)MQTTClientModel_handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained;
|
||||
- (void)socketManager:(NSString *)socketManager receivedMessage:(NSDictionary *)message topic:(NSString *)topic;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface QXManagerMqtt : NSObject
|
||||
@property (nonatomic, assign) BOOL isDiscontent;
|
||||
@property (nonatomic, weak) id <MQTTClientModelDelegate> delegate;
|
||||
|
||||
@property (nonatomic,strong,nullable) MQTTSessionManager *mySessionManager;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
|
||||
- (void)bindWithUserName:(NSString *)username password:(NSString *)password cliendId:(NSString *)cliendId isSSL:(BOOL)isSSL;
|
||||
|
||||
- (void)disconnect;
|
||||
|
||||
- (void)reConnect;
|
||||
|
||||
/**
|
||||
订阅主题
|
||||
|
||||
@param topic 主题
|
||||
*/
|
||||
typedef void (^SubscribeTopicHandler)(NSString *topic, BOOL success);
|
||||
|
||||
- (void)subscribeTopic:(NSString *)topic;
|
||||
|
||||
/**
|
||||
取消订阅
|
||||
|
||||
@param topic 主题
|
||||
*/
|
||||
- (void)unsubscribeTopic:(NSString *)topic;
|
||||
|
||||
/**
|
||||
发布消息
|
||||
*/
|
||||
- (void)sendDataToTopic:(NSString *)topic dict:(NSDictionary *)dict;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,244 +0,0 @@
|
||||
//
|
||||
// ManagerMqtt.m
|
||||
// SoundRiver
|
||||
//
|
||||
// Created by apple on 2020/3/19.
|
||||
//
|
||||
|
||||
#import "QXManagerMqtt.h"
|
||||
|
||||
@interface QXManagerMqtt()<MQTTSessionManagerDelegate>
|
||||
@property (nonatomic, strong)NSString *username;
|
||||
@property (nonatomic, strong)NSString *password;
|
||||
@property (nonatomic, strong)NSString *cliendId;
|
||||
|
||||
//订阅的topic
|
||||
@property (nonatomic,strong) NSMutableDictionary *subedDict;
|
||||
|
||||
@property (nonatomic,assign) BOOL isSSL;
|
||||
|
||||
@end
|
||||
|
||||
@implementation QXManagerMqtt
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static dispatch_once_t onceToken;
|
||||
static QXManagerMqtt *sharedManager;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedManager = [[QXManagerMqtt alloc] init];
|
||||
});
|
||||
return sharedManager;
|
||||
}
|
||||
#pragma mark - 绑定
|
||||
- (void)bindWithUserName:(NSString *)username password:(NSString *)password cliendId:(NSString *)cliendId isSSL:(BOOL)isSSL{
|
||||
self.username = username;
|
||||
self.password = password;
|
||||
self.cliendId = cliendId;
|
||||
self.isSSL = isSSL;
|
||||
[self.mySessionManager connectTo:AddressOfMQTTServer
|
||||
port:AddressOfMQTTPort
|
||||
tls:self.isSSL
|
||||
keepalive:60
|
||||
clean:YES
|
||||
auth:YES
|
||||
user:self.username
|
||||
pass:self.password
|
||||
will:NO
|
||||
willTopic:nil
|
||||
willMsg:nil
|
||||
willQos:MQTTQosLevelAtMostOnce
|
||||
willRetainFlag:NO
|
||||
withClientId:self.cliendId
|
||||
securityPolicy:[self customSecurityPolicy]
|
||||
certificates:nil
|
||||
protocolLevel:MQTTProtocolVersion311
|
||||
connectHandler:^(NSError *error) {
|
||||
NSLog(@"mqtt connect - %@", error);
|
||||
// if (error == nil) {
|
||||
// [self subscribeTopic:@"qx_room_topic"];
|
||||
// }
|
||||
}];
|
||||
self.mySessionManager.subscriptions = self.subedDict;
|
||||
}
|
||||
|
||||
- (MQTTSSLSecurityPolicy *)customSecurityPolicy
|
||||
{
|
||||
MQTTSSLSecurityPolicy *securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeNone];
|
||||
|
||||
securityPolicy.allowInvalidCertificates = YES;
|
||||
securityPolicy.validatesCertificateChain = YES;
|
||||
securityPolicy.validatesDomainName = NO;
|
||||
return securityPolicy;
|
||||
}
|
||||
|
||||
#pragma mark ---- 状态
|
||||
|
||||
- (void)sessionManager:(MQTTSessionManager *)sessionManager didChangeState:(MQTTSessionManagerState)newState {
|
||||
switch (newState) {
|
||||
case MQTTSessionManagerStateConnected:
|
||||
QXLOG(@"eventCode -- 连接成功");
|
||||
[self subscribeTopic:@"qx_room_topic"];
|
||||
[self reConnectForStateError];
|
||||
|
||||
break;
|
||||
case MQTTSessionManagerStateConnecting:
|
||||
QXLOG(@"eventCode -- 连接中");
|
||||
|
||||
break;
|
||||
case MQTTSessionManagerStateClosed:
|
||||
QXLOG(@"eventCode -- 连接被关闭");
|
||||
break;
|
||||
case MQTTSessionManagerStateError:
|
||||
QXLOG(@"eventCode -- 连接错误");
|
||||
break;
|
||||
case MQTTSessionManagerStateClosing:
|
||||
QXLOG(@"eventCode -- 关闭中");
|
||||
|
||||
break;
|
||||
case MQTTSessionManagerStateStarting:
|
||||
QXLOG(@"eventCode -- 连接开始");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
- (void)sessionManager:(MQTTSessionManager *)sessionManager didReceiveMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained{
|
||||
|
||||
NSError *error;
|
||||
NSString *dataStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
|
||||
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"\\u" withString:@"u_u"];
|
||||
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"\\U" withString:@"U_U"];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"\\" withString:@""];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"\\" withString:@""];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"\\" withString:@""];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"\\" withString:@""];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"\"\"{" withString:@"\"{"];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"}\"\"" withString:@"}\""];
|
||||
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"\"{" withString:@"{"];
|
||||
dataStr=[dataStr stringByReplacingOccurrencesOfString:@"}\"" withString:@"}"];
|
||||
|
||||
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"U_U" withString:@"\\U"];
|
||||
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"u_u" withString:@"\\u"];
|
||||
//dataStr = [self replaceUnicode:dataStr];
|
||||
if(dataStr != nil){
|
||||
|
||||
QXLOG(@"收到消息%@",dataStr);
|
||||
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[dataStr dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];
|
||||
QXLOG(@"收到消息%@",dict);
|
||||
if (dict != nil && self.delegate && [self.delegate respondsToSelector:@selector(socketManager:receivedMessage:topic:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.delegate socketManager:@"收到消息" receivedMessage:dict topic:topic];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(NSString *)replaceUnicode:(NSString *)unicodeStr {
|
||||
|
||||
NSString *tempStr1 = [unicodeStr stringByReplacingOccurrencesOfString:@"\\u" withString:@"\\U"];
|
||||
// NSString *tempStr2 = [tempStr1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
|
||||
// NSString *tempStr3 = [[@"\"" stringByAppendingString:tempStr2] stringByAppendingString:@"\""];
|
||||
NSData *tempData = [tempStr1 dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString* returnStr = [NSPropertyListSerialization propertyListFromData:tempData
|
||||
mutabilityOption:NSPropertyListImmutable
|
||||
format:NULL
|
||||
errorDescription:NULL];
|
||||
// NSString* returnStr = [[NSString alloc]initWithData:tempData encoding:NSUTF8StringEncoding];
|
||||
|
||||
//NSLog(@"Output = %@", returnStr);
|
||||
|
||||
return [returnStr stringByReplacingOccurrencesOfString:@"\\r\\n" withString:@"\n"];
|
||||
}
|
||||
|
||||
#pragma mark - 订阅
|
||||
//- (void)subscribeTopic:(NSString *)topic handler:(SubscribeTopicHandler)handler{
|
||||
- (void)subscribeTopic:(NSString *)topic{
|
||||
|
||||
QXLOG(@"当前需要订阅-------- topic = %@",topic);
|
||||
|
||||
if (![self.subedDict.allKeys containsObject:topic]) {
|
||||
[self.subedDict setObject:[NSNumber numberWithLong:MQTTQosLevelAtLeastOnce] forKey:topic];
|
||||
QXLOG(@"订阅字典 ----------- = %@",self.subedDict);
|
||||
self.mySessionManager.subscriptions = self.subedDict;
|
||||
}else {
|
||||
QXLOG(@"已经存在,不用订阅");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 取消订阅
|
||||
- (void)unsubscribeTopic:(NSString *)topic {
|
||||
QXLOG(@"当前需要取消订阅-------- topic = %@",topic);
|
||||
if ([self.subedDict.allKeys containsObject:topic]) {
|
||||
[self.subedDict removeObjectForKey:topic];
|
||||
QXLOG(@"更新之后的订阅字典 ----------- = %@",self.subedDict);
|
||||
self.mySessionManager.subscriptions = self.subedDict;
|
||||
}
|
||||
else {
|
||||
QXLOG(@"不存在,无需取消");
|
||||
}
|
||||
}
|
||||
#pragma mark - 发布消息
|
||||
- (void)sendDataToTopic:(NSString *)topic dict:(NSDictionary *)dict {
|
||||
QXLOG(@"发送命令 topic = %@ dict = %@",topic,dict);
|
||||
|
||||
// [dict setValue:[QPCommonTool dateWithNowSp] forKey:@"time"];
|
||||
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
|
||||
[self.mySessionManager sendData:data topic:topic qos:MQTTQosLevelAtLeastOnce retain:NO];
|
||||
}
|
||||
#pragma mark MQTTSessionManagerDelegate
|
||||
- (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained {
|
||||
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(MQTTClientModel_handleMessage:onTopic:retained:)]) {
|
||||
[self.delegate MQTTClientModel_handleMessage:data onTopic:topic retained:retained];
|
||||
}
|
||||
}
|
||||
- (void)disconnect {
|
||||
[self.mySessionManager disconnectWithDisconnectHandler:^(NSError *error) {
|
||||
QXLOG(@"断开连接 error = %@",[error description]);
|
||||
}];
|
||||
[self.mySessionManager setDelegate:nil];
|
||||
[self.subedDict removeAllObjects];
|
||||
_mySessionManager = nil;
|
||||
}
|
||||
- (void)reConnect {
|
||||
if (self.mySessionManager && self.mySessionManager.port) {
|
||||
if (self.mySessionManager.state == MQTTSessionManagerStateConnected) {
|
||||
return;
|
||||
}
|
||||
self.mySessionManager.delegate = self;
|
||||
[self.mySessionManager connectToLast:^(NSError *error) {
|
||||
QXLOG(@"重新连接 error = %@",[error description]);
|
||||
}];
|
||||
self.mySessionManager.subscriptions = self.subedDict;
|
||||
|
||||
}else if ([self.username isExist] && [self.password isExist] && [self.cliendId isExist]) {
|
||||
[self bindWithUserName:self.username password:self.password cliendId:self.cliendId isSSL:self.isSSL];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//连接错误之后又连接成功之后
|
||||
- (void)reConnectForStateError{
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - 懒加载
|
||||
- (MQTTSessionManager *)mySessionManager {
|
||||
if (!_mySessionManager) {
|
||||
_mySessionManager = [[MQTTSessionManager alloc]init];
|
||||
_mySessionManager.delegate = self;
|
||||
}
|
||||
return _mySessionManager;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)subedDict {
|
||||
if (!_subedDict) {
|
||||
_subedDict = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return _subedDict;
|
||||
}
|
||||
@end
|
||||
@@ -1,221 +0,0 @@
|
||||
//
|
||||
// QXRoomMessageManager.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/6/10.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "QXRoomChatListView.h"
|
||||
#import "QXRoomModel.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger) {
|
||||
/// 清空消息
|
||||
QXRoomMessageTypeClearMessage = 123,
|
||||
/// 歌词同步
|
||||
QXRoomMessageTypeSongLrc = 124,
|
||||
/// pk屏蔽远端声音
|
||||
QXRoomMessageTypeMuteRemoteAudio = 125,
|
||||
/// 关闭自己声音
|
||||
QXRoomMessageTypeMuteLocalAudio = 126,
|
||||
/// 基础文本消息类型
|
||||
QXRoomMessageTypeText = 1,
|
||||
/// 系统消息
|
||||
QXRoomMessageTypeSystem = 1000,
|
||||
/// 用户进入房间
|
||||
QXRoomMessageTypeJoin = 1001,
|
||||
/// 用户退出房间
|
||||
QXRoomMessageTypeQuit = 1002,
|
||||
/// 用户上麦
|
||||
QXRoomMessageTypeUpSeat = 1003,
|
||||
/// 用户下麦
|
||||
QXRoomMessageTypeDownSeat = 1004,
|
||||
/// 房间收到礼物
|
||||
QXRoomMessageTypeGift = 1005,
|
||||
/// 设置管理员
|
||||
QXRoomMessageTypeSetManage = 1006,
|
||||
/// 设置主持
|
||||
QXRoomMessageTypeSetCompere = 1007,
|
||||
/// 禁麦/解禁
|
||||
QXRoomMessageTypeSeatMute = 1008,
|
||||
/// 锁麦/解除锁麦
|
||||
QXRoomMessageTypeSeatLock = 1009,
|
||||
/// 踢出房间
|
||||
QXRoomMessageTypeTakeOff = 1011,
|
||||
/// 房间类型发生变化
|
||||
QXRoomMessageTypeRoomTypeChanged = 1012,
|
||||
/// 点歌/切歌/同意点歌
|
||||
QXRoomMessageTypeSwicthSong = 1013,
|
||||
/// 上麦模式发生变化 自由麦 | 排麦
|
||||
QXRoomMessageTypeAplayPitModeDidChanged = 1014,
|
||||
/// pk房数值变化
|
||||
QXRoomMessageTypePKValueDidChanged = 1015,
|
||||
/// 用户 禁言|禁麦 ,解除禁言|解除禁麦
|
||||
QXRoomMessageTypeRoomUserMute = 1016,
|
||||
/// 管理员被删除
|
||||
QXRoomMessageTypeManagerIsDelete = 1017,
|
||||
/// 主持人被删除
|
||||
QXRoomMessageTypeCompereIsDelete = 1018,
|
||||
/// 点唱时魅力排行榜发生变化
|
||||
QXRoomMessageTypeCharmRankList = 1019,
|
||||
/// 房间信息发生变化是推送
|
||||
QXRoomMessageTypeRoomInfoChanged = 1020,
|
||||
/// 清除魅力
|
||||
QXRoomMessageTypeRoomClearCharm = 1021,
|
||||
/// 拍卖者上麦
|
||||
QXRoomMessageTypeRoomAuctionUpSeat = 1022,
|
||||
/// 拍卖开始 开始倒计时
|
||||
QXRoomMessageTypeRoomAuctionStart = 1023,
|
||||
/// 竞拍麦位发生变化
|
||||
QXRoomMessageTypeRoomAuctionPitChanged = 1024,
|
||||
/// 竞拍结束
|
||||
QXRoomMessageTypeRoomAuctionEnd = 1025,
|
||||
/// 竞拍主持延时
|
||||
QXRoomMessageTypeRoomAuctionDelayTime = 1026,
|
||||
/// 拍卖类型发生变化
|
||||
QXRoomMessageTypeRoomAuctionTypeDidChanged = 1027,
|
||||
/// 私密小屋
|
||||
QXRoomMessageTypeRoomCabinRoomValueChanged = 1028,
|
||||
/// 有人向我发起pk
|
||||
QXRoomMessageTypeRoomRecieveInvitePk = 1029,
|
||||
/// 拒绝或接受pk
|
||||
QXRoomMessageTypeRoomPKAgreeOrRefuse = 1030,
|
||||
/// pk开始
|
||||
QXRoomMessageTypeRoomPKStart = 1031,
|
||||
/// pk结束 惩罚时间
|
||||
QXRoomMessageTypeRoomPKEnd = 1032,
|
||||
/// pk断开
|
||||
QXRoomMessageTypeRoomPKDisconnect = 1033,
|
||||
/// 排麦人数发生变化
|
||||
QXRoomMessageTypeRoomInLineNumber = 1034,
|
||||
/// 用户信息发生变化时推送
|
||||
QXRoomMessageTypeRoomUserInfoDidChanged = 1035,
|
||||
/// 房间人数校正
|
||||
QXRoomMessageTypeRoomOnlineNumber = 1036,
|
||||
/// pk惩罚阶段失败方想跑路需要胜利方的同意
|
||||
QXRoomMessageTypeRoomPkNeedAgree = 1037,
|
||||
/// 房间盲盒开礼物文字消息
|
||||
QXRoomMessageTypeRoomBlindBox = 1038,
|
||||
/// 房间已被封禁
|
||||
QXRoomMessageTypeRoomDidFire = 1039,
|
||||
}QXRoomMessageType;
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@protocol QXRoomMessageManagerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
/// 插入消息
|
||||
-(void)didInsertMessge:(QXRoomChatListModel*)message;
|
||||
/// 根据用户userid 插入消息
|
||||
-(void)didInsertMessge:(QXRoomChatListModel*)message userId:(NSString*)userId;
|
||||
/// 上下麦
|
||||
-(void)didUpDownSeatWithUser:(QXUserHomeModel*)user isUpSeat:(BOOL)isUpSeat pit_number:(NSInteger)pit_number;
|
||||
/// 上麦模式发生变化 2 自由麦 | 1 排麦
|
||||
-(void)aplayPitModeDidChanged:(NSString*)upMicType;
|
||||
/// 排麦人数发生变化
|
||||
-(void)aplayMicInLineNumberDidChanged:(NSString*)number;
|
||||
/// 清空消息
|
||||
-(void)didClearAllMessage;
|
||||
/// 有人发起点歌
|
||||
-(void)applySongWaitAgreeWithUserNickname:(NSString*)nickname;
|
||||
/// 主持人拒绝点歌
|
||||
-(void)applySongNoAgreeWithUserId:(NSString*)userId;
|
||||
/// 下一首歌状态发生变化
|
||||
-(void)nextSongDidChangedWithNextSong:(QXSongListModel*)nextInfo;
|
||||
/// 切歌
|
||||
-(void)nextSongDidStartWithSongInfo:(QXSongListModel*)songInfo nextInfo:(QXSongListModel*)nextInfo;
|
||||
/// 点歌房魅力发生变化
|
||||
-(void)songRoomCharmRankListDidChanged:(NSArray<QXRoomPitModel *>*)list;
|
||||
/// 房间内用户信息发生变化
|
||||
-(void)roomUserInfoDidChanged:(QXUserHomeModel *)user;
|
||||
|
||||
|
||||
|
||||
/// 房间状态发生变化
|
||||
-(void)roomTypeDidChanged;
|
||||
/// 房间歌词
|
||||
- (void)roomSongLrcProgress:(NSUInteger)progress;
|
||||
/// 房间信息发生变化
|
||||
- (void)roomInfoDidChanged:(QXRoomInfoModel*)roomInfo;
|
||||
/// 房间管理员/主持人状态发生变化 isManager 是为管理员 否为主持 isAdd 是为添加 否为删除
|
||||
- (void)roomSetManagerOrCompere:(QXUserHomeModel*)userInfo isManager:(BOOL)isManager isAdd:(BOOL)isAdd;
|
||||
/// 踢出房间
|
||||
-(void)userDidTakeOffWithUserInfo:(QXUserHomeModel*)userInfo;
|
||||
/// 清除魅力
|
||||
-(void)roomClearCharm;
|
||||
/// 收到礼物
|
||||
-(void)didRecieveGiftWithWithUserInfo:(QXUserHomeModel*)userInfo;
|
||||
/// 用户禁言禁麦状态发生变化
|
||||
-(void)userMuteStatusDidChanged:(QXUserHomeModel*)userInfo isMute:(NSString*)isMute isMutePit:(NSString*)isMutePit;
|
||||
/// 麦位状态发生变化
|
||||
-(void)roomSeatStatusDidChangedIsLock:(NSString*)is_lock pit_number:(NSString*)pit_number;
|
||||
/// 用户进出房间
|
||||
-(void)roomOnlineNumberDidChangedIsAdd:(BOOL)isAdd;
|
||||
/// 10秒自动校正在线人数
|
||||
-(void)roomOnlineNumberDidChangedOnlineNumber:(NSString*)onlineNumber;
|
||||
|
||||
|
||||
|
||||
/// 拍卖者被拉上麦
|
||||
-(void)auctionUpSeatWithUserInfo:(QXUserHomeModel*)userInfo isUpSeat:(BOOL)isUpSeat;
|
||||
/// 拍卖者列表发生变化
|
||||
-(void)auctionListDidChanged:(NSArray<QXRoomPitModel *>*)auctionList;
|
||||
/// 拍卖状态发生变化
|
||||
-(void)auctionStartOrEndIsStart:(BOOL)isStart user:(QXRoomAuctionUser *)user getUser:(QXRoomAuctionUser*)getUser;
|
||||
/// 拍卖时间延迟
|
||||
-(void)auctionTimeDelayWithEndTime:(NSString*)endTime;
|
||||
/// 拍卖类型发生变化
|
||||
-(void)auctionTypeDidChanged:(NSString*)type;
|
||||
/// 私密小屋心动值发生变化
|
||||
-(void)cabinRoomValueDidChanged:(NSString*)hotValue;
|
||||
|
||||
|
||||
/// 收到pk邀请
|
||||
-(void)recievePKInviteWithSendRoomId:(NSString*)SendRoomId AcceptRoomId:(NSString*)AcceptRoomId PkId:(NSString*)PkId message:(NSString*)message;
|
||||
/// 同意或拒绝pk邀请 user_id 与 room_id 为对方
|
||||
-(void)agreeOrRefusePKIsAgree:(BOOL)isAgree user_id:(NSString*)user_id room_id:(NSString*)room_id pk_id:(NSString*)pk_id;
|
||||
/// pk开始
|
||||
-(void)pkStartWithPkEndTimes:(NSString*)pk_end_times pk_id:(NSString*)pk_id;
|
||||
/// pk值发生变化 room_id_a发起者房间id create_value_a 发起者房间pk值 room_id_b 接收者房间id receive_value_b接受者房间pk值
|
||||
-(void)roomPKValueDidChangedWithRoomIdA:(NSString*)room_id_a create_value_a:(NSString*)create_value_a room_id_b:(NSString*)room_id_b receive_value_b:(NSString*)receive_value_b;
|
||||
/// pk结果 isVictory 0 负 1 胜 2平
|
||||
-(void)pkResultWithIsVictory:(NSInteger)isVictory
|
||||
end_time:(NSString*)end_time
|
||||
victory_name:(NSString*)victory_name
|
||||
victory_cover:(NSString*)victory_cover
|
||||
defeated_name:(NSString*)defeated_name
|
||||
defeated_cover:(NSString*)defeated_cover;
|
||||
/// pk断开
|
||||
-(void)pkDisConnect;
|
||||
/// 是否屏蔽ok远端声音
|
||||
-(void)pkMuteRemoteAudio:(BOOL)isMute fromUserInfo:(QXUserHomeModel*)fromUserInfo;
|
||||
/// 惩罚阶段败方想跑路 胜方收到后决定要不要让他跑
|
||||
-(void)roomPKRecieveLoserWantToRunRoadWithUserInfo:(QXUserHomeModel*)fromUserInfo;;
|
||||
/// 收到抢头条
|
||||
-(void)recieveHeadline:(QXHeadLineModel*)headline;
|
||||
|
||||
|
||||
/// 查询用户状态
|
||||
-(void)getUserStatusWithUsers:(NSArray <NSString*>*)users;
|
||||
|
||||
@end
|
||||
@interface QXRoomMessageManager : NSObject
|
||||
@property (nonatomic,weak)id<QXRoomMessageManagerDelegate>delegate;
|
||||
|
||||
+(instancetype)shared;
|
||||
|
||||
-(void)joinGroupWithRoomId:(NSString*)roomId;
|
||||
|
||||
-(void)quitGroupWithRoomId:(NSString*)roomId;
|
||||
|
||||
-(void)sendChatMessage:(NSString *)message messageType:(QXRoomMessageType)messageType needInsertMessage:(BOOL)needInsertMessage;
|
||||
|
||||
-(void)sendC2CMessage:(NSString *)message messageType:(QXRoomMessageType)messageType userId:(NSString*)userId;
|
||||
@end
|
||||
|
||||
@interface QXRoomMessage : NSObject
|
||||
@property (nonatomic,strong)NSString *RoomId;
|
||||
@property (nonatomic,strong)NSString *MsgType;
|
||||
@property (nonatomic,strong)NSDictionary *Text;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,657 +0,0 @@
|
||||
//
|
||||
// QXRoomMessageManager.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/6/10.
|
||||
//
|
||||
|
||||
#import "QXRoomMessageManager.h"
|
||||
#import <ImSDK_Plus/ImSDK_Plus.h>
|
||||
#import "QXMineNetwork.h"
|
||||
#import "QXGiftPlayerManager.h"
|
||||
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
|
||||
|
||||
@interface QXRoomMessageManager() <V2TIMGroupListener,V2TIMSimpleMsgListener,V2TIMAdvancedMsgListener>
|
||||
@property (nonatomic,strong)NSString *groupId;
|
||||
@end
|
||||
@implementation QXRoomMessageManager
|
||||
+ (instancetype)shared {
|
||||
static QXRoomMessageManager *global = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
global = [[self alloc] init];
|
||||
});
|
||||
return global;
|
||||
}
|
||||
-(void)joinGroupWithRoomId:(NSString *)roomId{
|
||||
MJWeakSelf
|
||||
if (self.groupId) {
|
||||
[self quitGroupWithRoomId:roomId];
|
||||
}
|
||||
[[V2TIMManager sharedInstance] addGroupListener:self];
|
||||
[[V2TIMManager sharedInstance] addSimpleMsgListener:self];
|
||||
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self];
|
||||
NSString *groupId = [NSString stringWithFormat:@"room%@",roomId];
|
||||
[[V2TIMManager sharedInstance] joinGroup:groupId msg:@"大家好,我来啦" succ:^{
|
||||
QXLOG(@"腾讯IM加入聊天室成功");
|
||||
weakSelf.groupId = groupId;
|
||||
} fail:^(int code, NSString *desc) {
|
||||
// 加入群组失败
|
||||
QXLOG(@"腾讯IM加入聊天室失败-code%d-原因%@",code,desc);
|
||||
}];
|
||||
}
|
||||
-(void)quitGroupWithRoomId:(NSString *)roomId{
|
||||
MJWeakSelf
|
||||
// [QXMineNetwork quitRoomWithRoomId:<#(nonnull NSString *)#> user_id:<#(nonnull NSString *)#> successBlock:<#^(NSDictionary * _Nonnull dict)successBlock#> failBlock:<#^(NSError * _Nonnull error, NSString * _Nonnull msg)failBlock#>];
|
||||
self.groupId = nil;
|
||||
[[V2TIMManager sharedInstance] removeGroupListener:self];
|
||||
[[V2TIMManager sharedInstance] removeSimpleMsgListener:self];
|
||||
[[V2TIMManager sharedInstance] removeAdvancedMsgListener:self];
|
||||
NSString *groupId = [NSString stringWithFormat:@"room%@",roomId];
|
||||
[[V2TIMManager sharedInstance] quitGroup:groupId succ:^{
|
||||
|
||||
} fail:^(int code, NSString * _Nullable desc) {
|
||||
|
||||
}];
|
||||
}
|
||||
// 新成员加入
|
||||
-(void)onMemberEnter:(NSString *)groupID memberList:(NSArray<V2TIMGroupMemberInfo *> *)memberList{
|
||||
|
||||
}
|
||||
// 有人离开
|
||||
-(void)onMemberLeave:(NSString *)groupID member:(V2TIMGroupMemberInfo *)member{
|
||||
|
||||
}
|
||||
- (void)onRecvNewMessage:(V2TIMMessage *)msg {
|
||||
if (msg.isBroadcastMessage) {
|
||||
// 收到了广播消息
|
||||
NSData *data = msg.customElem.data;
|
||||
NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
QXLOG(@"收到广播消息---%@",jsonStr);
|
||||
QXHeadLineModel *headline = [QXHeadLineModel yy_modelWithJSON:jsonStr];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(recieveHeadline:)]) {
|
||||
[self.delegate recieveHeadline:headline];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 收到系统消息
|
||||
-(void)onReceiveRESTCustomData:(NSString *)groupID data:(NSData *)data{
|
||||
NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
QXRoomMessage *msg = [QXRoomMessage yy_modelWithJSON:jsonStr];
|
||||
NSString *groupId = [NSString stringWithFormat:@"room%@",msg.RoomId];
|
||||
if ([groupId isEqualToString:self.groupId]) {
|
||||
// 处理逻辑
|
||||
NSInteger meesageType = msg.MsgType.integerValue;
|
||||
switch (meesageType) {
|
||||
case QXRoomMessageTypeSystem:{
|
||||
/// 系统消息
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeJoin:{
|
||||
/// 用户进入房间
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
NSString *jia_jia = [NSString stringWithFormat:@"%@",msg.Text[@"jia_jia"]];
|
||||
if (([jia_jia hasPrefix:@"http"] || [jia_jia hasPrefix:@"https"]) && ([jia_jia hasSuffix:@"svga"] || [jia_jia hasSuffix:@"mp4"])) {
|
||||
QXGiftModel *md = [[QXGiftModel alloc] init];
|
||||
md.play_image = jia_jia;
|
||||
[[QXGiftPlayerManager shareManager] displayChatEffectView:md];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
if ([model.FromUserInfo.user_id isEqualToString:QXGlobal.shareGlobal.loginModel.user_id]) {
|
||||
return;
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomOnlineNumberDidChangedIsAdd:)]) {
|
||||
[self.delegate roomOnlineNumberDidChangedIsAdd:YES];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeQuit:{
|
||||
/// 用户退出房间
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomOnlineNumberDidChangedIsAdd:)]) {
|
||||
[self.delegate roomOnlineNumberDidChangedIsAdd:NO];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeGift:{
|
||||
/// 收到礼物
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeGift;
|
||||
[[QXGiftPlayerManager shareManager] displayFullEffectView:model.GiftInfo];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didRecieveGiftWithWithUserInfo:)]) {
|
||||
[self.delegate didRecieveGiftWithWithUserInfo:model.ToUserInfo];
|
||||
}
|
||||
if (model.text.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QXRoomMessageTypeAplayPitModeDidChanged:{
|
||||
/// 上麦模式发生变化
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(aplayPitModeDidChanged:)]) {
|
||||
NSString* room_up_pit_type = [NSString stringWithFormat:@"%@",msg.Text[@"room_up_pit_type"]];
|
||||
[self.delegate aplayPitModeDidChanged:room_up_pit_type];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeUpSeat:{
|
||||
/// 用户上麦
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didUpDownSeatWithUser:isUpSeat:pit_number:)]) {
|
||||
NSString *pit_number = [NSString stringWithFormat:@"%@",msg.Text[@"pit_number"]];
|
||||
[self.delegate didUpDownSeatWithUser:model.FromUserInfo isUpSeat:YES pit_number:pit_number.integerValue];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeDownSeat:{
|
||||
/// 用户下麦
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didUpDownSeatWithUser:isUpSeat:pit_number:)]) {
|
||||
NSString *pit_number = [NSString stringWithFormat:@"%@",msg.Text[@"pit_number"]];
|
||||
[self.delegate didUpDownSeatWithUser:model.FromUserInfo isUpSeat:NO pit_number:pit_number.integerValue];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeSwicthSong:{
|
||||
/// 点歌
|
||||
NSString *action = [NSString stringWithFormat:@"%@",msg.Text[@"action"]];
|
||||
if (action.intValue == 1) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(applySongWaitAgreeWithUserNickname:)]) {
|
||||
[self.delegate applySongWaitAgreeWithUserNickname:model.FromUserInfo.nickname];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (action.intValue == 2) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(nextSongDidStartWithSongInfo:nextInfo:)]) {
|
||||
[self.delegate nextSongDidStartWithSongInfo:model.songInfo nextInfo:model.nextInfo];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (action.intValue == 4) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(applySongNoAgreeWithUserId:)]) {
|
||||
[self.delegate applySongNoAgreeWithUserId:model.FromUserInfo.user_id];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (action.intValue == 3) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(nextSongDidChangedWithNextSong:)]) {
|
||||
[self.delegate nextSongDidChangedWithNextSong:model.nextInfo];
|
||||
}
|
||||
return;
|
||||
}
|
||||
// @{
|
||||
// @"action":@"1", // 1有人发起点歌 主持人同意点歌走房间类型变化推送 2 切歌 3 下一首歌有变化 4 拒绝
|
||||
//
|
||||
// // 有人发起点歌时 前端收到推送为1 根据当前自己所在的麦位是否为主持麦,为主持麦时弹出有人申请点歌弹窗,其余人不处理该条推送
|
||||
//
|
||||
// @"songInfo":@{ // 仅在切歌时有该条消息
|
||||
// @"song_code":@"歌曲code",
|
||||
// @"song_name":@"歌曲名称",
|
||||
// @"singer":@"演唱者",
|
||||
// @"poster":@"歌曲封面",
|
||||
// @"duration":@"歌曲时长",
|
||||
//
|
||||
// @"user_id":@"点唱用户id",
|
||||
// @"nickname":@"点唱用户昵称",
|
||||
// @"avatar":@"点唱用户头像",
|
||||
// @"dress":@"点唱用户装扮",
|
||||
// @"charm":@"点唱用户魅力",
|
||||
// }
|
||||
// }
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomTypeChanged:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomTypeDidChanged)]) {
|
||||
[self.delegate roomTypeDidChanged];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeCharmRankList:{
|
||||
/// 点唱房魅力发生变化
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(songRoomCharmRankListDidChanged:)]) {
|
||||
NSArray *list = [NSArray yy_modelArrayWithClass:[QXRoomPitModel class] json:msg.Text[@"userCharmList"]];
|
||||
[self.delegate songRoomCharmRankListDidChanged:list];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeRoomInfoChanged:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomInfoDidChanged:)]) {
|
||||
QXRoomInfoModel *model = [QXRoomInfoModel yy_modelWithJSON:msg.Text[@"RoomInfo"]];
|
||||
[self.delegate roomInfoDidChanged:model];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeSetManage:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSetManagerOrCompere:isManager:isAdd:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
[self.delegate roomSetManagerOrCompere:model.FromUserInfo isManager:YES isAdd:YES];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:userId:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model userId:model.FromUserInfo.user_id];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeSetCompere:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSetManagerOrCompere:isManager:isAdd:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
[self.delegate roomSetManagerOrCompere:model.FromUserInfo isManager:NO isAdd:YES];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:userId:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model userId:model.FromUserInfo.user_id];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeCompereIsDelete:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSetManagerOrCompere:isManager:isAdd:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
[self.delegate roomSetManagerOrCompere:model.FromUserInfo isManager:NO isAdd:NO];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:userId:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model userId:model.FromUserInfo.user_id];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeManagerIsDelete:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSetManagerOrCompere:isManager:isAdd:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
[self.delegate roomSetManagerOrCompere:model.FromUserInfo isManager:YES isAdd:NO];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:userId:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model userId:model.FromUserInfo.user_id];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
|
||||
case QXRoomMessageTypeTakeOff:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(userDidTakeOffWithUserInfo:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
[self.delegate userDidTakeOffWithUserInfo:model.FromUserInfo];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeRoomClearCharm:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomClearCharm)]) {
|
||||
[self.delegate roomClearCharm];
|
||||
}
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeSeatMute:{
|
||||
/// 房间麦位位被禁麦
|
||||
}
|
||||
break;;
|
||||
case QXRoomMessageTypeSeatLock:{
|
||||
/// 房间被锁麦
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSeatStatusDidChangedIsLock:pit_number:)]) {
|
||||
NSString *is_lock = [NSString stringWithFormat:@"%@",msg.Text[@"is_lock"]];
|
||||
NSString *pit_number = [NSString stringWithFormat:@"%@",msg.Text[@"pit_number"]];
|
||||
[self.delegate roomSeatStatusDidChangedIsLock:is_lock pit_number:pit_number];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomUserMute:{
|
||||
/// 用户被禁言
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(userMuteStatusDidChanged:isMute:isMutePit:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
NSString *is_mute = [NSString stringWithFormat:@"%@",msg.Text[@"is_mute"]];
|
||||
NSString *is_mute_pit = [NSString stringWithFormat:@"%@",msg.Text[@"is_mute_pit"]];
|
||||
[self.delegate userMuteStatusDidChanged:model.FromUserInfo isMute:is_mute isMutePit:is_mute_pit];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:userId:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model userId:model.FromUserInfo.user_id];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QXRoomMessageTypeRoomAuctionUpSeat:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(auctionUpSeatWithUserInfo:isUpSeat:)]) {
|
||||
NSString *type = [NSString stringWithFormat:@"%@",msg.Text[@"type"]];
|
||||
/// 1 上麦 2 下麦
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
[self.delegate auctionUpSeatWithUserInfo:model.FromUserInfo isUpSeat:type.intValue==1];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomAuctionStart:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(auctionStartOrEndIsStart:user:getUser:)]) {
|
||||
QXRoomAuctionUser *user = [QXRoomAuctionUser yy_modelWithJSON:msg.Text[@"auction_user"]];
|
||||
[self.delegate auctionStartOrEndIsStart:YES user:user getUser:nil];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomAuctionPitChanged:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(auctionListDidChanged:)]) {
|
||||
NSArray *list = [NSArray yy_modelArrayWithClass:[QXRoomPitModel class] json:msg.Text[@"auction_list"]];
|
||||
[self.delegate auctionListDidChanged:list];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomAuctionEnd:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(auctionStartOrEndIsStart:user:getUser:)]) {
|
||||
QXRoomAuctionUser *user = [QXRoomAuctionUser yy_modelWithJSON:msg.Text[@"auction_user"]];
|
||||
QXRoomAuctionUser *getUser = [QXRoomAuctionUser yy_modelWithJSON:msg.Text[@"recipient"]];
|
||||
[self.delegate auctionStartOrEndIsStart:NO user:user getUser:getUser];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomAuctionDelayTime:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(auctionTimeDelayWithEndTime:)]) {
|
||||
NSString *endTime = [NSString stringWithFormat:@"%@",msg.Text[@"duration"]];
|
||||
[self.delegate auctionTimeDelayWithEndTime:endTime];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomAuctionTypeDidChanged:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(auctionTypeDidChanged:)]) {
|
||||
NSString *endTime = [NSString stringWithFormat:@"%@",msg.Text[@"type"]];
|
||||
[self.delegate auctionTypeDidChanged:endTime];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomCabinRoomValueChanged:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(cabinRoomValueDidChanged:)]) {
|
||||
NSString *hot_value = [NSString stringWithFormat:@"%@",msg.Text[@"hot_value"]];
|
||||
[self.delegate cabinRoomValueDidChanged:hot_value];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomRecieveInvitePk:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(recievePKInviteWithSendRoomId:AcceptRoomId:PkId:message:)]) {
|
||||
NSString *SendRoomId = [NSString stringWithFormat:@"%@",msg.Text[@"SendRoomId"]];
|
||||
NSString *AcceptRoomId = [NSString stringWithFormat:@"%@",msg.Text[@"AcceptRoomId"]];
|
||||
NSString *PkId = [NSString stringWithFormat:@"%@",msg.Text[@"PkId"]];
|
||||
NSString *message = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
|
||||
[self.delegate recievePKInviteWithSendRoomId:SendRoomId AcceptRoomId:AcceptRoomId PkId:PkId message:message];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomPKAgreeOrRefuse:{
|
||||
NSString *user_id = [NSString stringWithFormat:@"%@",msg.Text[@"user_id"]];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(agreeOrRefusePKIsAgree:user_id:room_id:pk_id:)]) {
|
||||
NSString *type = [NSString stringWithFormat:@"%@",msg.Text[@"type"]];
|
||||
NSString *room_id = [NSString stringWithFormat:@"%@",msg.Text[@"room_id"]];
|
||||
NSString *pk_id = [NSString stringWithFormat:@"%@",msg.Text[@"pk_id"]];
|
||||
[self.delegate agreeOrRefusePKIsAgree:type.intValue==1 user_id:user_id room_id:room_id pk_id:pk_id];
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:userId:)]) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeSystem;
|
||||
[self.delegate didInsertMessge:model userId:user_id];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomPKStart:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(pkStartWithPkEndTimes:pk_id:)]) {
|
||||
NSString *pk_end_times = [NSString stringWithFormat:@"%@",msg.Text[@"pk_end_times"]];
|
||||
NSString *pk_id = [NSString stringWithFormat:@"%@",msg.Text[@"pk_id"]];
|
||||
[self.delegate pkStartWithPkEndTimes:pk_end_times pk_id:pk_id];
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomPKEnd:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(pkResultWithIsVictory:end_time:victory_name:victory_cover:defeated_name:defeated_cover:)]) {
|
||||
NSString *type = [NSString stringWithFormat:@"%@",msg.Text[@"type"]];
|
||||
NSString *victory_name = [NSString stringWithFormat:@"%@",msg.Text[@"victory_name"]];
|
||||
NSString *victory_cover = [NSString stringWithFormat:@"%@",msg.Text[@"victory_cover"]];
|
||||
NSString *defeated_name = [NSString stringWithFormat:@"%@",msg.Text[@"defeated_name"]];
|
||||
NSString *defeated_cover = [NSString stringWithFormat:@"%@",msg.Text[@"defeated_cover"]];
|
||||
NSString *end_time = [NSString stringWithFormat:@"%@",msg.Text[@"end_time"]];
|
||||
[self.delegate pkResultWithIsVictory:type.intValue end_time:end_time victory_name:victory_name victory_cover:victory_cover defeated_name:defeated_name defeated_cover:defeated_cover];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomPKDisconnect:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(pkDisConnect)]) {
|
||||
[self.delegate pkDisConnect];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypePKValueDidChanged:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomPKValueDidChangedWithRoomIdA:create_value_a:room_id_b:receive_value_b:)]) {
|
||||
NSString *room_id_a = [NSString stringWithFormat:@"%@",msg.Text[@"room_id_a"]];
|
||||
NSString *room_id_b = [NSString stringWithFormat:@"%@",msg.Text[@"room_id_b"]];
|
||||
NSString *create_value_a = [NSString stringWithFormat:@"%@",msg.Text[@"create_value_a"]];
|
||||
NSString *receive_value_b = [NSString stringWithFormat:@"%@",msg.Text[@"receive_value_b"]];
|
||||
[self.delegate roomPKValueDidChangedWithRoomIdA:room_id_a create_value_a:create_value_a room_id_b:room_id_b receive_value_b:receive_value_b];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QXRoomMessageTypeRoomInLineNumber:{
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(aplayMicInLineNumberDidChanged:)]) {
|
||||
NSString *count = [NSString stringWithFormat:@"%@",msg.Text[@"count"]];
|
||||
[self.delegate aplayMicInLineNumberDidChanged:count];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomOnlineNumber:{
|
||||
NSString *online_number = [NSString stringWithFormat:@"%@",msg.Text[@"online_number"]];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomOnlineNumberDidChangedOnlineNumber:)]) {
|
||||
[self.delegate roomOnlineNumberDidChangedOnlineNumber:online_number];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QXRoomMessageTypeRoomPkNeedAgree:{
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomPKRecieveLoserWantToRunRoadWithUserInfo:)]) {
|
||||
[self.delegate roomPKRecieveLoserWantToRunRoadWithUserInfo:model.FromUserInfo];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QXRoomMessageTypeRoomBlindBox:{
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeChat;
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXRoomMessageTypeRoomUserInfoDidChanged:{
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeChat;
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomUserInfoDidChanged:)]) {
|
||||
[self.delegate roomUserInfoDidChanged:model.FromUserInfo];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
/// 有人向我发起pk
|
||||
QXRoomMessageTypeRoomRecieveInvitePk = 1029,
|
||||
/// 拒绝或接受pk
|
||||
QXRoomMessageTypeRoomPKAgreeOrRefuse = 1030,
|
||||
/// pk开始
|
||||
QXRoomMessageTypeRoomPKStart = 1031,
|
||||
/// pk结束 惩罚时间
|
||||
QXRoomMessageTypeRoomPKEnd = 1032,
|
||||
/// pk断开
|
||||
QXRoomMessageTypeRoomPKDisconnect = 1033,
|
||||
|
||||
*/
|
||||
|
||||
|
||||
-(void)onRecvC2CTextMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info text:(NSString *)text{
|
||||
|
||||
}
|
||||
-(void)onRecvC2CCustomMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info customData:(NSData *)data{
|
||||
NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
QXRoomMessage *msg = [QXRoomMessage yy_modelWithJSON:jsonStr];
|
||||
NSInteger meesageType = msg.MsgType.integerValue;
|
||||
if (meesageType == QXRoomMessageTypeMuteRemoteAudio){
|
||||
NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
|
||||
NSDictionary *dict = [json jsonValueDecoded];
|
||||
NSInteger is_mute = [[dict objectForKey:@"is_mute"] integerValue];
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(pkMuteRemoteAudio:fromUserInfo:)]) {
|
||||
[self.delegate pkMuteRemoteAudio:is_mute==1 fromUserInfo:model.FromUserInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
-(void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data{
|
||||
NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
QXRoomMessage *msg = [QXRoomMessage yy_modelWithJSON:jsonStr];
|
||||
NSInteger meesageType = msg.MsgType.integerValue;
|
||||
if (meesageType == QXRoomMessageTypeText) {
|
||||
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
|
||||
model.messageType = QXRoomChatMessageTypeChat;
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}else if (meesageType == QXRoomMessageTypeClearMessage) {
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didClearAllMessage)]) {
|
||||
[self.delegate didClearAllMessage];
|
||||
}
|
||||
}else if (meesageType == QXRoomMessageTypeSongLrc){
|
||||
NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
|
||||
NSDictionary *dict = [json jsonValueDecoded];
|
||||
NSInteger positionMs = [[dict objectForKey:@"position"] integerValue];
|
||||
if (positionMs<=0) {
|
||||
return;
|
||||
}
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSongLrcProgress:)]) {
|
||||
[self.delegate roomSongLrcProgress:positionMs];
|
||||
}
|
||||
QXLOG(@"收到歌词进度userID--%@---positionMs---%ld",info.userID,positionMs);
|
||||
}else if (meesageType == QXRoomMessageTypeMuteLocalAudio){
|
||||
NSString *json = [NSString stringWithFormat:@"%@",msg.Text[@"text"]];
|
||||
NSDictionary *dict = [json jsonValueDecoded];
|
||||
NSInteger is_mute = [[dict objectForKey:@"is_mute"] integerValue];
|
||||
QXUserHomeModel *userModel = [QXUserHomeModel yy_modelWithJSON:msg.Text[@"FromUserInfo"]];
|
||||
AgoraRtcAudioVolumeInfo *userInfo = [[AgoraRtcAudioVolumeInfo alloc] init];
|
||||
userInfo.uid = userModel.user_id.longLongValue;
|
||||
userInfo.volume = 0;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:noticeUserSpeak object:userInfo];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)sendChatMessage:(NSString *)message messageType:(QXRoomMessageType)messageType needInsertMessage:(BOOL)needInsertMessage{
|
||||
NSDictionary *dict = @{
|
||||
@"RoomId":self.groupId?self.groupId:@"",
|
||||
@"MsgType":[NSNumber numberWithInteger:messageType],
|
||||
@"Text":@{
|
||||
@"FromUserInfo":@{
|
||||
@"user_id":[QXGlobal shareGlobal].loginModel.user_id?[QXGlobal shareGlobal].loginModel.user_id:@"",
|
||||
@"nickname":[QXGlobal shareGlobal].loginModel.nickname?[QXGlobal shareGlobal].loginModel.nickname:@"",
|
||||
@"avatar":[QXGlobal shareGlobal].loginModel.avatar?[QXGlobal shareGlobal].loginModel.avatar:@"",
|
||||
@"icon":[QXGlobal shareGlobal].loginModel.icon?[QXGlobal shareGlobal].loginModel.icon:@"",
|
||||
},
|
||||
@"text":message
|
||||
}
|
||||
};
|
||||
if (needInsertMessage) {
|
||||
QXRoomChatListModel *model = [[QXRoomChatListModel alloc] init];
|
||||
model.text = message;
|
||||
QXUserHomeModel *userInfo = [[QXUserHomeModel alloc] init];
|
||||
userInfo.avatar = [QXGlobal shareGlobal].loginModel.avatar;
|
||||
userInfo.nickname = [QXGlobal shareGlobal].loginModel.nickname;
|
||||
userInfo.user_id = [QXGlobal shareGlobal].loginModel.user_id;
|
||||
userInfo.icon = [QXGlobal shareGlobal].loginModel.icon;
|
||||
model.FromUserInfo = userInfo;
|
||||
model.messageType = QXRoomChatMessageTypeChat;
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
|
||||
[self.delegate didInsertMessge:model];
|
||||
}
|
||||
}
|
||||
NSString *jsonStr = [dict jsonStringEncoded];
|
||||
NSData *data =[jsonStr dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[[V2TIMManager sharedInstance] sendGroupCustomMessage:data to:self.groupId priority:V2TIM_PRIORITY_NORMAL succ:^{
|
||||
QXLOG(@"发送自定义消息成功");
|
||||
} fail:^(int code, NSString * _Nullable desc) {
|
||||
QXLOG(@"发送自定义消息失败");
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)sendC2CMessage:(NSString *)message messageType:(QXRoomMessageType)messageType userId:(NSString *)userId{
|
||||
NSDictionary *dict = @{
|
||||
@"RoomId":self.groupId?self.groupId:@"",
|
||||
@"MsgType":[NSNumber numberWithInteger:messageType],
|
||||
@"Text":@{
|
||||
@"FromUserInfo":@{
|
||||
@"user_id":[QXGlobal shareGlobal].loginModel.user_id?[QXGlobal shareGlobal].loginModel.user_id:@"",
|
||||
@"nickname":[QXGlobal shareGlobal].loginModel.nickname?[QXGlobal shareGlobal].loginModel.nickname:@"",
|
||||
@"avatar":[QXGlobal shareGlobal].loginModel.avatar?[QXGlobal shareGlobal].loginModel.avatar:@"",
|
||||
@"icon":[QXGlobal shareGlobal].loginModel.icon?[QXGlobal shareGlobal].loginModel.icon:@"",
|
||||
},
|
||||
@"text":message
|
||||
}
|
||||
};
|
||||
NSString *jsonStr = [dict jsonStringEncoded];
|
||||
NSData *data =[jsonStr dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString*toUserId = [NSString stringWithFormat:@"u%@",userId];
|
||||
// [[V2TIMManager sharedInstance] sendC2CCustomMessage:data to:toUserId succ:^{
|
||||
//
|
||||
// } fail:^(int code, NSString * _Nullable desc) {
|
||||
//
|
||||
// }];
|
||||
V2TIMMessage *message1 = [[V2TIMManager sharedInstance] createCustomMessage:data];
|
||||
message1.isExcludedFromUnreadCount = YES;
|
||||
message1.isExcludedFromContentModeration = YES;
|
||||
[[V2TIMManager sharedInstance] sendMessage:message1 receiver:toUserId groupID:nil priority:(V2TIM_PRIORITY_HIGH) onlineUserOnly:YES offlinePushInfo:nil progress:^(uint32_t progress) {
|
||||
|
||||
} succ:^{
|
||||
|
||||
} fail:^(int code, NSString * _Nullable desc) {
|
||||
|
||||
}];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation QXRoomMessage
|
||||
|
||||
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user