diff --git a/Podfile b/Podfile index 4fd3dc64..b6a8908b 100644 --- a/Podfile +++ b/Podfile @@ -33,6 +33,9 @@ target 'xplan-ios' do pod 'BaiduMobStatCodeless', '~> 5.3.5' #文字自动滚动 pod 'MarqueeLabel-ObjC' + + #声网 + pod 'AgoraRtcEngine_iOS', '~> 3.0.1' #登录的 pod 'mob_sharesdk' diff --git a/Podfile.lock b/Podfile.lock index b5744f35..053457af 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -14,6 +14,7 @@ PODS: - AFNetworking/Serialization (4.0.1) - AFNetworking/UIKit (4.0.1): - AFNetworking/NSURLSession + - AgoraRtcEngine_iOS (3.0.1.1) - BaiduMobStatCodeless (5.3.5) - Base64 (1.1.2) - FFPopup (1.1.5) @@ -54,6 +55,7 @@ PODS: DEPENDENCIES: - AFNetworking + - AgoraRtcEngine_iOS (~> 3.0.1) - BaiduMobStatCodeless (~> 5.3.5) - Base64 - FFPopup @@ -79,6 +81,7 @@ DEPENDENCIES: SPEC REPOS: trunk: - AFNetworking + - AgoraRtcEngine_iOS - BaiduMobStatCodeless - Base64 - FFPopup @@ -102,6 +105,7 @@ SPEC REPOS: SPEC CHECKSUMS: AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce + AgoraRtcEngine_iOS: 8ccceaaecff2e80ab28fcd33f3dfd2b417eb5365 BaiduMobStatCodeless: b3c73335cc1a5d464540111ff08857fc33cae656 Base64: cecfb41a004124895a7bcee567a89bae5a89d49b FFPopup: a208dcee8db3e54ec4a88fcd6481f6f5d85b7a83 @@ -123,6 +127,6 @@ SPEC CHECKSUMS: SZTextView: 094dc6acc9beec537685c545d6e3e0d4975174e1 YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 -PODFILE CHECKSUM: 359c488aca65b2f81870e252d1da6f7da7b45dd5 +PODFILE CHECKSUM: 10f014ae106af90b11a01aa549879c0e566b93e3 COCOAPODS: 1.10.1 diff --git a/xplan-ios.xcodeproj/project.pbxproj b/xplan-ios.xcodeproj/project.pbxproj index 78f07081..23b4d3b9 100644 --- a/xplan-ios.xcodeproj/project.pbxproj +++ b/xplan-ios.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 18486213271EA9DA005FC5DC /* RtcManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 18486212271EA9DA005FC5DC /* RtcManager.m */; }; + 18486217271EAB8C005FC5DC /* BaseRtcImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = 18486216271EAB8C005FC5DC /* BaseRtcImpl.m */; }; + 18486235271EB794005FC5DC /* AgoraRtcImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = 18486234271EB794005FC5DC /* AgoraRtcImpl.m */; }; 186A52E026FC559200D67B2C /* SecurityGuardSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186A52DA26FC559200D67B2C /* SecurityGuardSDK.framework */; }; 186A52E126FC559200D67B2C /* SGSecurityBody.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186A52DB26FC559200D67B2C /* SGSecurityBody.framework */; }; 186A52E226FC559200D67B2C /* RPSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186A52DC26FC559200D67B2C /* RPSDK.framework */; }; @@ -248,6 +251,13 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 18486211271EA9DA005FC5DC /* RtcManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RtcManager.h; sourceTree = ""; }; + 18486212271EA9DA005FC5DC /* RtcManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RtcManager.m; sourceTree = ""; }; + 18486214271EAA03005FC5DC /* RtcDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RtcDelegate.h; sourceTree = ""; }; + 18486215271EAB8C005FC5DC /* BaseRtcImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseRtcImpl.h; sourceTree = ""; }; + 18486216271EAB8C005FC5DC /* BaseRtcImpl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseRtcImpl.m; sourceTree = ""; }; + 18486233271EB794005FC5DC /* AgoraRtcImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AgoraRtcImpl.h; sourceTree = ""; }; + 18486234271EB794005FC5DC /* AgoraRtcImpl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AgoraRtcImpl.m; sourceTree = ""; }; 186A52DA26FC559200D67B2C /* SecurityGuardSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SecurityGuardSDK.framework; sourceTree = ""; }; 186A52DB26FC559200D67B2C /* SGSecurityBody.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SGSecurityBody.framework; sourceTree = ""; }; 186A52DC26FC559200D67B2C /* RPSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RPSDK.framework; sourceTree = ""; }; @@ -674,6 +684,20 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 18486210271EA9A5005FC5DC /* RTC */ = { + isa = PBXGroup; + children = ( + 18486211271EA9DA005FC5DC /* RtcManager.h */, + 18486212271EA9DA005FC5DC /* RtcManager.m */, + 18486214271EAA03005FC5DC /* RtcDelegate.h */, + 18486215271EAB8C005FC5DC /* BaseRtcImpl.h */, + 18486216271EAB8C005FC5DC /* BaseRtcImpl.m */, + 18486233271EB794005FC5DC /* AgoraRtcImpl.h */, + 18486234271EB794005FC5DC /* AgoraRtcImpl.m */, + ); + path = RTC; + sourceTree = ""; + }; 186A52D826FC551700D67B2C /* Library */ = { isa = PBXGroup; children = ( @@ -906,6 +930,7 @@ 189DD56126DE45F800AB55B1 /* Main */ = { isa = PBXGroup; children = ( + 18486210271EA9A5005FC5DC /* RTC */, E8AEAED3271412D00017FCE0 /* Room */, E8E70D6E26F2EB1200F03460 /* Mine */, 18E7B1B426E8B2960064BC9B /* Tabbar */, @@ -1984,6 +2009,7 @@ 189DD73F26E21C3F00AB55B1 /* YYUtility+Carrier.m in Sources */, 18E7B26926E8D5D60064BC9B /* XCCurrentVCStackManager.m in Sources */, E824544326F58FCE00BE8163 /* XPMinePayPwdInputView.m in Sources */, + 18486235271EB794005FC5DC /* AgoraRtcImpl.m in Sources */, 9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */, E8EEB8F426FC2050007C6EBA /* SDBrowserImageView.m in Sources */, E824544626F5934700BE8163 /* XPMinePayPwdPresenter.m in Sources */, @@ -2020,6 +2046,7 @@ E8AEAEF327141C7C0017FCE0 /* XPRoomMessageContainerView.m in Sources */, E8AE427327153A3500BEEBB2 /* XPRoomActivityContainerView.m in Sources */, E86596432701611A00846EBD /* UIImage+ImageEffects.m in Sources */, + 18486217271EAB8C005FC5DC /* BaseRtcImpl.m in Sources */, E8CEA03D26EA3DE500644B44 /* LoginPasswordPresent.m in Sources */, E8E70D7726F2F15100F03460 /* XPMineViewController.m in Sources */, E8AC722C26F49580007D6E91 /* XPMineNotificaViewController.m in Sources */, @@ -2047,6 +2074,7 @@ E8EEB90926FC579A007C6EBA /* XPMineUserInfoEditTableViewCell.m in Sources */, 18C17A5D26F338F300C48E11 /* XplanFBFlutterViewContainer.m in Sources */, E89DA67527009ACD008483C1 /* XPMineRechargeNavView.m in Sources */, + 18486213271EA9DA005FC5DC /* RtcManager.m in Sources */, 186A536926FC6F2E00D67B2C /* XCShareView.m in Sources */, 186A534C26FC6ED900D67B2C /* TTAlertView.m in Sources */, E868070A271959DB0024F48F /* XPRoomPositionView.m in Sources */, diff --git a/xplan-ios/Global/XPConstant.h b/xplan-ios/Global/XPConstant.h index ec8bdcb8..643ecf61 100644 --- a/xplan-ios/Global/XPConstant.h +++ b/xplan-ios/Global/XPConstant.h @@ -22,6 +22,7 @@ typedef NS_ENUM(NSUInteger, KeyType) { KeyType_QQSecret, ///QQ 的 secret KeyType_WechatAppid,///微信的 appid KeyType_WechatSecret,///微信的 secret + KeyType_Agora,///声网 key }; /// 获取当前项目中所用到的 type 所对应的 value 的值 type 类型 diff --git a/xplan-ios/Global/XPConstant.m b/xplan-ios/Global/XPConstant.m index a045f847..da26bbce 100644 --- a/xplan-ios/Global/XPConstant.m +++ b/xplan-ios/Global/XPConstant.m @@ -19,21 +19,23 @@ NSString * const KeyWithType(KeyType type) { NSDictionary * dic = @{ ///正式环境 @(YES):@{ - @(KeyType_PasswordEncode): @"1ea53d260ecf11e7b56e00163e046a26", - @(KeyType_NTESQuickLoginBusinessId): @"09c1214706c34f4798d3f05d86148608", - @(KeyType_QQAppid) : @"101937205", - @(KeyType_QQSecret) : @"458ed9d671ba4b177799189db5fbc434", - @(KeyType_WechatAppid) : @"wx3f0462eb7eccd64f", - @(KeyType_WechatSecret) : @"1c07949e3f53433f1c6038bfcdd54c40", + @(KeyType_PasswordEncode) : @"1ea53d260ecf11e7b56e00163e046a26", + @(KeyType_NTESQuickLoginBusinessId) : @"09c1214706c34f4798d3f05d86148608", + @(KeyType_QQAppid) : @"101937205", + @(KeyType_QQSecret) : @"458ed9d671ba4b177799189db5fbc434", + @(KeyType_WechatAppid) : @"wx3f0462eb7eccd64f", + @(KeyType_WechatSecret) : @"1c07949e3f53433f1c6038bfcdd54c40", + @(KeyType_Agora) : @"7ae1a8dabe7a44a9a67c829faa409e70", }, ///测试环境 @(NO):@{ - @(KeyType_PasswordEncode): @"1ea53d260ecf11e7b56e00163e046a26", - @(KeyType_NTESQuickLoginBusinessId): @"09c1214706c34f4798d3f05d86148608", - @(KeyType_QQAppid) : @"101937205", - @(KeyType_QQSecret) : @"458ed9d671ba4b177799189db5fbc434", - @(KeyType_WechatAppid) : @"wx3f0462eb7eccd64f", - @(KeyType_WechatSecret) : @"1c07949e3f53433f1c6038bfcdd54c40", + @(KeyType_PasswordEncode) : @"1ea53d260ecf11e7b56e00163e046a26", + @(KeyType_NTESQuickLoginBusinessId) : @"09c1214706c34f4798d3f05d86148608", + @(KeyType_QQAppid) : @"101937205", + @(KeyType_QQSecret) : @"458ed9d671ba4b177799189db5fbc434", + @(KeyType_WechatAppid) : @"wx3f0462eb7eccd64f", + @(KeyType_WechatSecret) : @"1c07949e3f53433f1c6038bfcdd54c40", + @(KeyType_Agora) : @"7ae1a8dabe7a44a9a67c829faa409e70", } }; NSDictionary * enviroDic = [dic objectForKey:@(isRelease)]; diff --git a/xplan-ios/Main/RTC/AgoraRtcImpl.h b/xplan-ios/Main/RTC/AgoraRtcImpl.h new file mode 100644 index 00000000..b1c2fc01 --- /dev/null +++ b/xplan-ios/Main/RTC/AgoraRtcImpl.h @@ -0,0 +1,16 @@ +// +// AgoraRtcImpl.h +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import "BaseRtcImpl.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface AgoraRtcImpl : BaseRtcImpl + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/RTC/AgoraRtcImpl.m b/xplan-ios/Main/RTC/AgoraRtcImpl.m new file mode 100644 index 00000000..51ea5117 --- /dev/null +++ b/xplan-ios/Main/RTC/AgoraRtcImpl.m @@ -0,0 +1,66 @@ +// +// AgoraRtcImpl.m +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import "AgoraRtcImpl.h" +#import "XPConstant.h" +#import + +@interface AgoraRtcImpl() + +@property(nonatomic, strong) AgoraRtcEngineKit *engine; + +@end + +@implementation AgoraRtcImpl + +- (instancetype)init +{ + self = [super init]; + if (self) { + _engine = [AgoraRtcEngineKit sharedEngineWithAppId:KeyWithType(KeyType_Agora) delegate:self]; + [_engine setChannelProfile:AgoraChannelProfileLiveBroadcasting]; + [_engine enableLastmileTest]; + [_engine setParameters:@"{\"che.audio.keep.audiosession\":true}"]; + [_engine enableAudio]; + [_engine disableVideo]; + [_engine enableAudioVolumeIndication:900 smooth:3 report_vad:YES]; + [_engine setAudioProfile:AgoraAudioProfileMusicStandard scenario:AgoraAudioScenarioChatRoomEntertainment]; +#ifdef DEBUG + [_engine setLogFilter:AgoraLogFilterInfo]; +#else + [_engine setLogFilter:0]; +#endif + } + return self; +} + +#pragma mark - RtcDelegate impl +- (void)joinChannel:(nonnull NSString *)channelId { + [self.engine setClientRole:AgoraClientRoleAudience]; + int code = [self.engine joinChannelByToken:nil channelId:channelId info:nil uid:[[[AccountInfoStorage instance] getUid] integerValue] joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) { + // TODO: success + }]; + if (code != 0) { + // TODO: fail + + } +} + +- (void)broadcast:(BOOL)on { + [self.engine setClientRole:on ? AgoraClientRoleBroadcaster : AgoraClientRoleAudience]; + [self.engine muteLocalAudioStream:!on]; +} + +- (void)exitChannel { + [self.engine leaveChannel:nil]; +} + +- (void)destory { + [AgoraRtcEngineKit destroy]; +} + +@end diff --git a/xplan-ios/Main/RTC/BaseRtcImpl.h b/xplan-ios/Main/RTC/BaseRtcImpl.h new file mode 100644 index 00000000..74953a36 --- /dev/null +++ b/xplan-ios/Main/RTC/BaseRtcImpl.h @@ -0,0 +1,18 @@ +// +// RTCBaseImpl.h +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import +#import "RtcDelegate.h" +#import "AccountInfoStorage.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface BaseRtcImpl : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/RTC/BaseRtcImpl.m b/xplan-ios/Main/RTC/BaseRtcImpl.m new file mode 100644 index 00000000..3e753e12 --- /dev/null +++ b/xplan-ios/Main/RTC/BaseRtcImpl.m @@ -0,0 +1,17 @@ +// +// RTCBaseImpl.m +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import "BaseRtcImpl.h" + +@implementation BaseRtcImpl + +- (void)joinChannel:(NSString *)channelId broadcast:(BOOL)on { + [self joinChannel:channelId]; + [self broadcast:on]; +} + +@end diff --git a/xplan-ios/Main/RTC/RtcDelegate.h b/xplan-ios/Main/RTC/RtcDelegate.h new file mode 100644 index 00000000..588f96a7 --- /dev/null +++ b/xplan-ios/Main/RTC/RtcDelegate.h @@ -0,0 +1,37 @@ +// +// RTCDelegate.h +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol RtcDelegate + +/** + 加入频道(房间) + */ +- (void)joinChannel:(NSString *)channelId; +/** + 上下麦(说话) + */ +- (void)broadcast:(BOOL)on; +/** + 加入频道同时上麦 + */ +- (void)joinChannel:(NSString *)channelId broadcast:(BOOL)on; +/** + 退出频道 + */ +- (void)exitChannel; +/** + 销毁引擎 + */ +- (void)destory; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/RTC/RtcManager.h b/xplan-ios/Main/RTC/RtcManager.h new file mode 100644 index 00000000..187c6a78 --- /dev/null +++ b/xplan-ios/Main/RTC/RtcManager.h @@ -0,0 +1,32 @@ +// +// RTCManager.h +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import +#import "RtcDelegate.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef enum : NSUInteger { + RtcEngineType_Zego,//即构 + RtcEngineType_Agora,//声网 + RtcEngineType_WJ,//无界 + RtcEngineType_AgoraFast,//声网急速 +} RtcEngineType; + +@interface RtcManager : NSObject + +@property (nonatomic, strong, readonly) id engine; + ++ (instancetype _Nonnull)sharedEngineWithType:(RtcEngineType)type; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +- (id)copy NS_UNAVAILABLE; +- (id)mutableCopy NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/RTC/RtcManager.m b/xplan-ios/Main/RTC/RtcManager.m new file mode 100644 index 00000000..a4d9a8d6 --- /dev/null +++ b/xplan-ios/Main/RTC/RtcManager.m @@ -0,0 +1,56 @@ +// +// RTCManager.m +// xplan-ios +// +// Created by zu on 2021/10/19. +// + +#import "RtcManager.h" +#import "AgoraRtcImpl.h" + +@interface RtcManager() + +@property (nonatomic, strong, readwrite) id engine; +@property (nonatomic, assign) RtcEngineType engineType; + +@end + +@implementation RtcManager + ++ (instancetype)sharedEngineWithType:(RtcEngineType)type { + static dispatch_once_t onceToken; + static RtcManager *instance = nil; + dispatch_once(&onceToken,^{ + instance = [[self alloc] init]; + }); + [instance setEngineType:type]; + return instance; +} + +- (void) setEngineType:(RtcEngineType)type { + if (_engine && type != _engineType) { + [_engine exitChannel]; + [_engine destory]; + _engine = nil; + } + _engineType = type; +} + +- (id)engine { + if (!_engine) { + switch (_engineType) { + case RtcEngineType_Agora: { + _engine = [[AgoraRtcImpl alloc] init]; + } + break; + + default: { + _engine = [[AgoraRtcImpl alloc] init]; + } + break; + } + } + return _engine; +} + +@end