覆盖羽声

This commit is contained in:
启星
2025-10-20 09:43:10 +08:00
parent affed1af58
commit 0d82f9e0ef
1331 changed files with 43209 additions and 14707 deletions

195
QXLive/Manager/QXAgoraEngine.h Executable file
View File

@@ -0,0 +1,195 @@
//
// 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

850
QXLive/Manager/QXAgoraEngine.m Executable file
View File

@@ -0,0 +1,850 @@
//
// 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{
QXLOG(@"声网状态---%ld",errorCode)
}
//
- (void)setChannelProfile {
[self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
}
//
- (void)joinChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString*)agora_token agora_rtm_token:(NSString*)agora_rtm_token isUpSeat:(BOOL)isUpSeat successBock:(nonnull void (^)(void))successBock{
if (isUpSeat) {
self.option.clientRoleType = AgoraClientRoleBroadcaster;
}else{
self.option.clientRoleType = AgoraClientRoleAudience;
}
if (_currentChannel.length > 0) {
if (![_currentChannel isEqualToString:channelId]) {
[self switchToChannel:channelId withRoom:chatRoom agora_token:agora_token agora_rtm_token:agora_rtm_token isUpSeat:isUpSeat successBock:successBock];
}
}else{
__weak typeof(self)weakSelf = self;
[self.agoraKit joinChannelByToken:agora_token channelId:channelId uid:QXGlobal.shareGlobal.loginModel.user_id.longLongValue mediaOptions:self.option joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
[weakSelf onInitKTVCenterWithToken:agora_rtm_token];
[weakSelf muteLocalAudioStream:YES];
[weakSelf muteAllRemoteAudioStreams:NO];
self.option.publishMicrophoneTrack = YES;
self.option.publishMediaPlayerAudioTrack = YES;
self.option.enableAudioRecordingOrPlayout = YES;
self.option.publishMediaPlayerId = [self->_ktvPlayer getMediaPlayerId];
[self.agoraKit updateChannelWithMediaOptions:self.option];
// uid
if (successBock) {
successBock();
}
}];
}
}
//- (void)joinExChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString*)agora_token agora_rtm_token:(NSString*)agora_rtm_token successBock:(void(^)(void))successBock{
// [self.agoraKit joinChannelExByToken:<#(NSString * _Nullable)#> channelId:<#(NSString * _Nonnull)#> userAccount:<#(NSString * _Nonnull)#> delegate:<#(id<AgoraRtcEngineDelegate> _Nullable)#> mediaOptions:<#(AgoraRtcChannelMediaOptions * _Nonnull)#> joinSuccess:<#^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed)joinSuccessBlock#>]
//}
//
/*
*/
- (void)setClientRoleBroadcaster:(BOOL)isBroadcaster {
[self.agoraKit setClientRole:isBroadcaster ? AgoraClientRoleBroadcaster : AgoraClientRoleAudience];
}
- (void)rtcEngine:(AgoraRtcEngineKit * _Nonnull)engine tokenPrivilegeWillExpire:(NSString *_Nonnull)token{
// [self.agoraKit renewToken:<#(NSString * _Nonnull)#>]
}
//
-(void)leaveChannel {
int result = [self.agoraKit leaveChannel:^(AgoraChannelStats * _Nonnull stat) {
QXLOG(@"声网进入退出频道回调");
}];
QXLOG(@"声网退出频道result---------%@",result);
//退
self.chatRoom = nil;
self.currentChannel = nil;
}
//
- (void)switchToChannel:(NSString *)channelId withRoom:(UIViewController *)chatRoom agora_token:(NSString *)agora_token agora_rtm_token:(NSString *)agora_rtm_token isUpSeat:(BOOL)isUpSeat successBock:(void (^)(void))successBock{
__weak typeof(self)weakSelf = self;
[self.agoraKit leaveChannel:^(AgoraChannelStats * _Nonnull stat) {
[self.agoraKit joinChannelByToken:agora_token channelId:channelId uid:QXGlobal.shareGlobal.loginModel.user_id.longLongValue mediaOptions:self.option joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
[weakSelf onInitKTVCenterWithToken:agora_rtm_token];
[weakSelf muteLocalAudioStream:YES];
[weakSelf muteAllRemoteAudioStreams:NO];
AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
option.publishMicrophoneTrack = YES;
option.publishMediaPlayerAudioTrack = YES;
option.enableAudioRecordingOrPlayout = YES;
option.publishMediaPlayerId = [self->_ktvPlayer getMediaPlayerId];
[self.agoraKit updateChannelWithMediaOptions:option];
if (successBock) {
successBock();
}
}];
}];
}
//
- (void)destroyEngine
{
if (!self.agoraKit) {
return;
}
[AgoraRtcEngineKit destroy];
self.agoraKit = nil;
[self.ktvAmcc destroyMusicPlayer:_ktvPlayer];
_ktvPlayer = nil;
[self.ktvAmcc registerEventDelegate:nil];
[AgoraMusicContentCenter destroy];
self.ktvAmcc = nil;
self.isOpenMic = NO;
}
//
- (void)muteLocalAudioStream:(BOOL)mute
{
// [self.agoraKit enableLocalAudio:!mute];
// if ([self.songModel.user_id isEqualToString:QXGlobal.shareGlobal.loginModel.user_id]) {
// ///
// [self.agoraKit muteRecordingSignal:mute];
// }else{
// [self.agoraKit muteRecordingSignal:mute];
// [self.agoraKit muteLocalAudioStream:mute];
// }
int result = [self.agoraKit muteLocalAudioStream:mute];
QXLOG(@"音频模块禁麦---%d",result);
// [self setClientRoleBroadcaster:!mute];
// [self.agoraKit muteRecordingSignal:mute];
}
-(void)enableAudio:(BOOL)enble{
self.isOpenMic = enble;
int result = [self.agoraKit enableLocalAudio:enble];
QXLOG(@"音频模块启动---%d",result);
}
//
- (int)setEnableSpeakerphone:(BOOL)enableSpeaker
{
return [self.agoraKit setEnableSpeakerphone:enableSpeaker];
}
- (BOOL)isSpeakerphoneEnabled
{
return [self.agoraKit isSpeakerphoneEnabled];
}
- (int)muteAllRemoteAudioStreams:(BOOL)mute
{
return [self.agoraKit muteAllRemoteAudioStreams:mute];
}
- (int)startAudioMixing:(NSString * _Nonnull)filePath
loopback:(BOOL)loopback
replace:(BOOL)replace
cycle:(NSInteger)cycle
{
// self.isPlay = YES;
return [self.agoraKit startAudioMixing:filePath loopback:loopback cycle:cycle startPos:0];
}
- (int)paseAudioMixing{
// self.isPlay = NO;
return [self.agoraKit pauseAudioMixing];
}
- (int)stopAudioMixing{
// self.isPlay = NO;
return [self.agoraKit stopAudioMixing];
}
- (int)resumeAudioMixing{
// self.isPlay = YES;
return [self.agoraKit resumeAudioMixing];
}
- (int)adjustAudioMixingVolume:(NSInteger)volume{
return [self.agoraKit adjustAudioMixingVolume:volume];
}
- (double)getEffectsVolume{
return [self.agoraKit getEffectsVolume];
}
#pragma mark-
- (void)registerLocalUserAccount
{
[self.agoraKit registerLocalUserAccount:@"" appId:AgoraAuthId];
}
- (void)RequestMusicURLData:(NSString *)MusicID{
// LNNetworkAPI *api = [[LNNetworkAPI alloc] initWithUrl:@"api/Song/index" parameters:@{@"input":MusicID,@"filter":@"name",@"type":@"netease",@"page":@"1"}];
// [api startRequestWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request, NSDictionary * _Nonnull result) {
// if ([result[@"status"] integerValue] == 1) {
//
// NSArray *DataDic = result[@"data"];
// NSDictionary *dic = DataDic[0];
//
// NSString * filePath = [dic objectForKey:@"url"];
//
// BOOL loopback = NO;
// BOOL replace = NO;
// NSInteger cycle = 1;
//
//
// //
// [self.agoraKit startAudioMixing: filePath loopback: loopback replace: replace cycle: cycle];
//
// }else{
// [SRToastTool showTips:result[@"info"]];
// }
// } failure:^(__kindof YTKBaseRequest * _Nonnull request, NSString * _Nonnull errorInfo) {
// [SRToastTool showError:errorInfo];
// }];
}
#pragma mark-Enginedelegate
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didLeaveChannelWithStats:(AgoraChannelStats *)stats
{
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine localAudioStateChanged:(AgoraAudioLocalState)state reason:(AgoraAudioLocalReason)reason{
QXLOG(@"%lu",(unsigned long)state);
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine audioMixingStateChanged:(AgoraAudioMixingStateType)state reasonCode:(AgoraAudioMixingReasonCode)reasonCode{
QXLOG(@"音乐播放状态改变%lu",(long)state);
switch (state) {
case AgoraAudioMixingStateTypePlaying:
{
}
break;
case AgoraAudioMixingStateTypePaused:
{
}
break;
case AgoraAudioMixingStateTypeStopped:
{
// if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineLocalAudioMixingDidFinish)]) {
// [self.delegate rtcEngineLocalAudioMixingDidFinish];
// return;
// }
}
break;
default:
break;
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid reason:(AgoraUserOfflineReason)reason{
// NSDictionary *parm = @{
// @"user_id":[NSNumber numberWithInteger:uid],
// @"is_online":[NSNumber numberWithBool:NO],
// };
// [[NSNotificationCenter defaultCenter] postNotificationName:noticeRoomUserOnlineStatusDidChanged object:parm];
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed{
// NSDictionary *parm = @{
// @"user_id":[NSNumber numberWithInteger:uid],
// @"is_online":[NSNumber numberWithBool:YES],
// };
// [[NSNotificationCenter defaultCenter] postNotificationName:noticeRoomUserOnlineStatusDidChanged object:parm];
}
///
-(void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray<AgoraRtcAudioVolumeInfo *> *)speakers totalVolume:(NSInteger)totalVolume{
// NSMutableDictionary *usersSoundLevels = [NSMutableDictionary dictionary];
// for (AgoraRtcAudioVolumeInfo *info in speakers) {
// if (info.uid == 0) {
// [usersSoundLevels setValue:@(info.volume) forKey:QXGlobal.shareGlobal.loginModel.user_id];
// }else{
// [usersSoundLevels setValue:@(info.volume) forKey:[NSString stringWithFormat:@"%lu",info.uid]];
// }
// }
// if (self.delegate && [self.delegate respondsToSelector:@selector(onRTCEngineRoomPublishSoundLevelUpdate:)]) {
// [self.delegate onRTCEngineRoomPublishSoundLevelUpdate:speakers];
// }
for (AgoraRtcAudioVolumeInfo *info in speakers) {
[[NSNotificationCenter defaultCenter] postNotificationName:noticeUserSpeak object:info];
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine remoteVideoStats:(AgoraRtcRemoteVideoStats *)stats{
NSLog(@"uid=%ld直播远端视频状态",stats.uid);
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoFrameOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed{
NSLog(@"uid=%ld直播远端视频首次加载",uid);
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoFirstLoadWithUid:size:)]) {
[self.delegate rtcEngineVideoFirstLoadWithUid:uid size:size];
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine videoSizeChangedOfSourceType:(AgoraVideoSourceType)sourceType uid:(NSUInteger)uid size:(CGSize)size rotation:(NSInteger)rotation{
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine remoteVideoStateChangedOfUid:(NSUInteger)uid state:(AgoraVideoRemoteState)state reason:(AgoraVideoRemoteReason)reason elapsed:(NSInteger)elapsed{
NSLog(@"uid=%ld---直播远端视频状态发生变化status=%ld",uid,state);
if (state == AgoraVideoRemoteStateStopped) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoDidStop:)]) {
[self.delegate rtcEngineVideoDidStop:uid];
}
}else if (state == AgoraVideoRemoteStateStarting) {
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoDidStart:)]) {
[self.delegate rtcEngineVideoDidStart:uid];
}
}else{
// if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineVideoDidStart:)]) {
// [self.delegate rtcEngineVideoDidStart:uid];
// }
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine channelMediaRelayStateDidChange:(AgoraChannelMediaRelayState)state error:(AgoraChannelMediaRelayError)error{
NSLog(@"channelMediaRelayStateDidChange");
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine localVideoStateChangedOfState:(AgoraVideoLocalState)state reason:(AgoraLocalVideoStreamReason)reason sourceType:(AgoraVideoSourceType)sourceType{
NSLog(@"localVideoStateChangedOfState");
if (state == AgoraVideoLocalStateCapturing && sourceType == AgoraVideoSourceTypeScreen) {
self.option.publishScreenCaptureAudio = YES;
self.option.publishScreenCaptureVideo = YES;
self.option.publishCameraTrack = NO;
[self.agoraKit updateChannelWithMediaOptions:self.option];
}else if (state == AgoraVideoLocalStateStopped && sourceType == AgoraVideoSourceTypeScreen) {
[self.agoraKit stopScreenCapture];
}
}
-(void)rtcEngine:(AgoraRtcEngineKit *)engine audioMixingPositionChanged:(NSInteger)position{
}
//- (void)rtcEngineLocalAudioMixingDidFinish:(AgoraRtcEngineKit *_Nonnull)engine{
// if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineLocalAudioMixingDidFinish)]) {
// [self.delegate rtcEngineLocalAudioMixingDidFinish];
// return;
// }
// NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
// NSString *filePath = [cachePath stringByAppendingPathComponent:@"testPlist.plist"];
//
// NSMutableArray *MusicListArray = [NSMutableArray arrayWithContentsOfFile:filePath];
//
// NSInteger index = self.index;
// switch (self.playType) {
// case 0:
//
// break;
// case 1:
//
// index = MusicListArray.count - 1;
//
// index = arc4random() % index;
//
// break;
// case 2:
//
// if (index == MusicListArray.count - 1) {
// index = 0;
// }//1
// else{
// index++;
// }
// break;
// default:
// break;
// }
//
// NSDictionary *dic = MusicListArray[index];
// NSString * filePathstr = [dic objectForKey:@"songid"];
// [self RequestMusicURLData:filePathstr];
//}
-(void)addBgMusic:(QXSongListModel *)music{
if (self.bgMusicArray.count == 0 && self.songModel == nil) {
[self.bgMusicArray addObject:music];
[self nextBgMusic];
}else{
[self.bgMusicArray addObject:music];
}
}
-(void)nextBgMusic{
if (self.bgMusicArray.count > 0) {
QXSongListModel *music = self.bgMusicArray.firstObject;
[self ktv_EndSing];
[self ktv_StartSing:YES withSong:music];
if (self.delegate && [self.delegate respondsToSelector:@selector(rtcEngineBackgroundMusicNextSong:)]) {
[self.delegate rtcEngineBackgroundMusicNextSong:music];
}
[self.bgMusicArray removeObject:self.songModel];
}else{
dispatch_async(dispatch_get_main_queue(), ^{
showToast(@"已经是最后一首了");
});
}
}
-(void)pausePlayMusic{
[self.ktvPlayer pause];
}
-(void)resumePlayMusic{
[self.ktvPlayer resume];
}
- (void)setUseMicrophone:(BOOL)useMicrophone {
_useMicrophone = useMicrophone;
[self.agoraKit adjustRecordingSignalVolume:useMicrophone ? 100 : 0];
}
- (void)onInitKTVCenterWithToken:(NSString*)token{
// 1. AgoraMusicContentCenter
AgoraMusicContentCenterConfig *config = [AgoraMusicContentCenterConfig new];
// App ID
config.appId = AgoraAuthId;
// ID ID RTC 使 uid 0
config.mccUid = QXGlobal.shareGlobal.loginModel.user_id.integerValue;
// Token
config.token = token;
// AgoraRtcEngineKit
config.rtcEngine = self.agoraKit;
_ktvAmcc = [AgoraMusicContentCenter sharedContentCenterWithConfig:config];
[_ktvAmcc registerEventDelegate:self];
//使
_ktvPlayer = [_ktvAmcc createMusicPlayerWithDelegate:self];
}
- (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;
// _screenParams.videoParams = videoParams;
}
return _screenParams;
}
- (CGSize)screenShareVideoDimension {
CGSize screenSize = UIScreen.mainScreen.bounds.size;
CGSize boundingSize = CGSizeMake(540, 960);
CGFloat mW = boundingSize.width / screenSize.width;
CGFloat mH = boundingSize.height / screenSize.height;
if (mH < mW) {
boundingSize.width = boundingSize.height / screenSize.height * screenSize.width;
} else if (mW < mH) {
boundingSize.height = boundingSize.width / screenSize.width * screenSize.height;
}
return boundingSize;
}
-(void)startScreenCapture{
// ///
//// [self prepareSystemBroadcaster];
//
// AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
// option.publishMicrophoneTrack = YES;
// option.publishMediaPlayerAudioTrack = YES;
// option.enableAudioRecordingOrPlayout = YES;
// option.publishScreenCaptureVideo = YES;
// option.publishScreenCaptureAudio = YES;
// option.publishCameraTrack = NO;
// option.clientRoleType = AgoraClientRoleBroadcaster;
// [self.agoraKit updateChannelWithMediaOptions:option];
// [self.agoraKit startScreenCapture:self.screenParams];
// [self.agoraKit muteLocalVideoStream:NO];
// [self.agoraKit enableVideo];
// [self.agoraKit enableLocalVideo:YES];
// [self prepareSystemBroadcaster];
// for (UIView *view in self.systemBroadcastPicker.subviews) {
// if ([view isKindOfClass:[UIButton class]]) {
// [((UIButton *)view) sendActionsForControlEvents:(UIControlEventAllEvents)];
// break;
// }
// }
// AgoraVideoEncoderConfiguration *encoderConfig = [[AgoraVideoEncoderConfiguration alloc] initWithSize:CGSizeMake(960, 540)
// frameRate:(AgoraVideoFrameRateFps15)
// bitrate:AgoraVideoBitrateStandard
// orientationMode:(AgoraVideoOutputOrientationModeFixedPortrait)
// mirrorMode:(AgoraVideoMirrorModeAuto)];
// [self.agoraKit setVideoEncoderConfiguration:encoderConfig];
//
// // set up local video to render your local camera preview
// AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
// videoCanvas.uid = QXGlobal.shareGlobal.loginModel.user_id.longLongValue;
// // the view to be binded
//// videoCanvas.view = self.localView.videoView;
// videoCanvas.renderMode = AgoraVideoRenderModeHidden;
// [self.agoraKit setupLocalVideo:videoCanvas];
// // you have to call startPreview to see local video
// [self.agoraKit startPreview];
// [self.agoraKit enableAudio];
// [self.agoraKit enableVideo];
[self.agoraKit setScreenCaptureScenario:AgoraScreenScenarioVideo];
self.option.clientRoleType = AgoraClientRoleBroadcaster;
[self.agoraKit updateChannelWithMediaOptions:self.option];
[self.agoraKit startScreenCapture:self.screenParams];
[self prepareSystemBroadcaster];
for (UIView *view in self.systemBroadcastPicker.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
[((UIButton *)view) sendActionsForControlEvents:(UIControlEventAllEvents)];
break;
}
}
}
- (void)prepareSystemBroadcaster {
CGRect frame = CGRectMake(0, 0, 60, 60);
self.systemBroadcastPicker = [[RPSystemBroadcastPickerView alloc]initWithFrame:frame];
self.systemBroadcastPicker.showsMicrophoneButton = NO;
self.systemBroadcastPicker.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
self.systemBroadcastPicker.preferredExtension = [NSString stringWithFormat:@"%@.QXLiveScreen",bundleId];
}
-(void)startPreViewWithUid:(NSInteger)uid view:(nonnull UIView *)view{
AgoraRtcVideoCanvas* videoCanvas = [[AgoraRtcVideoCanvas alloc]init];
videoCanvas.uid = uid;
videoCanvas.view = view;
videoCanvas.renderMode = AgoraVideoRenderModeFit;
videoCanvas.setupMode = AgoraVideoViewSetupAdd;
[self.agoraKit setupRemoteVideo:videoCanvas];
}
- (AgoraRtcChannelMediaOptions *)option {
if (_option == nil) {
_option = [[AgoraRtcChannelMediaOptions alloc] init];
_option.clientRoleType = AgoraClientRoleAudience;
_option.publishCameraTrack = NO;
_option.publishMicrophoneTrack = YES;
_option.publishScreenCaptureVideo = NO;
_option.publishScreenCaptureAudio = NO;
}
return _option;
}
@end

View File

@@ -0,0 +1,23 @@
//
// 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

View File

@@ -0,0 +1,97 @@
//
// 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

View File

@@ -0,0 +1,42 @@
//
// 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

View File

@@ -0,0 +1,141 @@
//
// 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

View File

@@ -0,0 +1,38 @@
//
// QXLocationManager.h
// YSDTrucksProject
//
// Created by 党凯 on 2020/7/17.
// Copyright © 2020 党凯. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol QXLocationManagerDelegate <NSObject>
@optional
-(void)locationSuccessWithCity:(NSString*_Nonnull)city province:(NSString*_Nonnull)province area:(NSString*_Nonnull)area address:(NSString*_Nonnull)address;
@end
NS_ASSUME_NONNULL_BEGIN
@interface QXLocationManager : NSObject
@property (nonatomic,weak)id<QXLocationManagerDelegate>delegate;
+(instancetype)shareManager;
/**
开始定位
*/
-(void)startLoction;
/**
结束定位
*/
-(void)stopLoction;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,155 @@
//
// QXLocationManager.m
// YSDTrucksProject
//
// Created by on 2020/7/17.
// Copyright © 2020 . All rights reserved.
//
#import "QXLocationManager.h"
@interface QXLocationManager()<CLLocationManagerDelegate>
@property (nonatomic,strong)CLLocationManager *lcManager;
@end
@implementation QXLocationManager
+(instancetype)shareManager{
static QXLocationManager *manager = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
manager = [[QXLocationManager alloc] init];
});
return manager;
}
- (instancetype)init
{
self = [super init];
if (self) {
// [AMapServices sharedServices].apiKey = mapKey;
// _locationManager = [[AMapLocationManager alloc] init];
// //
// [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
// // 2s2s
// _locationManager.locationTimeout =2;
// // 2s2s
// _locationManager.reGeocodeTimeout = 2;
// _locationManager.delegate = self;
// if ([CLLocationManager authorizationStatus]) {
//
self.lcManager = [[CLLocationManager alloc] init];
self.lcManager.delegate = self; //
// ()
self.lcManager.distanceFilter = 100;
self.lcManager.desiredAccuracy = kCLLocationAccuracyBest; // ()
[self.lcManager requestWhenInUseAuthorization];//
// [self.lcManager startUpdatingLocation]; //
// }else{
//
// //
//
// }
}
return self;
}
//-(void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{
// if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
// [locationManager requestAlwaysAuthorization];
// }
//}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(@"定位到了");
__weak typeof(self)weakSelf = self;
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:[locations firstObject] completionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError * _Nullable error) {
CLPlacemark *place = [placemarks firstObject];
//place
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(locationSuccessWithCity:province:area:address:)]) {
///
NSString *province = place.administrativeArea;
///
NSString *city = place.locality;
///
NSString *area = place.subLocality;
[weakSelf.delegate locationSuccessWithCity:place.locality province:province area:area address:place.name];
}
}];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"获取定位失败");
}
-(void)startLoction{
if (![self checkAuthorization]) {
UIAlertController *al = [UIAlertController alertControllerWithTitle:@"您没有打开定位权限" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
[al addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {
}]];
[al addAction:[UIAlertAction actionWithTitle:@"去设置" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
//
NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
}]];
[KEYWINDOW.rootViewController presentViewController:al animated:YES completion:nil];
// [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
// resultBlock(location,regeocode,error);
// }];
[self.lcManager startUpdatingLocation];
}else{
// [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
// resultBlock(location,regeocode,error);
// }];
[self.lcManager startUpdatingLocation];
}
}
-(void)stopLoction{
[self.lcManager stopUpdatingLocation];
}
//
-(BOOL)checkAuthorization{
BOOL result = NO;
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
switch (status) {
//
case kCLAuthorizationStatusDenied:
result = NO;
break;
//使
case kCLAuthorizationStatusNotDetermined:
result = YES;
break;
//
case kCLAuthorizationStatusRestricted:
result = NO;
break;
//App使
case kCLAuthorizationStatusAuthorizedAlways:
result = YES;
break;
//使使
case kCLAuthorizationStatusAuthorizedWhenInUse:
result = YES;
break;
default:
break;
}
return result;
}
@end

