KSCloudWebManager.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. //
  2. // KSCloudWebManager.m
  3. // KulexiuSchoolStudent
  4. //
  5. // Created by 王智 on 2024/1/19.
  6. //
  7. #import "KSCloudWebManager.h"
  8. #import <CloudAccompanyLibrary/CloudWebConfig.h>
  9. #import <CloudAccompanyLibrary/KSCloudWebViewController.h>
  10. #import <KSToolLibrary/RecordCheckManager.h>
  11. #import "KSPremissionAlert.h"
  12. #import "KSBaseWKWebViewController.h"
  13. #import "KSMediaMergeView.h"
  14. #import <KSToolLibrary/UIDevice+TFDevice.h>
  15. #import "AppDelegate+AppService.h"
  16. #import "AccompanyLoadingView.h"
  17. #import "KSWebLoadRefreshView.h"
  18. @interface KSCloudWebManager ()<KSCloudWebViewControllerDelegate>
  19. @property (nonatomic, strong) AccompanyLoadingView *customLoading;
  20. @property (nonatomic, strong) KSWebLoadRefreshView *errorView;
  21. @end
  22. @implementation KSCloudWebManager
  23. + (instancetype)shareInstance {
  24. static KSCloudWebManager *manager = nil;
  25. static dispatch_once_t onceToken;
  26. dispatch_once(&onceToken, ^{
  27. manager = [[KSCloudWebManager alloc] init];
  28. });
  29. return manager;
  30. }
  31. - (void)configCloudWebSource {
  32. CLOUD_CONFIG.scrpit_name = SCRIPT_NAME;
  33. CLOUD_CONFIG.agent_name = AGENT_NAME;
  34. CLOUD_CONFIG.agent_domain = AGENT_DOMAIN;
  35. CLOUD_CONFIG.token_type = UserDefault(Token_type);
  36. CLOUD_CONFIG.current_token = UserDefault(TokenKey);
  37. CLOUD_CONFIG.user_ID = UserDefault(UIDKey);
  38. CLOUD_CONFIG.socket_host = SOCKET_URL;
  39. CLOUD_CONFIG.authFilePath = CERT_PATH;
  40. CLOUD_CONFIG.need_auth = SSL_AUTH;
  41. CLOUD_CONFIG.themeColor = CLIENT_THEMECOLOR;
  42. CLOUD_CONFIG.soundFilePath = [[NSBundle mainBundle] pathForResource:@"synthgms" ofType:@"sf2"];
  43. }
  44. - (void)showWebView:(NSDictionary *)parm fromController:(CustomNavViewController *)navCtrl {
  45. // 先检测相机 再检测麦克风
  46. [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
  47. [self afterCheckCameraCheckMic:type parm:parm fromController:navCtrl];
  48. }];
  49. }
  50. - (void)afterCheckCameraCheckMic:(PREMISSIONTYPE)cameraType parm:(NSDictionary *)sourceParm fromController:(CustomNavViewController *)navCtrl {
  51. [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
  52. if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
  53. NSDictionary *valueDic = [sourceParm ks_dictionaryValueForKey:@"content"];
  54. KSCloudWebViewController *ctrl = [[KSCloudWebViewController alloc] init];
  55. ctrl.webViewDelegate = self;
  56. ctrl.url = [valueDic ks_stringValueForKey:@"url"];
  57. ctrl.parmDic = valueDic;
  58. NSInteger orientation = [valueDic ks_integerValueForKey:@"orientation"];
  59. BOOL isLandScape = orientation == 0 ? YES : NO;
  60. ctrl.ks_landScape = isLandScape;
  61. [navCtrl pushViewController:ctrl animated:YES];
  62. }
  63. else { //
  64. NSString *content = @"";
  65. CHECKDEVICETYPE checkType = CHECKDEVICETYPE_BOTH;
  66. if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
  67. content = @"请开启相机和麦克风访问权限";
  68. checkType = CHECKDEVICETYPE_BOTH;
  69. }
  70. else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
  71. content = @"请开启相机访问权限";
  72. checkType = CHECKDEVICETYPE_CAMREA;
  73. }
  74. else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
  75. content = @"请开启麦克风访问权限";
  76. checkType = CHECKDEVICETYPE_MIC;
  77. }
  78. [self showAlertWithMessage:content type:checkType];
  79. }
  80. }];
  81. }
  82. - (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
  83. [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:[NSObject getKeyWindow] cancel:^{
  84. } confirm:^{
  85. [self openSettingView];
  86. }];
  87. }
  88. - (void)openSettingView {
  89. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
  90. }
  91. // 回调权限
  92. - (void)NotiferShowPremissAlert:(NSString *)message {
  93. [KSPremissionAlert shareInstanceDisplayImage:CHECKDEVICETYPE_BOTH message:message showInView:[NSObject getKeyWindow] cancel:^{
  94. } confirm:^{
  95. [self openSettingView];
  96. }];
  97. }
  98. // 下载
  99. - (void)notiferDownloadFileUrl:(NSString *)url success:(void (^)(NSURL * _Nonnull, NSString * _Nonnull))success faliure:(void (^)(void))faliure {
  100. [KSNetworkingManager downloadFileRequestWithFileUrl:url progress:^(int64_t bytesRead, int64_t totalBytes) {
  101. } success:^(NSURL * _Nonnull fileUrl) {
  102. if (success) {
  103. success(fileUrl,url);
  104. }
  105. } faliure:^(NSError * _Nonnull error) {
  106. if (faliure) {
  107. faliure();
  108. }
  109. }];
  110. }
  111. // 上传
  112. - (void)uploadFile:(NSString *)uploadFileUrl success:(void (^)(NSString * _Nonnull))success faliure:(void (^)(NSString * _Nonnull))faliure {
  113. [LOADING_MANAGER showCustomLoading:@"上传中..."];
  114. NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:uploadFileUrl]];
  115. NSString *suffix = [NSString stringWithFormat:@".%@",[uploadFileUrl pathExtension]];
  116. [UPLOAD_MANAGER configWithfilePath:@"/user/"];
  117. [UPLOAD_MANAGER videoUpload:fileData fileName:@"video" fileSuffix:suffix progress:^(int64_t bytesWritten, int64_t totalBytes) {
  118. // 显示进度
  119. int progress = (int)(bytesWritten / totalBytes * 100);
  120. __block NSString *tipsMessage = [NSString stringWithFormat:@"上传中 %d%%",progress];
  121. dispatch_main_async_safe(^{
  122. [LOADING_MANAGER.loadingView setDisplayText:tipsMessage];
  123. });
  124. } successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
  125. [LOADING_MANAGER removeCustomLoading];
  126. NSString *fileUrl = [fileUrlArray lastObject];
  127. success(fileUrl);
  128. } faliure:^(NSError * _Nullable error, NSString * _Nullable descMessaeg) {
  129. [LOADING_MANAGER removeCustomLoading];
  130. faliure(descMessaeg);
  131. }];
  132. }
  133. #pragma mark ------- KSCloudWebViewControllerDelegate
  134. - (void)openWebViewWithParm:(NSDictionary *)parm inNavController:(UINavigationController *)navController {
  135. KSBaseWKWebViewController *detailCtrl = [[KSBaseWKWebViewController alloc] init];
  136. detailCtrl.url = [parm ks_stringValueForKey:@"url"];
  137. detailCtrl.parmDic = parm;
  138. NSInteger orientation = [parm ks_integerValueForKey:@"orientation"];
  139. BOOL isLandScape = orientation == 0 ? YES : NO;
  140. detailCtrl.ks_landScape = isLandScape;
  141. // if ([parm ks_boolValueForKey:@"showLoadingAnim"]) {
  142. // [detailCtrl showCoursewareLoading];
  143. // }
  144. [navController pushViewController:detailCtrl animated:YES];
  145. }
  146. - (void)showMergeViewWithParm:(NSDictionary *)parm displayInView:(UIView *)displayView callBackController:(KSCloudWebViewController *)controller {
  147. KSMediaMergeView *mergeView = [[KSMediaMergeView alloc] init];
  148. [displayView addSubview:mergeView];
  149. [mergeView mas_makeConstraints:^(MASConstraintMaker *make) {
  150. make.left.right.top.bottom.mas_equalTo(displayView);
  151. }];
  152. mergeView.recordId = [parm ks_stringValueForKey:@"recordId"];
  153. mergeView.songName = [parm ks_stringValueForKey:@"title"];
  154. mergeView.coverImage = [parm ks_stringValueForKey:@"coverImg"];
  155. MJWeakSelf;
  156. NSInteger defaultDelay = [parm ks_integerValueForKey:@"defaultDelay"];
  157. NSURL *videoUrl = [parm valueForKey:@"videoUrl"];
  158. NSURL *bgAudioUrl = [parm valueForKey:@"bgAudioUrl"];
  159. NSURL *recordUrl = [parm valueForKey:@"recordUrl"];
  160. NSString *accompanyUrl = [parm ks_stringValueForKey:@"remoteBgUrl"];
  161. [mergeView configWithVideoUrl:videoUrl bgAudioUrl:bgAudioUrl remoteBgUrl:accompanyUrl recordUrl:recordUrl offsetTime:defaultDelay mergeCallback:^(BOOL isPublished) {
  162. if (isPublished) {
  163. [weakSelf callBackMergeSuccess:controller];
  164. }
  165. }];
  166. }
  167. - (void)callBackMergeSuccess:(KSCloudWebViewController *)controller {
  168. [controller musicPublishCallBack];
  169. }
  170. - (void)changeCurrentPageLandScape:(BOOL)landScape changeController:(KSCloudWebViewController *)controller {
  171. if (landScape) {
  172. // 切换到横屏
  173. if (IS_IPAD) {
  174. controller.zh_statusBarHidden = YES;
  175. }
  176. AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
  177. delegate.allowAutoRotate = YES;
  178. [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:controller];
  179. }
  180. else {
  181. if (IS_IPAD) {
  182. controller.zh_statusBarHidden = NO;
  183. }
  184. AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
  185. delegate.allowAutoRotate = NO;
  186. [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:controller];
  187. }
  188. }
  189. - (void)notiferShowAICustomLoadingDisplayInView:(UIView *)view callBackController:(KSCloudWebViewController *)controller {
  190. MJWeakSelf;
  191. [self.customLoading loadingCallback:^{
  192. [weakSelf notiferBack:controller];
  193. }];
  194. if ([view.subviews containsObject:self.customLoading]) {
  195. return;
  196. }
  197. [view addSubview:self.customLoading];
  198. [self.customLoading mas_makeConstraints:^(MASConstraintMaker *make) {
  199. make.left.top.right.bottom.mas_equalTo(view);
  200. }];
  201. [view bringSubviewToFront:self.customLoading];
  202. [self.customLoading showLoading];
  203. }
  204. - (void)notiferRemoveAICustomLoading {
  205. [self.customLoading stopLoading];
  206. _customLoading = nil;
  207. }
  208. #pragma mark ---- error View
  209. - (void)notiferShowErrorViewDisplayInView:(UIView *)view callBackController:(KSCloudWebViewController *)controller {
  210. MJWeakSelf;
  211. [_errorView failViewActionCallback:^(BOOL isBack) {
  212. [weakSelf hideErrorViewInView:view];
  213. if (isBack) {
  214. [weakSelf notiferBack:controller];
  215. }
  216. else {
  217. [weakSelf notiferRefresh:controller];
  218. }
  219. }];
  220. }
  221. - (void)notiferRemoveErrorInView:(UIView *)view {
  222. [self hideErrorViewInView:view];
  223. }
  224. - (void)hideErrorViewInView:(UIView *)view {
  225. if ([view.subviews containsObject:self.errorView]) {
  226. [self.errorView removeFromSuperview];
  227. }
  228. _errorView = nil;
  229. }
  230. - (void)notiferRefresh:(KSCloudWebViewController *)controller {
  231. [controller loadRequest];
  232. }
  233. #pragma mark ----- 小酷AI loading
  234. - (AccompanyLoadingView *)customLoading {
  235. if (!_customLoading) {
  236. _customLoading = [AccompanyLoadingView shareInstance];
  237. }
  238. return _customLoading;
  239. }
  240. - (void)notiferBack:(KSCloudWebViewController *)controller {
  241. if (_customLoading) {
  242. [self notiferRemoveAICustomLoading];
  243. }
  244. if (_errorView) {
  245. [_errorView removeFromSuperview];
  246. _errorView = nil;
  247. }
  248. [controller backAction];
  249. }
  250. #pragma mark --- web error
  251. - (KSWebLoadRefreshView *)errorView {
  252. if (!_errorView) {
  253. _errorView = [KSWebLoadRefreshView shareInstance];
  254. }
  255. return _errorView;
  256. }
  257. @end