82
QXLive/Manager/QXManagerMqtt.h Executable file
View File

@@ -0,0 +1,82 @@
//
// ManagerMqtt.h
// SoundRiver
//
// Created by apple on 2020/3/19.
//
#import <Foundation/Foundation.h>
#import "MQTTClient.h"
#import "MQTTSessionManager.h"
#import <CommonCrypto/CommonHMAC.h>
//typedef NS_ENUM(NSInteger) {
// /// 巡乐会进度更新
// QXManagerMqttTypeAcProgress = 100,
// /// 巡乐会即将开始
// QXManagerMqttTypeAcWill = 101,
// /// 巡乐会已经开始
// QXManagerMqttTypeAcStart = 102,
// /// 巡乐会结束落包
// QXManagerMqttTypeAcEnd = 103,
// /// 有人锁定了礼物
// QXManagerMqttTypeAcLock = 103,
//}QXManagerMqttType;
/// 礼物话题
static NSString * _Nonnull qx_room_topic = @"qx_room_topic";
/// 巡乐会话题
static NSString * _Nonnull qx_ac_topic = @"qx_xunlehui";
/// 小时榜话题
static NSString * _Nonnull qx_hour_ranking = @"qx_hour_ranking";
/// 红包话题
static NSString * _Nonnull qx_red_redpacket = @"qx_redpacket_arrive";
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

251
QXLive/Manager/QXManagerMqtt.m Executable file
View File

@@ -0,0 +1,251 @@
//
// 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];
[MQTTLog setLogLevel:(DDLogLevelError)];
});
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 subscribeTopic:qx_ac_topic];
[self subscribeTopic:qx_hour_ranking];
[self subscribeTopic:qx_red_redpacket];
[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{
NSString *localPassword = [[NSUserDefaults standardUserDefaults] objectForKey:kChirldLocalPassword];
if ([localPassword isExist]) {
return;
}
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

View File

@@ -0,0 +1,50 @@
//
// QXRedPacketManager.h
// QXLive
//
// Created by 启星 on 2025/10/11.
//
#import <Foundation/Foundation.h>
#import "QXRedPacketModel.h"
@class QXRedPacketManager;
@protocol QXRedPacketManagerDelegate <NSObject>
/// 推送添加单个红包回调
- (void)QXRedPacketManager:(QXRedPacketManager *)manager didAddRedPacket:(QXRedPacketModel *)redPacket remainingCount:(NSInteger)remainingCount;
/// 首次获取房间内红包列表进行添加后回调
- (void)QXRedPacketManager:(QXRedPacketManager *)manager didAddRedPackets:(NSArray<QXRedPacketModel *>*)redPackets remainingCount:(NSInteger)remainingCount;
/// 红包从列表移除后的回调
- (void)QXRedPacketManager:(QXRedPacketManager *)manager didRemoveRedPacket:(NSString *)packetId remainingCount:(NSInteger)remainingCount;
/// 红包状态发生变化时回调(由不可抢到可抢)
- (void)QXRedPacketManager:(QXRedPacketManager *)manager didUpdateRedPacket:(QXRedPacketModel *)redPacket remainingCount:(NSInteger)remainingCount;
/// 红包状态发生变化时回调(由不可抢到可抢)
- (void)QXRedPacketManager:(QXRedPacketManager *)manager didUpdateRedPacketTime:(long)time redPacket:(QXRedPacketModel *)redPacket;
@end
@interface QXRedPacketManager : NSObject
@property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, QXRedPacketModel *> *redPackets;
@property (nonatomic, weak) id<QXRedPacketManagerDelegate> delegate;
+ (instancetype)sharedManager;
/// 批量添加红包
- (void)addRedPackets:(NSArray<QXRedPacketModel *>*)redPackets;
/// 添加红包
- (void)addRedPacket:(QXRedPacketModel *)redPacket;
/// 移除红包
- (void)removeRedPacket:(NSString *)packetId;
/// 获取所有红包
- (NSArray<QXRedPacketModel *> *)allRedPackets;
/// 根据红包id获取红包
- (QXRedPacketModel *)getRedPacket:(NSString *)packetId;
/// 检查并更新红包状态
- (void)checkAndUpdateRedPackets;
/// 移除所有红包
-(void)removeAllRedpackets;
/// 开启定时器
-(void)startCheckTimer;
/// 销毁定时器
-(void)endCheckTimer;
/// 回收内存
-(void)destoryRedpacketInfo;
@end

View File

@@ -0,0 +1,134 @@
//
// QXRedPacketManager.m
// QXLive
//
// Created by on 2025/10/11.
//
#import "QXRedPacketManager.h"
@interface QXRedPacketManager ()
@property (nonatomic, strong) NSMutableDictionary<NSString *, QXRedPacketModel *> *redPackets;
@property (nonatomic, strong) NSTimer *checkTimer;
@end
@implementation QXRedPacketManager
+ (instancetype)sharedManager {
static QXRedPacketManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[QXRedPacketManager alloc] init];
});
return instance;
}
- (instancetype)init {
self = [super init];
if (self) {
_redPackets = [NSMutableDictionary dictionary];
}
return self;
}
-(void)addRedPackets:(NSArray<QXRedPacketModel *> *)redPackets{
if (redPackets.count == 0) {
return;
}
for (QXRedPacketModel*md in redPackets) {
self.redPackets[md.redpacket_id] = md;
}
if ([self.delegate respondsToSelector:@selector(QXRedPacketManager:didAddRedPackets:remainingCount:)]) {
[self.delegate QXRedPacketManager:[QXRedPacketManager sharedManager] didAddRedPackets:redPackets remainingCount:self.redPackets.count];
}
}
- (void)addRedPacket:(QXRedPacketModel *)redPacket {
if (!redPacket.redpacket_id) return;
self.redPackets[redPacket.redpacket_id] = redPacket;
if ([self.delegate respondsToSelector:@selector(QXRedPacketManager:didAddRedPacket:remainingCount:)]) {
[self.delegate QXRedPacketManager:[QXRedPacketManager sharedManager] didAddRedPacket:redPacket remainingCount:self.redPackets.count];
}
}
- (void)removeRedPacket:(NSString *)packetId {
[self.redPackets removeObjectForKey:packetId];
if ([self.delegate respondsToSelector:@selector(QXRedPacketManager:didRemoveRedPacket:remainingCount:)]) {
[self.delegate QXRedPacketManager:[QXRedPacketManager sharedManager] didRemoveRedPacket:packetId remainingCount:self.redPackets.count];
}
}
- (NSArray<QXRedPacketModel *> *)allRedPackets {
return [self sortRedPacketsByOpenTime:[self.redPackets allValues]];
}
- (NSArray *)sortRedPacketsByOpenTime:(NSArray *)redPackets {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"start_time" ascending:YES];
NSArray *sortedArray = [redPackets sortedArrayUsingDescriptors:@[sortDescriptor]];
return sortedArray;
}
-(QXRedPacketModel *)getRedPacket:(NSString *)packetId{
return [self.redPackets objectForKey:packetId];
}
- (void)startCheckTimer {
self.checkTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(checkAndUpdateRedPackets)
userInfo:nil
repeats:YES];
}
- (void)checkAndUpdateRedPackets {
NSArray *packets = [self.allRedPackets copy];
for (QXRedPacketModel *packet in packets) {
//
long packetTime = [packet remainingTime];
if ((packetTime <= -packet.redpacket_time.intValue)) {
// 10
[self removeRedPacket:packet.redpacket_id];
}
if (packet.countdown.intValue == 0) {
continue;
}
if ([self.delegate respondsToSelector:@selector(QXRedPacketManager:didUpdateRedPacketTime:redPacket:)]) {
[self.delegate QXRedPacketManager:[QXRedPacketManager sharedManager] didUpdateRedPacketTime:packetTime redPacket:packet];
}
BOOL wasAvailable = packet.isAvailable;
packet.isAvailable = [packet canOpenNow];
//
if (wasAvailable != packet.isAvailable) {
if ([self.delegate respondsToSelector:@selector(QXRedPacketManager:didUpdateRedPacket:remainingCount:)]) {
[self.delegate QXRedPacketManager:[QXRedPacketManager sharedManager] didUpdateRedPacket:packet remainingCount:self.redPackets.count];
}
}
}
}
-(void)removeAllRedpackets{
[self.redPackets removeAllObjects];
}
-(void)endCheckTimer{
if (self.checkTimer) {
[self.checkTimer invalidate];
self.checkTimer = nil;
}
}
-(void)destoryRedpacketInfo{
[self removeAllRedpackets];
[self endCheckTimer];
self.delegate = nil;
}
- (void)dealloc {
if (self.checkTimer) {
[self.checkTimer invalidate];
self.checkTimer = nil;
}
}
@end

View File

@@ -0,0 +1,291 @@
//
// QXRoomMessageManager.h
// QXLive
//
// Created by 启星 on 2025/6/10.
//
#import <Foundation/Foundation.h>
#import "QXRoomChatListView.h"
#import "QXRoomModel.h"
#import "QXRoomFriendRelationModel.h"
#import "QXRedPacketModel.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,
/// 交友房阶段发生变化
QXRoomMessageTypeRoomFriendPartDidChanged = 1049,
/// 交友房时间发生延时
QXRoomMessageTypeRoomFriendDelayTime = 1050,
/// 交友房卡关系完成
QXRoomMessageTypeRoomFriendCreateRelation = 1051,
/// 私密小屋结束时间发生延时
QXRoomMessageTypeCabinTimeDelay = 1052,
/// 麦位发生变化
QXRoomMessageTypeSeatDidChanged = 1053,
/// 心动值发生变化
QXRoomMessageTypeHeartDidChanged = 1054,
/// 交友房私密小屋有人退出房间
QXRoomMessageTypeFriendRoomQuit = 1055,
/// 巡乐会盘进度更新
QXRoomMessageTypeMeetActivityProgressUpdate = 1056,
/// 巡乐会盘抽奖结果更新
QXRoomMessageTypeMeetActivityDrawGift = 1057,
/// 离线
QXRoomMessageTypeRoomUserOnlineStatus = 1058,
/// 清除个人魅力
QXRoomMessageTypeRoomClearUserCharm = 1059,
/// 发红包
QXRoomMessageTypeSendRedpacket = 1060,
/// 红包已被抢完
QXRoomMessageTypeRedpacketFinished = 1061,
}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)didRecieveGiftWithWithUserInfos:(NSArray<QXUserHomeModel*>*)userInfos;
/// 用户禁言禁麦状态发生变化
-(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)roomSeatExchangedWithFromPitNumber:(NSInteger)fromPitNumber toPitNumber:(NSInteger)toPitNumber userInfo:(QXUserHomeModel*)userInfo;
/// 拍卖者被拉上麦
-(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;
/// 交友房
/// 交友房阶段发生变化 step 阶段 1等待 2心动 3牵手 friend_id 场次id
-(void)friendPartDidChangedWithType:(NSString*)step friend_id:(NSString*)friend_id end_time:(NSString*)end_time relationModel:(QXRoomFriendRelationModel*)relationModel;
/// 交友房时间发生延时 end_time 截止时间
-(void)friendTimeDelayWithTime:(NSString*)end_time;
/// 交友房麦位发生变化
-(void)friendSeatDidChanged:(NSArray<QXRoomPitModel*>*)pitArray;
/// 心动值发生变化
-(void)friendHeartNumberDidChanged:(NSArray<QXRoomFriendHeartListModel*>*)heartArray;
/// 关系创建完成
-(void)friendRelationIsCreatedWithrelationModel:(QXRoomFriendRelationModel*)relationModel;
/// 有人退出交友房私密小屋
-(void)friendCabinRoomIsQuit;
/// 私密小屋时间发生延时
-(void)friendCabinRoomTimeDelayWithTime:(NSString*)end_time;
/// 巡乐会进度更新
-(void)meetActivityProgressIsUpdate:(NSDictionary*)updateDict;
/// 巡乐会礼物发生变化
-(void)meetActivityGiftInfoIsUpdate:(QXRoomChatListModel*)giftInfo;
/// 清除个人魅力
-(void)roomClearUserCharmWithUserId:(NSString*)userId;
/// 发红包
-(void)recievedRedPacket:(QXRedPacketModel*)model;
/// 红包
-(void)redPacketDidFinished:(NSString*)redpacket_id;
/// 房间用户在线状态发生变化
//-(void)roomUserOnlineStatusDidChanged:(BOOL)isOnline userId:(NSString*)userId;
@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

View File

@@ -0,0 +1,789 @@
//
// 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;
@property (nonatomic,strong)NSString *roomId;
@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:self.groupId];
}
[[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;
weakSelf.roomId = roomId;
} fail:^(int code, NSString *desc) {
//
QXLOG(@"腾讯IM加入聊天室失败-code%d-原因%@",code,desc);
}];
}
-(void)quitGroupWithRoomId:(NSString *)roomId{
MJWeakSelf
self.groupId = nil;
self.roomId = 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:jia_jia];
}
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;
NSArray *arr = [model.GiftInfo.play_image componentsSeparatedByString:@","];
[[QXGiftPlayerManager shareManager] displayFullEffectViewWithMorePlayImages:arr];
if (model.ToUserInfos.count>0) {
if (self.delegate && [self.delegate respondsToSelector:@selector(didRecieveGiftWithWithUserInfos:)]) {
[self.delegate didRecieveGiftWithWithUserInfos:model.ToUserInfos];
}
}else{
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 = QXRoomChatMessageTypeGift;
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;
///
case QXRoomMessageTypeRoomFriendPartDidChanged:{
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
if (self.delegate && [self.delegate respondsToSelector:@selector(friendPartDidChangedWithType:friend_id:end_time:relationModel:)]) {
[self.delegate friendPartDidChangedWithType:model.step friend_id:model.friend_id end_time:model.end_time relationModel:model.friend_user];
}
if (model.step.intValue != 3) {
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
model.messageType = QXRoomChatMessageTypeSystem;
[self.delegate didInsertMessge:model];
}
}
}
break;
case QXRoomMessageTypeRoomFriendDelayTime:{
NSString *end_time = [NSString stringWithFormat:@"%@",msg.Text[@"end_time"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(friendTimeDelayWithTime:)]) {
[self.delegate friendTimeDelayWithTime:end_time];
}
}
break;
case QXRoomMessageTypeSeatDidChanged:{
NSArray *pitArray = [NSArray yy_modelArrayWithClass:[QXRoomPitModel class] json:msg.Text[@"list"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(friendSeatDidChanged:)]) {
[self.delegate friendSeatDidChanged:pitArray];
}
}
break;
case QXRoomMessageTypeHeartDidChanged:{
NSArray *heartArray = [NSArray yy_modelArrayWithClass:[QXRoomFriendHeartListModel class] json:msg.Text[@"list"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(friendHeartNumberDidChanged:)]) {
[self.delegate friendHeartNumberDidChanged:heartArray];
}
}
break;
case QXRoomMessageTypeRoomFriendCreateRelation:{
QXRoomFriendRelationModel *relationModel = [QXRoomFriendRelationModel yy_modelWithJSON:msg.Text];
if (self.delegate && [self.delegate respondsToSelector:@selector(friendRelationIsCreatedWithrelationModel:)]) {
[self.delegate friendRelationIsCreatedWithrelationModel:relationModel];
}
}
break;
case QXRoomMessageTypeFriendRoomQuit:{
if (self.delegate && [self.delegate respondsToSelector:@selector(friendCabinRoomIsQuit)]) {
[self.delegate friendCabinRoomIsQuit];
}
}
break;
case QXRoomMessageTypeCabinTimeDelay:{
NSString *end_time = [NSString stringWithFormat:@"%@",msg.Text[@"time_day"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(friendCabinRoomTimeDelayWithTime:)]) {
[self.delegate friendCabinRoomTimeDelayWithTime:end_time];
}
}
break;
case QXRoomMessageTypeMeetActivityProgressUpdate:{
NSDictionary *progressDict = msg.Text;
if (self.delegate && [self.delegate respondsToSelector:@selector(meetActivityProgressIsUpdate:)]) {
[self.delegate meetActivityProgressIsUpdate:progressDict];
}
}
break;
case QXRoomMessageTypeMeetActivityDrawGift:{
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
if (self.delegate && [self.delegate respondsToSelector:@selector(meetActivityGiftInfoIsUpdate:)]) {
[self.delegate meetActivityGiftInfoIsUpdate:model];
}
}
break;
case QXRoomMessageTypeRoomDidFire:{
QXRoomChatListModel *model = [QXRoomChatListModel yy_modelWithJSON:msg.Text];
NSInteger fromPitNumber = [msg.Text[@"from_pit_number"] integerValue];
NSInteger toPitNumber = [msg.Text[@"to_pit_number"] integerValue];
if (self.delegate && [self.delegate respondsToSelector:@selector(roomSeatExchangedWithFromPitNumber:toPitNumber:userInfo:)]) {
[self.delegate roomSeatExchangedWithFromPitNumber:fromPitNumber toPitNumber:toPitNumber userInfo:model.FromUserInfo];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(didInsertMessge:)]) {
model.messageType = QXRoomChatMessageTypeSystem;
[self.delegate didInsertMessge:model];
}
}
break;
case QXRoomMessageTypeRoomClearUserCharm:{
NSString *userId = [NSString stringWithFormat:@"%@",msg.Text[@"user_id"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(roomClearUserCharmWithUserId:)]) {
[self.delegate roomClearUserCharmWithUserId:userId];
}
}
break;
case QXRoomMessageTypeRoomUserOnlineStatus:{
NSString *userId = [NSString stringWithFormat:@"%@",msg.Text[@"user_id"]];
// 1 线 2线
NSInteger type = 1;
type = [msg.Text[@"type"] integerValue];
BOOL isOnline = type == 1?YES:NO;
// if (self.delegate && [self.delegate respondsToSelector:@selector(roomUserOnlineStatusDidChanged:userId:)]) {
// [self.delegate roomUserOnlineStatusDidChanged:YES userId:userId];
// }
NSDictionary *parm = @{
@"user_id":userId,
@"is_online":[NSNumber numberWithBool:isOnline],
};
[[NSNotificationCenter defaultCenter] postNotificationName:noticeRoomUserOnlineStatusDidChanged object:parm];
}
break;
case QXRoomMessageTypeSendRedpacket:{
QXRedPacketModel *model = [QXRedPacketModel yy_modelWithJSON:msg.Text[@"redpacketInfo"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(recievedRedPacket:)]) {
[self.delegate recievedRedPacket:model];
}
}
break;
case QXRoomMessageTypeRedpacketFinished:{
NSString *redpacket_id = [NSString stringWithFormat:@"%@",msg.Text[@"redpacket_id"]];
if (self.delegate && [self.delegate respondsToSelector:@selector(redPacketDidFinished:)]) {
[self.delegate redPacketDidFinished:redpacket_id];
}
}
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];
if ([groupID isEqualToString:self.groupId]) {
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.roomId?self.roomId:@"",
@"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.roomId?self.roomId:@"",
@"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