|
@@ -1,1854 +0,0 @@
|
|
|
-//
|
|
|
-// KSAccompanyWebViewController.m
|
|
|
-// KulexiuForTeacher
|
|
|
-//
|
|
|
-// Created by Kyle on 2022/3/20.
|
|
|
-//
|
|
|
-
|
|
|
-#import "KSAccompanyWebViewController.h"
|
|
|
-#import "WebViewBaseConfig.h" // 基础配置
|
|
|
-#import "SwiftImportHeader.h" // swift 桥接
|
|
|
-#import <KSTunerLibrary/KSTunerLibrary-Swift.h>
|
|
|
-
|
|
|
-#import <KSAudioSessionManager.h> // audio session
|
|
|
-#import <KSAQRecordManager.h> // 录音
|
|
|
-#import "KSTargetWebSocketManager.h" // web socket
|
|
|
-#import <KSVideoRecordManager.h> // 视频录制
|
|
|
-#import <KSCloudBeatView.h> // 节拍器
|
|
|
-#import <MidiPlayerEngine.h> // midi 播放
|
|
|
-
|
|
|
-#import "AccompanyLoadingView.h"
|
|
|
-
|
|
|
-#define KSMidiSongFileKey (@"KSDownloadMidiSong")
|
|
|
-
|
|
|
-// 合成
|
|
|
-#import <KSMediaEditor.h>
|
|
|
-#import "KSAccompanyDraftViewController.h"
|
|
|
-#import "KSLogManager.h"
|
|
|
-
|
|
|
-#import "AudioEnginePlayer.h"
|
|
|
-
|
|
|
-@interface KSAccompanyWebViewController ()<KSAQRecordManagerDelegate,KSAudioSessionManagerDelegate,PlayerEngineDelegate,TunerDelegate,AudioEnginePlayerDelegate>
|
|
|
-
|
|
|
-@property (nonatomic, strong) KSAudioSessionManager *audioSessionManager;
|
|
|
-
|
|
|
-@property (nonatomic, assign) MetronomeType beatType;
|
|
|
-
|
|
|
-@property (nonatomic, strong) MidiPlayerEngine *playerEngine; // player
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL initEngineSuccess; // 加载引擎是否成功
|
|
|
-
|
|
|
-@property (nonatomic, assign) float songOriginalSpeed;
|
|
|
-
|
|
|
-@property (nonatomic, assign) float currentSpeed; // 当前播放的速度
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL isPlaying; // 是否正在播放的状态
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSString *currentSongId; // song id
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSDictionary *configEngineParm; // 初始化mid播放引擎的参数
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSMutableDictionary *metronomeParm; // 节拍器播放的参数
|
|
|
-
|
|
|
-// 是否发送了musicXML信息
|
|
|
-@property (nonatomic, assign) BOOL hasSendStartMessage;
|
|
|
-
|
|
|
-@property (nonatomic, strong) KSAQRecordManager *AQManager;
|
|
|
-
|
|
|
-@property (nonatomic, strong) KSTargetWebSocketManager *socketManager;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSMutableDictionary *evaluatParm;
|
|
|
-
|
|
|
-// 录制的message
|
|
|
-@property (nonatomic, strong) NSMutableDictionary *recordParm;
|
|
|
-
|
|
|
-// 评测开始时发送recordStart消息的标识
|
|
|
-@property (nonatomic, assign) BOOL isCompareStart;
|
|
|
-// 校音开始时发送 checkStart消息标识
|
|
|
-@property (nonatomic, assign) BOOL isSoundCheckStart;
|
|
|
-
|
|
|
-// 自定义UI控件容器
|
|
|
-@property (nonatomic, strong) UIView *viewContainer;
|
|
|
-
|
|
|
-@property (nonatomic, strong) KSVideoRecordManager *videoRecordManager;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSDictionary *endRecordParm;
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL isCameraOpen;
|
|
|
-
|
|
|
-@property (nonatomic, strong) AccompanyLoadingView *loadingView;
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL isTunerRuning;
|
|
|
-
|
|
|
-@property (nonatomic, strong) Tuner *tuner;
|
|
|
-
|
|
|
-// 延迟校准开始时发送 AdjustStart消息标识
|
|
|
-@property (nonatomic, assign) BOOL isDelayCheckStart;
|
|
|
-// 检测延迟播放器
|
|
|
-@property (nonatomic, strong) AudioEnginePlayer *delayCheckPlayer;
|
|
|
-
|
|
|
-// 音频播放器
|
|
|
-@property (nonatomic, strong) AudioEnginePlayer *musicPlayer;
|
|
|
-
|
|
|
-@property (nonatomic, assign) float musicSpeed; //播放速度
|
|
|
-// 录音开始时间
|
|
|
-@property (nonatomic, assign) NSTimeInterval recordStartTime;
|
|
|
-// 播放开始时间
|
|
|
-@property (nonatomic, assign) NSTimeInterval playerStartTime;
|
|
|
-// 播放延迟
|
|
|
-@property (nonatomic, assign) NSInteger offsetTime;
|
|
|
-
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL checkPlayerReady;
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL musicPlayerReady;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSDictionary *playerParm;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSMutableArray *delayArray;
|
|
|
-
|
|
|
-@property (nonatomic, assign) NSInteger checkIndex;
|
|
|
-
|
|
|
-@property (nonatomic, assign) NSInteger checkPrequence;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSURL *bgAudioUrl;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSURL *recordUrl;
|
|
|
-
|
|
|
-@property (nonatomic, strong) NSString *accompanyUrl;
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL muteAccompany; // 是否静音
|
|
|
-
|
|
|
-@property (nonatomic, assign) NSInteger musicStartTime; // 开始播放的时间
|
|
|
-
|
|
|
-@property (nonatomic, assign) BOOL hasRecordMusicOffset; // 是否记录了播放延迟
|
|
|
-
|
|
|
-@end
|
|
|
-
|
|
|
-@implementation KSAccompanyWebViewController
|
|
|
-
|
|
|
-- (void)handerAudioInterruption {
|
|
|
- if (_playerEngine) {
|
|
|
- [self stopPlayAction];
|
|
|
- }
|
|
|
- if (_musicPlayer) {
|
|
|
- [self stopMp3Player];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)resumeAudioSession {
|
|
|
- // 恢复
|
|
|
- if (_playerEngine) {
|
|
|
- [self.playerEngine resumeAUGraph];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 打断处理
|
|
|
-- (void)audioInterruption {
|
|
|
- if (_videoRecordManager) {
|
|
|
- [self.videoRecordManager resetSession];
|
|
|
- }
|
|
|
- [self handerAudioInterruption];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)ignorRecordVideo {
|
|
|
- if (_videoRecordManager) {
|
|
|
- self.videoRecordManager.skipSaveRecord = YES;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)stopSession {
|
|
|
- if (_videoRecordManager) {
|
|
|
- [self.videoRecordManager stopSession];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)resetPlayerConfig {
|
|
|
- [self freeMp3Player]; // 若之前有播放器,剔除
|
|
|
- self.checkPrequence = 800;
|
|
|
- self.checkPlayerReady = NO;
|
|
|
- self.musicPlayerReady = NO;
|
|
|
- self.recordStartTime = 0;
|
|
|
- self.playerStartTime = 0;
|
|
|
- self.offsetTime = 0;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)downloadMp3File:(NSString *)musicUrl {
|
|
|
- if (![NSString isEmptyString:musicUrl]) {
|
|
|
- NSString *fileName = [musicUrl getUrlFileName];
|
|
|
- NSString *filePath = [self getAccompanyFilePathWithName:fileName];
|
|
|
- NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:filePath];
|
|
|
- if ([self checkSongHasSaveAccompanyWithSongUrl:musicUrl]) {
|
|
|
- [self configVideoRecord:fileUrl];
|
|
|
- [self initMusicPlayer:fileUrl];
|
|
|
- }
|
|
|
- else {
|
|
|
- MJWeakSelf;
|
|
|
- [self downloadUrl:musicUrl success:^{
|
|
|
- [weakSelf configVideoRecord:fileUrl];
|
|
|
- [weakSelf initMusicPlayer:fileUrl];
|
|
|
- } faliure:^{
|
|
|
-
|
|
|
- }];
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- [self configVideoRecord:nil];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)initMusicPlayer:(NSURL *)musicUrl {
|
|
|
-
|
|
|
- [self.musicPlayer prepareNativeSongWithUrl:musicUrl];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)downloadCheckMusic:(NSString *)checkMusicUrl {
|
|
|
- if (![NSString isEmptyString:checkMusicUrl]) {
|
|
|
- NSString *fileName = [checkMusicUrl getUrlFileName];
|
|
|
- NSString *filePath = [self getAccompanyFilePathWithName:fileName];
|
|
|
- NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:filePath];
|
|
|
- if ([self checkSongHasSaveAccompanyWithSongUrl:checkMusicUrl]) {
|
|
|
- [self initCheckPlayer:fileUrl];
|
|
|
- }
|
|
|
- else {
|
|
|
- MJWeakSelf;
|
|
|
- [self downloadUrl:checkMusicUrl success:^{
|
|
|
- [weakSelf initCheckPlayer:fileUrl];
|
|
|
- } faliure:^{
|
|
|
-
|
|
|
- }];
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)initCheckPlayer:(NSURL *)checkUrl {
|
|
|
- [self.delayCheckPlayer prepareNativeSongWithUrl:checkUrl];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)initMp3Player:(NSString *)musicUrl checkUrl:(NSString *)checkUrl {
|
|
|
-
|
|
|
- [self resetPlayerConfig];
|
|
|
- self.accompanyUrl = musicUrl;
|
|
|
- [self downloadCheckMusic:checkUrl];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)freeMp3Player {
|
|
|
- if (_delayCheckPlayer) {
|
|
|
- [self.delayCheckPlayer freePlayer];
|
|
|
- }
|
|
|
- if (_musicPlayer) {
|
|
|
- [self.musicPlayer freePlayer];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)stopMp3Player {
|
|
|
- if (_delayCheckPlayer) {
|
|
|
- [self.delayCheckPlayer stopPlay];
|
|
|
- }
|
|
|
- if (_musicPlayer) {
|
|
|
- [self.musicPlayer stopPlay];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-- (void)viewDidLoad {
|
|
|
- [super viewDidLoad];
|
|
|
- // Do any additional setup after loading the view.
|
|
|
- [self configAudioSession];
|
|
|
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnterBackground) name:@"appEnterBackground" object:nil];
|
|
|
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnterForeground) name:@"appEnterForeground" object:nil];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (void)checkMessage:(id)message {
|
|
|
- NSDictionary *result = [message mj_JSONObject];
|
|
|
- NSString *type = [[result ks_dictionaryValueForKey:@"header"] ks_stringValueForKey:@"type"];
|
|
|
- NSString *commond = [[result ks_dictionaryValueForKey:@"header"] ks_stringValueForKey:@"commond"];
|
|
|
- if ([type isEqualToString:@"DELAY_CHECK"] && [commond isEqualToString:@"recordEnd"]) {
|
|
|
- NSDictionary *body = [result ks_dictionaryValueForKey:@"body"];
|
|
|
- NSTimeInterval micDelay = [body ks_doubleValueForKey:@"firstNoteDelayDuration"] - self.offsetTime;
|
|
|
- [self.delayArray addObject:[NSNumber numberWithDouble:micDelay]];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)connectSocketService {
|
|
|
-
|
|
|
- MJWeakSelf;
|
|
|
- self.socketManager.didReceiveMessage = ^(id _Nonnull message) {
|
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- [weakSelf checkMessage:message];
|
|
|
- // api
|
|
|
- NSMutableDictionary *sendMessage = [NSMutableDictionary dictionary];
|
|
|
- [sendMessage setValue:@"sendResult" forKey:@"api"];
|
|
|
- [sendMessage setValue:message forKey:@"content"];
|
|
|
- // 服务返回数据传给H5
|
|
|
- [weakSelf postMessage:sendMessage];
|
|
|
- });
|
|
|
- };
|
|
|
- self.socketManager.connectionStatus = ^(BOOL isSuccess) {
|
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
-
|
|
|
- if (!isSuccess) {
|
|
|
- // NSLog(@"-----连接失败");
|
|
|
- if (weakSelf.hasSendStartMessage) {
|
|
|
- if (weakSelf.AQManager.isRunning) {
|
|
|
- NSDictionary *postParm = @{@"api" : @"cancelEvaluating",
|
|
|
- @"content" : @{@"reson":@"服务异常,请重试"}
|
|
|
- };
|
|
|
- [weakSelf postMessage:postParm];
|
|
|
- [weakSelf stopRecordService];
|
|
|
- weakSelf.isCompareStart = NO;
|
|
|
- weakSelf.isSoundCheckStart = NO;
|
|
|
- weakSelf.isDelayCheckStart = NO;
|
|
|
- }
|
|
|
- }
|
|
|
- else if (weakSelf.evaluatParm) {
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:weakSelf.evaluatParm];
|
|
|
- NSDictionary *valueDic = [weakSelf.evaluatParm ks_dictionaryValueForKey:@"content"];
|
|
|
- [valueDic setValue:@"服务异常,请重试" forKey:@"reson"];
|
|
|
- [sendParm setValue:valueDic forKey:@"content"];
|
|
|
- [weakSelf postMessage:sendParm];
|
|
|
- weakSelf.hasSendStartMessage = YES;
|
|
|
- weakSelf.isCompareStart = NO;
|
|
|
- weakSelf.isSoundCheckStart = NO;
|
|
|
- weakSelf.isDelayCheckStart = NO;
|
|
|
- }
|
|
|
- else { // 其他断开
|
|
|
- if (weakSelf.AQManager.isRunning) {
|
|
|
- NSDictionary *postParm = @{@"api" : @"cancelEvaluating",
|
|
|
- @"content" : @{@"reson":@"服务异常,请重试"}
|
|
|
- };
|
|
|
- [weakSelf postMessage:postParm];
|
|
|
- [weakSelf stopRecordService];
|
|
|
- weakSelf.isCompareStart = NO;
|
|
|
- weakSelf.isSoundCheckStart = NO;
|
|
|
- weakSelf.isDelayCheckStart = NO;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- // NSLog(@"-----连接成功");
|
|
|
- if (weakSelf.hasSendStartMessage == NO && weakSelf.evaluatParm) {
|
|
|
- NSDictionary *content = [weakSelf.evaluatParm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSString *sendData = [weakSelf configDataCommond:@"musicXml" body:content type:@"SOUND_COMPARE"];
|
|
|
- [weakSelf sendDataToSocketService:sendData];
|
|
|
- [weakSelf postMessage:weakSelf.evaluatParm];
|
|
|
- weakSelf.hasSendStartMessage = YES;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
- [self.socketManager SRWebSocketOpen];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)appEnterBackground {
|
|
|
- NSDictionary *parm = @{@"api":@"suspendPlay"};
|
|
|
- [self postMessage:parm];
|
|
|
- [self handerAudioInterruption];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)appEnterForeground {
|
|
|
- if (self.isCameraOpen) {
|
|
|
- if ([self.videoRecordManager getSessionStatusisActive] == NO) {
|
|
|
- [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)initWebView {
|
|
|
- [self.scrollView removeFromSuperview];
|
|
|
-
|
|
|
- [self.view addSubview:self.viewContainer];
|
|
|
- [self.viewContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
- make.left.right.top.bottom.mas_equalTo(self.view);
|
|
|
- }];
|
|
|
-
|
|
|
- if (self.myWebView == nil) {
|
|
|
-
|
|
|
- WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
|
|
|
- config.selectionGranularity = WKSelectionGranularityDynamic;
|
|
|
- config.allowsInlineMediaPlayback = YES;
|
|
|
- config.mediaTypesRequiringUserActionForPlayback = NO;
|
|
|
-
|
|
|
- config.processPool = [KSBaseWKWebViewController singleWkProcessPool];
|
|
|
- config.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
|
|
|
- [self configUserAgent:config];
|
|
|
-
|
|
|
- //自定义的WKScriptMessageHandler 是为了解决内存不释放的问题
|
|
|
- WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
|
|
|
- //这个类主要用来做native与JavaScript的交互管理
|
|
|
- WKUserContentController * wkUController = [[WKUserContentController alloc] init];
|
|
|
- [wkUController addScriptMessageHandler:weakScriptMessageDelegate name:SCRIPT_NAME];
|
|
|
- config.userContentController = wkUController;
|
|
|
-
|
|
|
- WKPreferences *preferences = [WKPreferences new];
|
|
|
- // 是否支出javaScript
|
|
|
- preferences.javaScriptEnabled = YES;
|
|
|
- //不通过用户交互,是否可以打开窗口
|
|
|
- preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
|
|
- config.preferences = preferences;
|
|
|
- self.myWebView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
|
|
|
- self.myWebView.opaque = NO;
|
|
|
- self.myWebView.UIDelegate = self;
|
|
|
- self.myWebView.navigationDelegate = self;
|
|
|
- self.myWebView.scrollView.bounces = NO;
|
|
|
- self.myWebView.backgroundColor = [UIColor clearColor];
|
|
|
- self.myWebView.scrollView.backgroundColor = [UIColor clearColor];
|
|
|
-#ifdef DEBUG
|
|
|
- if (@available(iOS 16.4, *)) {
|
|
|
- self.myWebView.inspectable = YES;
|
|
|
- }
|
|
|
-#endif
|
|
|
- // 加载进度条和title
|
|
|
- [self.myWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
|
|
|
- [self.myWebView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
|
|
|
- [self.view addSubview:self.myWebView];
|
|
|
- [self.myWebView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
- make.left.right.mas_equalTo(self.view);
|
|
|
- make.top.mas_equalTo(self.view.mas_top);
|
|
|
- make.bottom.mas_equalTo(self.view.mas_bottom);
|
|
|
- }];
|
|
|
- self.myWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
|
-
|
|
|
- [self setupProgress];
|
|
|
-
|
|
|
- [self loadRequest];
|
|
|
- }
|
|
|
- else {
|
|
|
- [self.myWebView reload];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)configUserAgent:(WKWebViewConfiguration *)config {
|
|
|
- NSString *oldUserAgent = config.applicationNameForUserAgent;
|
|
|
- NSString *newAgent = [NSString stringWithFormat:@"%@ %@ %@",oldUserAgent,AGENT_NAME,AGENT_DOMAIN];
|
|
|
- config.applicationNameForUserAgent = newAgent;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)configRecordManager {
|
|
|
- if (self.AQManager.isRunning) {
|
|
|
- [self.AQManager stopRecord];
|
|
|
- }
|
|
|
- self.AQManager = [[KSAQRecordManager alloc] init];
|
|
|
- self.AQManager.delegate = self;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)viewWillAppear:(BOOL)animated {
|
|
|
- [super viewWillAppear:animated];
|
|
|
- [self connectSocketService];
|
|
|
- if (self.isCameraOpen) {
|
|
|
- [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)viewWillDisappear:(BOOL)animated {
|
|
|
- [super viewWillDisappear:animated];
|
|
|
-
|
|
|
- if (_socketManager) {
|
|
|
- [self.socketManager SRWebSocketClose];
|
|
|
- _socketManager = nil;
|
|
|
- }
|
|
|
- // 停止播放和录制
|
|
|
- [self stopSession];
|
|
|
- [self stopPlayAction];
|
|
|
- [self stopRecordService];
|
|
|
- [self stopTuner];
|
|
|
-
|
|
|
- BOOL isBack = [self isViewPopDismiss];
|
|
|
- if (isBack) { // 页面销毁才删除
|
|
|
- if (_AQManager) {
|
|
|
- [_AQManager freeAudioQueue];
|
|
|
- }
|
|
|
- // 如果退出评测页面 清除 playerEngine
|
|
|
- if (self.playerEngine) {
|
|
|
- [self.playerEngine cleanup];
|
|
|
- self.playerEngine = nil;
|
|
|
- }
|
|
|
- // 返回不保存视频
|
|
|
- [self ignorRecordVideo];
|
|
|
- [self freeMp3Player];
|
|
|
- [self removeTuner];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)removeTuner {
|
|
|
- if (_tuner) {
|
|
|
- [_tuner freeTuner];
|
|
|
- _tuner = nil;
|
|
|
- NSLog(@"--- free tuner ");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (void)sendDataToSocketService:(id)data {
|
|
|
- if (_socketManager) {
|
|
|
- [self.socketManager sendData:data];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark --- WKScriptMessageHandler
|
|
|
-
|
|
|
-- (void)userContentController:(WKUserContentController *)userContentController
|
|
|
- didReceiveScriptMessage:(WKScriptMessage *)message {
|
|
|
- if ([message.name isEqualToString:SCRIPT_NAME]) {
|
|
|
- NSDictionary *parm = [self convertJsonStringToNSDictionary:message.body];
|
|
|
- // 回到主线程
|
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"createMusicPlayer"]) {
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSString *musicUrl = [content ks_stringValueForKey:@"musicSrc"];
|
|
|
- NSString *checkUrl = [content ks_stringValueForKey:@"tuneSrc"];
|
|
|
- self.playerParm = parm;
|
|
|
- [self initMp3Player:musicUrl checkUrl:checkUrl];
|
|
|
- // 下载文件
|
|
|
- [self downloadMp3File:musicUrl];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startEvaluating"]) { // 开始评测
|
|
|
- [self configRecordManager];
|
|
|
- self.hasSendStartMessage = NO;
|
|
|
- [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
|
|
|
- if (type == PREMISSIONTYPE_YES) {
|
|
|
- self.evaluatParm = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
- // 如果socket 连上了
|
|
|
- if (self.socketManager.socketReadyState == SR_OPEN) {
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSString *sendData = [self configDataCommond:@"musicXml" body:content type:@"SOUND_COMPARE"];
|
|
|
- [self sendDataToSocketService:sendData];
|
|
|
- [self postMessage:parm];
|
|
|
- self.hasSendStartMessage = YES;
|
|
|
- }
|
|
|
- else {
|
|
|
- [self connectSocketService];
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- [self responseMessage:@"storageUnable" desc:@"没有麦克风访问权限" parm:parm];
|
|
|
- [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
|
|
|
- }
|
|
|
- }];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endEvaluating"]) {// 停止评测
|
|
|
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
- self.musicStartTime = 0;
|
|
|
- self.evaluatParm = nil;
|
|
|
- [self stopRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- [self sendEndMessage];
|
|
|
- [self stopMp3Player]; // 停止播放
|
|
|
- });
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cancelEvaluating"]) { // 取消评测
|
|
|
- self.musicStartTime = 0;
|
|
|
- self.evaluatParm = nil;
|
|
|
- [self stopRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- [self stopMp3Player]; // 停止播放
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startRecording"]) { // 开始录制
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- self.musicStartTime = [content ks_integerValueForKey:@"firstNoteTime"];
|
|
|
- if ([[content allKeys] containsObject:@"accompanimentState"]) {
|
|
|
- BOOL mute = [content ks_boolValueForKey:@"accompanimentState"] == NO;
|
|
|
- self.muteAccompany = mute;
|
|
|
- }
|
|
|
- else {
|
|
|
- self.muteAccompany = NO;
|
|
|
- }
|
|
|
- if ([[content allKeys] containsObject:@"speedRate"]) { // 播放速度
|
|
|
- self.musicSpeed = [content ks_floatValueForKey:@"speedRate"];
|
|
|
- }
|
|
|
- else {
|
|
|
- self.musicSpeed = 1.0f;
|
|
|
- }
|
|
|
-
|
|
|
- if (self->_videoRecordManager) {
|
|
|
- [self.videoRecordManager clearVideoFile];
|
|
|
- }
|
|
|
- [self postMessage:parm];
|
|
|
- self.isCompareStart = YES;
|
|
|
- [self startRecordService];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endRecording"]) { // 停止录音
|
|
|
- self.recordParm = nil;
|
|
|
- [self stopRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"pauseRecording"]) {
|
|
|
- [self puaseRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"resumeRecording"]) {
|
|
|
- [self resumeRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"isWiredHeadsetOn"]) {
|
|
|
- [self configAudioDeviceType:parm];
|
|
|
- }
|
|
|
- // 发送消息给socket service
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"proxyMessage"]) {
|
|
|
- [self sendMessageToSocket:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"proxyServiceMessage"]) {
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSString *sendData = [content mj_JSONString];
|
|
|
- NSLog(@"proxyServiceMessage ------- %@",sendData);
|
|
|
- [self sendDataToSocketService:sendData];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openCamera"]) { // 开启摄像头
|
|
|
- [RecordCheckManager checkCameraPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
|
|
|
- [self afterCheckCameraCheckAlbum:type parm:parm];
|
|
|
- }];
|
|
|
-
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"closeCamera"]) { // 关闭摄像头
|
|
|
- self.isCameraOpen = NO;
|
|
|
- if (self->_videoRecordManager) {
|
|
|
- [self.videoRecordManager removeDisplay];
|
|
|
- }
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startCapture"]) { // 开始录制
|
|
|
- [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
|
|
|
- if (type == PREMISSIONTYPE_YES) {
|
|
|
- [self.videoRecordManager setIgnoreAudio:YES];
|
|
|
- self.videoRecordManager.audioUrl = self.AQManager.audioUrl;
|
|
|
- [self.videoRecordManager startRecord];
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else {
|
|
|
-// [self responseMessage:@"storageUnable" desc:@"没有相册存储权限" parm:parm];
|
|
|
-// [self showAlertWithMessage:@"开启相册存储" type:CHECKDEVICETYPE_CAMREA];
|
|
|
- }
|
|
|
- }];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endCapture"]) { // 结束录制
|
|
|
- if (self->_videoRecordManager) {
|
|
|
- self.endRecordParm = parm;
|
|
|
- [self.videoRecordManager stopRecord];
|
|
|
- }
|
|
|
- else {
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"setCaptureMode"]) {
|
|
|
- NSString *modeString = [[parm ks_dictionaryValueForKey:@"content"] ks_stringValueForKey:@"mode"];
|
|
|
- BOOL isIgnoreAudio = [modeString isEqualToString:@"evaluating"];
|
|
|
- [self postMessage:parm];
|
|
|
- [self.videoRecordManager setIgnoreAudio:isIgnoreAudio];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startSoundCheck"]) { // 开始校音
|
|
|
- [self configRecordManager];
|
|
|
- [self postMessage:parm];
|
|
|
- self.isCompareStart = NO;
|
|
|
- self.isSoundCheckStart = YES;
|
|
|
- self.isDelayCheckStart = NO;
|
|
|
- [self startRecordService];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endSoundCheck"]) {
|
|
|
- // 结束校音
|
|
|
- self.isSoundCheckStart = NO;
|
|
|
- [self stopRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- // 音视频合成
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openAdjustRecording"]) {
|
|
|
- KSAccompanyDraftViewController *ctrl = [[KSAccompanyDraftViewController alloc] init];
|
|
|
- ctrl.ks_landScape = YES;
|
|
|
-
|
|
|
- if (self.bgAudioUrl == nil) {
|
|
|
- [LOADING_MANAGER MBShowAUTOHidingInWindow:@"当前曲目无mp3伴奏"];
|
|
|
- }
|
|
|
- else {
|
|
|
- if (self.AQManager && self.AQManager.audioUrl) {
|
|
|
- self.recordUrl = self.AQManager.audioUrl;
|
|
|
-
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- ctrl.recordId = [content ks_stringValueForKey:@"recordId"];
|
|
|
- ctrl.songName = [content ks_stringValueForKey:@"title"];
|
|
|
- ctrl.coverImage = [content ks_stringValueForKey:@"coverImg"];
|
|
|
- if ([[content allKeys] containsObject:@"speedRate"]) {
|
|
|
- ctrl.musicSpeed = [content ks_floatValueForKey:@"speedRate"];
|
|
|
- }
|
|
|
- else {
|
|
|
- ctrl.musicSpeed = 1.0f;
|
|
|
- }
|
|
|
- MJWeakSelf;
|
|
|
- NSInteger micDelay = [UserDefaultObjectForKey(@"micDelay") integerValue];
|
|
|
- NSInteger defaultDelay = self.offsetTime + micDelay;
|
|
|
- [ctrl configWithVideoUrl:self.videoRecordManager.videoFileURL bgAudioUrl:self.bgAudioUrl remoteBgUrl:self.accompanyUrl recordUrl:self.recordUrl offsetTime:defaultDelay mergeCallback:^(BOOL isPublished) {
|
|
|
- if (isPublished) {
|
|
|
- [weakSelf musicPublishCallBack:content];
|
|
|
- }
|
|
|
- }];
|
|
|
- [self.navigationController pushViewController:ctrl animated:NO];
|
|
|
- }
|
|
|
- else {
|
|
|
- [LOADING_MANAGER MBShowAUTOHidingInWindow:@"麦克风被占用"];
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"videoUpdate"]) { // 上传
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
- NSMutableDictionary *contentParm = [NSMutableDictionary dictionaryWithDictionary:[sendParm ks_dictionaryValueForKey:@"content"]];
|
|
|
- if (self.videoRecordManager) {
|
|
|
-
|
|
|
- MJWeakSelf;
|
|
|
- [self.videoRecordManager saveVideoCallback:^(BOOL isSuccess, NSString * _Nullable message) {
|
|
|
- if (isSuccess) {
|
|
|
- [LOADING_MANAGER MBShowAUTOHidingInWindow:@"已保存到相册"];
|
|
|
- [weakSelf uploadVideoWithParm:contentParm sendParm:sendParm];
|
|
|
- }
|
|
|
- }];
|
|
|
- }
|
|
|
- }
|
|
|
-#pragma mark -------- 云教练原生播放对接
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudDetail"]) { // 初始化方法
|
|
|
- /**
|
|
|
- api: 'cloudDetail',
|
|
|
- content: {
|
|
|
- midi: '',
|
|
|
- denominator: 4,
|
|
|
- numerator: 4,
|
|
|
- // xml整体原始速度
|
|
|
- originalSpeed: 90,
|
|
|
- // 间隔(ms)
|
|
|
- interval: 50
|
|
|
- }
|
|
|
- */
|
|
|
-
|
|
|
- [self configAudioSession];
|
|
|
- // 重置track num array
|
|
|
- self.configEngineParm = [parm copy];
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSString *midiUrl = [content ks_stringValueForKey:@"midi"];
|
|
|
- NSInteger denominator = [content ks_integerValueForKey:@"denominator"];
|
|
|
- NSInteger numerator = [content ks_integerValueForKey:@"numerator"];
|
|
|
- NSString *beatString = [NSString stringWithFormat:@"%zd/%zd", numerator,denominator];
|
|
|
- self.beatType = [self getBeatTypeFromString:beatString];
|
|
|
-
|
|
|
- float originalSpeed = [content ks_floatValueForKey:@"originalSpeed"];
|
|
|
- self.songOriginalSpeed = originalSpeed;
|
|
|
- self.currentSpeed = originalSpeed;
|
|
|
- NSInteger reportInterval = [content ks_integerValueForKey:@"interval"];
|
|
|
- // 下载midi文件
|
|
|
- BOOL hasSaveSong = [self checkSongHasSaveWithSongUrl:midiUrl];
|
|
|
- NSString *fileName = [midiUrl getUrlFileName];
|
|
|
- NSString *filePath = [self getFilePathWithName:fileName];
|
|
|
- if (hasSaveSong) {
|
|
|
- [self configPlayerEngineWithSong:filePath reportTime:reportInterval];
|
|
|
- }
|
|
|
- else {
|
|
|
- MJWeakSelf;
|
|
|
- [self downloadMidiFile:midiUrl success:^{
|
|
|
- [weakSelf configPlayerEngineWithSong:filePath reportTime:reportInterval];
|
|
|
- } faliure:^{
|
|
|
-
|
|
|
- }];
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudGetMediaStatus"]) { // 获取播放状态
|
|
|
- /**
|
|
|
- api: 'cloudGetMediaStatus',
|
|
|
- content: {
|
|
|
- status: 'init' | 'play' | 'suspend'
|
|
|
- }
|
|
|
- */
|
|
|
- NSString *engineStatus = @"init";
|
|
|
- if (self.initEngineSuccess) {
|
|
|
- if (self.isPlaying) {
|
|
|
- engineStatus = @"play";
|
|
|
- }
|
|
|
- else {
|
|
|
- engineStatus = @"suspend";
|
|
|
- }
|
|
|
- }
|
|
|
- NSMutableDictionary *valueDic = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [valueDic setValue:engineStatus forKey:@"status"];
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
- [sendParm setValue:valueDic forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
- }
|
|
|
- // 播放、暂停、进度、播放结束、跳转指定位置
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudPlay"]) { // 播放
|
|
|
- /**
|
|
|
- api: 'cloudPlay',
|
|
|
- content: {
|
|
|
- // 当前曲目id
|
|
|
- songID: 0,
|
|
|
- // xml整体原始速度
|
|
|
- originalSpeed: 90,
|
|
|
- // 当前选择速度
|
|
|
- speed: 90,
|
|
|
- // 开始时间(ms)
|
|
|
- startTime: 0
|
|
|
- // 播放频率
|
|
|
- hertz:440
|
|
|
- }
|
|
|
- */
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- self.currentSongId = [content ks_stringValueForKey:@"songID"];
|
|
|
- float speed = [content ks_floatValueForKey:@"speed"];
|
|
|
- float originalSpeed = [content ks_floatValueForKey:@"originalSpeed"];
|
|
|
- double rate = speed / originalSpeed;
|
|
|
- self.currentSpeed = speed;
|
|
|
- float hertz = [content ks_floatValueForKey:@"hertz"];
|
|
|
- // 播放的hertz
|
|
|
- [self.playerEngine adjustPitchByHZ:hertz];
|
|
|
-
|
|
|
- [self.playerEngine setMusicPlayerSpeed:rate];
|
|
|
- Float64 startTime = [content ks_doubleValueForKey:@"startTime"];
|
|
|
- NSLog(@"------%@", [content ks_stringValueForKey:@"startTime"]);
|
|
|
- [self.playerEngine setProgressTime:(startTime/1000)];
|
|
|
- // 播放
|
|
|
- [self playAction];
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudSuspend"]) { // 暂停
|
|
|
- /**
|
|
|
- api: 'cloudSuspend',
|
|
|
- content: {
|
|
|
- // 当前曲目id
|
|
|
- songID: 0,
|
|
|
- }
|
|
|
- */
|
|
|
- [self stopPlayAction];
|
|
|
- [self postMessage:parm];
|
|
|
-
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudSetCurrentTime"]) { // // 跳转指定位置
|
|
|
- /**
|
|
|
- api: 'cloudSetCurrentTime',
|
|
|
- content: {
|
|
|
- // 当前曲目id
|
|
|
- songID: 0,
|
|
|
- // 指定位置时间(ms)
|
|
|
- currentTime: 0
|
|
|
- }
|
|
|
- */
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- Float64 currentTime = [content ks_doubleValueForKey:@"currentTime"];
|
|
|
- if (self.playerEngine) {
|
|
|
- [self.playerEngine setProgressTime:(currentTime/1000)];
|
|
|
- }
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudChangeSpeed"]) { // 调速 范围(45-270整数)
|
|
|
- /**
|
|
|
- api: 'cloudChangeSpeed',
|
|
|
- content: {
|
|
|
- // 当前曲目id
|
|
|
- songID: 0,
|
|
|
- // 调整速度
|
|
|
- speed: 90
|
|
|
- // xml整体原始速度
|
|
|
- originalSpeed: 90,
|
|
|
- }
|
|
|
- */
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- float speed = [content ks_floatValueForKey:@"speed"];
|
|
|
- float originalSpeed = [content ks_floatValueForKey:@"originalSpeed"];
|
|
|
- double rate = speed / originalSpeed;
|
|
|
- self.currentSpeed = speed;
|
|
|
- [self.playerEngine setMusicPlayerSpeed:rate];
|
|
|
- // 回报信息
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- // 设置每个轨道音量
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudVolume"]) {
|
|
|
- /**
|
|
|
- api: 'cloudVolume',
|
|
|
- content: {
|
|
|
- parts: [
|
|
|
- {
|
|
|
- name: '',
|
|
|
- volume: 90,//0-100
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
- */
|
|
|
- NSLog(@"-cloudVolume -----%@",parm);
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- int instrumentId = [content ks_intValueForKey:@"activeMidiId"];
|
|
|
- float volume = [content ks_floatValueForKey:@"activeMidiVolume"];
|
|
|
- if (instrumentId < 0) {
|
|
|
- [self postMessage:parm];
|
|
|
- [self.playerEngine getAllTrackVolume];
|
|
|
- return;
|
|
|
- }
|
|
|
- [self.playerEngine volumeTrackVolumeWithInstrumentId:instrumentId volume:volume/100];
|
|
|
- [self postMessage:parm];
|
|
|
- [self.playerEngine getAllTrackVolume];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudMetronome"]) { // 节拍器播放
|
|
|
- self.metronomeParm = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSInteger repeatCount = [content ks_integerValueForKey:@"repeat"];
|
|
|
- NSInteger denominator = [content ks_integerValueForKey:@"denominator"];
|
|
|
- NSInteger numerator = [content ks_integerValueForKey:@"numerator"];
|
|
|
- NSInteger supplement = [content ks_integerValueForKey:@"supplement"];
|
|
|
- NSString *beatString = [NSString stringWithFormat:@"%zd/%zd", numerator,denominator];
|
|
|
- self.beatType = [self getBeatTypeFromString:beatString];
|
|
|
- [self showBeatViewRepeatCount:repeatCount supplement:supplement];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudDestroy"]) { // 销毁播放器
|
|
|
- self.initEngineSuccess = NO;
|
|
|
- // 重置track num array
|
|
|
- self.isPlaying = NO;
|
|
|
- if (self.playerEngine) {
|
|
|
- [self.playerEngine cleanup];
|
|
|
- self.playerEngine = nil;
|
|
|
- }
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudLoading"]) { // loading
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- BOOL showLoading = [content ks_boolValueForKey:@"show"];
|
|
|
- if (showLoading) {
|
|
|
- [self showCustomLoading];
|
|
|
- }
|
|
|
- else {
|
|
|
- [self removeCustomLoadingView];
|
|
|
- }
|
|
|
- }
|
|
|
- // 跟音
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudToggleFollow"]) { // 跟音
|
|
|
- [RecordCheckManager checkMicPermissionAvaiableCallback:^(PREMISSIONTYPE type) {
|
|
|
- if (type == PREMISSIONTYPE_YES) {
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSString *status = [content ks_stringValueForKey:@"state"];
|
|
|
- if ([status isEqualToString:@"start"]) { // 开始
|
|
|
- [self configAudioSession];
|
|
|
- [self startTuner];
|
|
|
- }
|
|
|
- else if ([status isEqualToString:@"end"]) { // 结束
|
|
|
- [self stopTuner];
|
|
|
- }
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- else {
|
|
|
- [self responseMessage:@"storageUnable" desc:@"没有麦克风权限" parm:parm];
|
|
|
- [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
|
|
|
- }
|
|
|
- }];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"cloudAccompanyMessage"]) { // 获取伴奏 废弃⚠️
|
|
|
-
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startTune"]) { // 延迟测试开始
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
- NSInteger count = [content ks_integerValueForKey:@"count"];
|
|
|
- if (count == 0) {
|
|
|
- [self.delayArray removeAllObjects];
|
|
|
- self.checkIndex = 0;
|
|
|
- }
|
|
|
- self.checkIndex += 1;
|
|
|
- [self configRecordManager];
|
|
|
- [self postMessage:parm];
|
|
|
- self.isCompareStart = NO;
|
|
|
- self.isSoundCheckStart = NO;
|
|
|
- self.isDelayCheckStart = YES;
|
|
|
- [self startRecordService];
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endTune"]) { // 延迟测试停止
|
|
|
-
|
|
|
- self.isDelayCheckStart = NO;
|
|
|
- [self stopRecordService];
|
|
|
- [self postMessage:parm];
|
|
|
- [self stopMp3Player];
|
|
|
- [self sendAdjustEndMessage]; // 发送结束消息
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"finishTune"]) { // 延迟测试结束
|
|
|
- NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
|
|
|
-
|
|
|
- NSInteger errorCount = 0;
|
|
|
- NSInteger totalDelay = 0;
|
|
|
- for (NSInteger index = 0 ; index < self.delayArray.count; index++) {
|
|
|
- NSInteger micDelay = [self.delayArray[index] integerValue];
|
|
|
- if (micDelay > 10 && micDelay < 300) {
|
|
|
- totalDelay += micDelay;
|
|
|
- }
|
|
|
- else {
|
|
|
- errorCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- NSMutableDictionary *contentParm = [NSMutableDictionary dictionaryWithDictionary:content];
|
|
|
- if (errorCount > 1) { // 错误次数过多
|
|
|
- [contentParm setValue:@(NO) forKey:@"result"];
|
|
|
- }
|
|
|
- else {
|
|
|
- [contentParm setValue:@(YES) forKey:@"result"];
|
|
|
- NSInteger averageDelay = totalDelay / (self.delayArray.count - errorCount);
|
|
|
- UserDefaultSet([NSNumber numberWithDouble:averageDelay], @"micDelay");
|
|
|
- }
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
|
|
|
- [sendParm setValue:@"finishTune" forKey:@"api"];
|
|
|
- [sendParm setValue:contentParm forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
- [self.delayArray removeAllObjects];
|
|
|
- self.checkIndex = 0;
|
|
|
- }
|
|
|
- else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"getDeviceDelay"]) {
|
|
|
- NSInteger micDelay = [UserDefaultObjectForKey(@"micDelay") integerValue];
|
|
|
- NSMutableDictionary *content = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [content setValue:[NSNumber numberWithInteger:micDelay] forKey:@"value"];
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
|
|
|
- [sendParm setValue:@"getDeviceDelay" forKey:@"api"];
|
|
|
- [sendParm setValue:content forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
- }
|
|
|
- else {
|
|
|
- [super handleScriptMessageSource:parm];
|
|
|
- }
|
|
|
-
|
|
|
- });
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)afterCheckCameraCheckAlbum:(PREMISSIONTYPE)cameraType parm:(NSDictionary *)sourceParm {
|
|
|
-
|
|
|
- [RecordCheckManager checkPhotoLibraryPremissionAvaiableCallback:^(PREMISSIONTYPE type) {
|
|
|
- if (type == PREMISSIONTYPE_YES && cameraType == PREMISSIONTYPE_YES) {
|
|
|
- self.isCameraOpen = YES;
|
|
|
- [self.videoRecordManager setIgnoreAudio:YES];
|
|
|
- [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
|
|
|
- [self postMessage:sourceParm];
|
|
|
- }
|
|
|
- else { //
|
|
|
-
|
|
|
- NSString *content = @"";
|
|
|
- NSString *des = @"";;
|
|
|
- if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_NO) {
|
|
|
- des = @"没有相机和相册访问权限";
|
|
|
- content = @"请开启相机和相册访问权限";
|
|
|
- }
|
|
|
- else if (cameraType == PREMISSIONTYPE_NO && type == PREMISSIONTYPE_YES) {
|
|
|
- des = @"没有相机访问权限";
|
|
|
- content = @"请开启相机访问权限";
|
|
|
- }
|
|
|
- else if (cameraType == PREMISSIONTYPE_YES && type == PREMISSIONTYPE_NO) {
|
|
|
- des = @"没有相册访问权限";
|
|
|
- content = @"请开启相册访问权限";
|
|
|
- }
|
|
|
- [self responseMessage:@"storageUnable" desc:des parm:sourceParm];
|
|
|
- [self showAlertWithMessage:content type:CHECKDEVICETYPE_CAMREA];
|
|
|
-
|
|
|
- }
|
|
|
- }];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)responseMessage:(NSString *)reson desc:(NSString *)desc parm:(NSDictionary *)parm {
|
|
|
- NSMutableDictionary *sendContent = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [sendContent setValue:reson forKey:@"reson"];
|
|
|
- [sendContent setValue:desc forKey:@"des"];
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
- [sendParm setValue:sendContent forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)musicPublishCallBack:(NSDictionary *)content {
|
|
|
- NSMutableDictionary *parm = [NSMutableDictionary dictionary];
|
|
|
- [parm setValue:@"hideComplexButton" forKey:@"api"];
|
|
|
- [parm setValue:@{} forKey:@"content"];
|
|
|
- [self postMessage:parm];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)uploadVideoWithParm:(NSMutableDictionary *)contentParm sendParm:(NSMutableDictionary *)sendParm {
|
|
|
-// MJWeakSelf;
|
|
|
-// [self.videoRecordManager uploadRecordVideoSuccess:^(NSString * _Nonnull videoUrl) {
|
|
|
-// [contentParm setValue:@"success" forKey:@"type"];
|
|
|
-// [contentParm setValue:videoUrl forKey:@"filePath"];
|
|
|
-// [contentParm setValue:@"上传成功" forKey:@"message"];
|
|
|
-// [sendParm setValue:contentParm forKey:@"content"];
|
|
|
-//
|
|
|
-// [weakSelf postMessage:sendParm];
|
|
|
-// } failure:^(NSString * _Nonnull desc) {
|
|
|
-// [contentParm setValue:@"error" forKey:@"type"];
|
|
|
-// [contentParm setValue:desc forKey:@"message"];
|
|
|
-// [sendParm setValue:contentParm forKey:@"content"];
|
|
|
-// [weakSelf postMessage:sendParm];
|
|
|
-// }];
|
|
|
-}
|
|
|
-- (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
|
|
|
- [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:self.view cancel:^{
|
|
|
-
|
|
|
- } confirm:^{
|
|
|
- [self openSettingView];
|
|
|
- }];
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-- (void)openSettingView {
|
|
|
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)downloadUrl:(NSString *)url success:(void(^)(void))success faliure:(void(^)(void))faliure {
|
|
|
-
|
|
|
- [KSNetworkingManager downloadFileRequestWithFileUrl:url progress:^(int64_t bytesRead, int64_t totalBytes) {
|
|
|
-
|
|
|
- } success:^(NSURL * _Nonnull fileUrl) {
|
|
|
-
|
|
|
- if ([self saveAccompanyFileWithUrl:fileUrl accompanyUrl:url]) {
|
|
|
- if (success) {
|
|
|
- success();
|
|
|
- }
|
|
|
- }
|
|
|
- } faliure:^(NSError * _Nonnull error) {
|
|
|
- if (faliure) {
|
|
|
- faliure();
|
|
|
- }
|
|
|
- }];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)configVideoRecord:(NSURL *)path {
|
|
|
- self.videoRecordManager.bgAudioUrl = path;
|
|
|
- self.bgAudioUrl = path;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)showBeatViewRepeatCount:(NSInteger)repeatCount supplement:(NSInteger)supplement {
|
|
|
- KSCloudBeatView *beatView = [KSCloudBeatView shareInstanceWithBeatType:self.beatType speed:self.currentSpeed repeatCount:repeatCount supplement:supplement];
|
|
|
- MJWeakSelf;
|
|
|
- [beatView startPlayWithEndCallback:^(BOOL isCancle) {
|
|
|
- if (isCancle) { // 取消
|
|
|
- [weakSelf sendEndMetronomeMessage:YES];
|
|
|
- }
|
|
|
- else { // 播放完成
|
|
|
- [weakSelf sendEndMetronomeMessage:NO];
|
|
|
- }
|
|
|
- }];
|
|
|
- [self.view addSubview:beatView];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (void)sendEndMetronomeMessage:(BOOL)isCancel {
|
|
|
- NSString *status = isCancel ? @"cancel" : @"finish";
|
|
|
- NSMutableDictionary *valueDic = [NSMutableDictionary dictionaryWithDictionary:[self.metronomeParm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [valueDic setValue:status forKey:@"status"];
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:self.metronomeParm];
|
|
|
- [sendParm setValue:valueDic forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)downloadMidiFile:(NSString *)midiUrl success:(void(^)(void))success faliure:(void(^)(void))faliure {
|
|
|
-
|
|
|
- [KSNetworkingManager downloadFileRequestWithFileUrl:midiUrl progress:^(int64_t bytesRead, int64_t totalBytes) {
|
|
|
-
|
|
|
- } success:^(NSURL * _Nonnull fileUrl) {
|
|
|
-
|
|
|
- if ([self saveMidiFileWithUrl:fileUrl midiUrl:midiUrl]) {
|
|
|
- if (success) {
|
|
|
- success();
|
|
|
- }
|
|
|
- }
|
|
|
- } faliure:^(NSError * _Nonnull error) {
|
|
|
- if (faliure) {
|
|
|
- faliure();
|
|
|
- }
|
|
|
- }];
|
|
|
-}
|
|
|
-
|
|
|
-- (BOOL)saveMidiFileWithUrl:(NSURL *)fileUrl midiUrl:(NSString *)midiUrl {
|
|
|
- NSData *sourceData = [NSData dataWithContentsOfURL:fileUrl];
|
|
|
- NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
|
|
|
- NSString *filePath= [cachePath stringByAppendingPathComponent:@"MidiSong"];
|
|
|
- // 先创建子目录
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
- if (![fileManager fileExistsAtPath:filePath]) {
|
|
|
- [fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
|
|
|
- }else{
|
|
|
- NSLog(@"已创建文件夹");
|
|
|
- }
|
|
|
- NSString *fileName = [midiUrl getUrlFileName];
|
|
|
- NSString *tempPath = [filePath stringByAppendingPathComponent:fileName];
|
|
|
- BOOL success = [sourceData writeToFile:tempPath atomically:NO];
|
|
|
- return success;
|
|
|
-}
|
|
|
-
|
|
|
-- (NSString *)getFilePathWithName:(NSString *)fileName {
|
|
|
- NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
|
|
|
- NSString *filePath= [cachePath stringByAppendingPathComponent:@"MidiSong"];
|
|
|
- return [filePath stringByAppendingPathComponent:fileName];;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-- (BOOL)checkSongHasSaveWithSongUrl:(NSString *)songUrl {
|
|
|
- BOOL hasSaveFile = NO;
|
|
|
- NSString *fileName = [songUrl getUrlFileName];
|
|
|
- NSString *filePath = [self getFilePathWithName:fileName];
|
|
|
-
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
- if ([fileManager fileExistsAtPath:filePath]) {
|
|
|
- hasSaveFile = YES;
|
|
|
- }
|
|
|
- return hasSaveFile;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)sendMessageToSocket:(NSDictionary *)parm {
|
|
|
- NSString *messageHeader = @"proxyMessage";
|
|
|
- NSString *sendMessage = [self configDataCommond:messageHeader body:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [self sendDataToSocketService:sendMessage];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)configAudioDeviceType:(NSDictionary *)parm {
|
|
|
- AUDIODEVICE_TYPE type = [KSAQRecordManager queryAudioOutputDeviceType];
|
|
|
- NSString *valueStr = @"";
|
|
|
- BOOL checkIsWired = NO;
|
|
|
- switch (type) {
|
|
|
- case AUDIODEVICE_TYPE_HEADPHONE:
|
|
|
- {
|
|
|
- valueStr = @"有线耳机";
|
|
|
- checkIsWired = YES;
|
|
|
- }
|
|
|
- break;
|
|
|
- case AUDIODEVICE_TYPE_BLUETOOTH:
|
|
|
- {
|
|
|
- valueStr = @"蓝牙耳机";
|
|
|
- checkIsWired = YES;
|
|
|
- }
|
|
|
- break;
|
|
|
- case AUDIODEVICE_TYPE_NONE:
|
|
|
- {
|
|
|
- valueStr = @"";
|
|
|
- checkIsWired = NO;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- NSMutableDictionary *valueDic = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [valueDic setValue:valueStr forKey:@"type"];
|
|
|
- [valueDic setValue:[NSNumber numberWithBool:checkIsWired] forKey:@"checkIsWired"];
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
- [sendParm setValue:valueDic forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)startRecordService {
|
|
|
- if (self.AQManager.isRunning) {
|
|
|
- [self.AQManager stopRecord];
|
|
|
- }
|
|
|
- [self.AQManager startRecord];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)stopRecordService {
|
|
|
- if (self.AQManager.isRunning) {
|
|
|
- [self.AQManager stopRecord];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)puaseRecordService {
|
|
|
- if (self.AQManager.isRunning) {
|
|
|
- [self.AQManager pauserRecord];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)resumeRecordService {
|
|
|
- [self.AQManager resumeRecord];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)sendEndMessage {
|
|
|
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
- // 上传停止的信息 发送给服务端
|
|
|
- NSString *endMessage = @"recordEnd";
|
|
|
- NSString *endData = [self configDataCommond:endMessage body:nil type:@"SOUND_COMPARE"];
|
|
|
- [self sendDataToSocketService:endData];
|
|
|
- self.isCompareStart = NO;
|
|
|
- NSLog(@"---- send end message");
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-- (void)sendAdjustEndMessage {
|
|
|
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
- // 上传停止的信息 发送给服务端
|
|
|
- NSString *endMessage = @"recordEnd";
|
|
|
- NSString *endData = [self configDataCommond:endMessage body:nil type:@"DELAY_CHECK"];
|
|
|
- [self sendDataToSocketService:endData];
|
|
|
- self.isDelayCheckStart = NO;
|
|
|
- NSLog(@"---- send adjust end message");
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-- (void)sendOffsetTimeToService {
|
|
|
- // 上传停止的信息 发送给服务端
|
|
|
- NSString *offsetMessage = @"audioPlayStart";
|
|
|
- NSTimeInterval micDelay = [UserDefault(@"micDelay") doubleValue];
|
|
|
- NSDictionary *dic = @{@"offsetTime" : [NSNumber numberWithInteger:self.offsetTime], @"micDelay": [NSNumber numberWithInteger:micDelay]};
|
|
|
- NSString *endData = [self configDataCommond:offsetMessage body:dic type:@"SOUND_COMPARE"];
|
|
|
- NSLog(@"------ %@", endData);
|
|
|
- [self sendDataToSocketService:endData];
|
|
|
- self.isCompareStart = NO;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark-------- KSAQRecordManagerDelegate
|
|
|
-- (void)recordInterruption {
|
|
|
- NSDictionary *postParm = @{@"api" : @"cancelEvaluating",
|
|
|
- @"content" : @{@"reson":@"录制错误,请重试"}
|
|
|
- };
|
|
|
- [self postMessage:postParm];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-- (void)audioRouteChange:(AUDIODEVICE_TYPE)type {
|
|
|
- NSString *valueStr = @"";
|
|
|
- BOOL checkIsWired = NO;
|
|
|
- switch (type) {
|
|
|
- case AUDIODEVICE_TYPE_HEADPHONE:
|
|
|
- {
|
|
|
- valueStr = @"有线耳机";
|
|
|
- checkIsWired = YES;
|
|
|
- }
|
|
|
- break;
|
|
|
- case AUDIODEVICE_TYPE_BLUETOOTH:
|
|
|
- {
|
|
|
- valueStr = @"蓝牙耳机";
|
|
|
- checkIsWired = YES;
|
|
|
- }
|
|
|
- break;
|
|
|
- case AUDIODEVICE_TYPE_NONE:
|
|
|
- {
|
|
|
- valueStr = @"";
|
|
|
- checkIsWired = NO;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- NSDictionary *postParm = @{@"api" : @"listenerWiredStatus",
|
|
|
- @"content" : @{@"type":valueStr,
|
|
|
- @"checkIsWired":[NSNumber numberWithBool:checkIsWired]
|
|
|
- }
|
|
|
- };
|
|
|
- [self postMessage:postParm];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark ------- 评测app播放
|
|
|
-
|
|
|
-- (void)recordDidStart:(NSTimeInterval)time { // ms
|
|
|
- self.hasRecordMusicOffset = NO;
|
|
|
- self.recordStartTime = time;
|
|
|
- if (self.isDelayCheckStart) {
|
|
|
- NSLog(@"---- delay - record did start %f", time);
|
|
|
- // 播放音频
|
|
|
- // 播放校音音频
|
|
|
- dispatch_main_sync_safe(^{
|
|
|
- [self.delayCheckPlayer seekToTimePlay:0];
|
|
|
- });
|
|
|
- }
|
|
|
- else if (self.isCompareStart) {
|
|
|
- NSLog(@"---- compare - record did start %f", time);
|
|
|
- if (self.playerEngine == nil && _musicPlayer) {
|
|
|
- dispatch_main_sync_safe(^{
|
|
|
- self.musicPlayer.isMute = self.muteAccompany;
|
|
|
- self.musicPlayer.rate = self.musicSpeed;
|
|
|
- // 进度跳转
|
|
|
- [self.musicPlayer seekToTimePlay:self.musicStartTime];
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (void)audioRecord:(KSAQRecordManager *)audioRecord didRecordAudioData:(void *)data length:(UInt32)length {
|
|
|
-
|
|
|
- if (self.socketManager.socketReadyState != SR_OPEN) {
|
|
|
- return;
|
|
|
- }
|
|
|
- NSData *pushData = [[NSData alloc] initWithBytes:data length:length];
|
|
|
- if (self.isCompareStart) { // 发送评测开始消息
|
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- NSDate *date = [NSDate date];
|
|
|
- NSTimeInterval inteveral = [date timeIntervalSince1970];
|
|
|
- double beginTime = inteveral - audioRecord.sampleTime;
|
|
|
- NSDictionary *parm = @{
|
|
|
- @"api" : @"recordStartTime",
|
|
|
- @"content" : @{@"inteveral" : [NSNumber numberWithDouble:beginTime]}
|
|
|
- };
|
|
|
- [self postMessage:parm];
|
|
|
- });
|
|
|
-
|
|
|
- NSLog(@"--------- send start message");
|
|
|
- _isCompareStart = NO;
|
|
|
- NSString *startMessage = @"recordStart";
|
|
|
- NSString *startString = [self configDataCommond:startMessage body:nil type:@"SOUND_COMPARE"];
|
|
|
- [self sendDataToSocketService:startString];
|
|
|
- }
|
|
|
- else if (self.isSoundCheckStart) { // 校音开始
|
|
|
-
|
|
|
- NSLog(@"--------- send check start message");
|
|
|
- _isSoundCheckStart = NO;
|
|
|
- NSString *checkStartMessage = @"start";
|
|
|
- NSString *startString = [self configDataCommond:checkStartMessage body:nil type:@"PITCH_DETECTION"];
|
|
|
- [self sendDataToSocketService:startString];
|
|
|
- }
|
|
|
- else if (self.isDelayCheckStart) {
|
|
|
- NSLog(@"--------- send delay check start message");
|
|
|
- _isDelayCheckStart = NO;
|
|
|
- NSString *checkStartMessage = @"recordStart";
|
|
|
- NSInteger frequence = self.checkPrequence;
|
|
|
- NSDictionary *parm = @{@"HZ" : @(frequence)};
|
|
|
- NSString *startString = [self configDataCommond:checkStartMessage body:parm type:@"DELAY_CHECK"];
|
|
|
- [self sendDataToSocketService:startString];
|
|
|
- }
|
|
|
- // NSLog(@"--------- send audio data length %d", length);
|
|
|
- [self sendDataToSocketService:pushData];
|
|
|
-}
|
|
|
-
|
|
|
-- (NSString *)configDataCommond:(NSString *)commond body:(id)bodyMessage type:(NSString *)dataType {
|
|
|
- NSMutableDictionary *parm = [NSMutableDictionary dictionary];
|
|
|
- if (bodyMessage) {
|
|
|
- [parm setValue:bodyMessage forKey:@"body"];
|
|
|
- }
|
|
|
- NSMutableDictionary *headerParm = [NSMutableDictionary dictionary];
|
|
|
- if ([NSString isEmptyString:commond]) {
|
|
|
- [headerParm setValue:@"" forKey:@"commond"];
|
|
|
- }
|
|
|
- else {
|
|
|
- [headerParm setValue:commond forKey:@"commond"];
|
|
|
- }
|
|
|
- if (![NSString isEmptyString:dataType]) {
|
|
|
- [headerParm setValue:dataType forKey:@"type"];
|
|
|
- }
|
|
|
- [headerParm setValue:@(200) forKey:@"status"];
|
|
|
- [parm setValue:headerParm forKey:@"header"];
|
|
|
- return [parm mj_JSONString];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (NSString *)configDataCommond:(NSString *)commond body:(id)bodyMessage {
|
|
|
- NSMutableDictionary *parm = [NSMutableDictionary dictionary];
|
|
|
- if (bodyMessage) {
|
|
|
- [parm setValue:bodyMessage forKey:@"body"];
|
|
|
- }
|
|
|
- if ([NSString isEmptyString:commond]) {
|
|
|
- [parm setValue:@{@"commond":@""} forKey:@"header"];
|
|
|
- }
|
|
|
- else {
|
|
|
- [parm setValue:@{@"commond":commond} forKey:@"header"];
|
|
|
- }
|
|
|
- return [parm mj_JSONString];
|
|
|
-}
|
|
|
-
|
|
|
-- (KSTargetWebSocketManager *)socketManager {
|
|
|
- if (!_socketManager) {
|
|
|
- _socketManager = [[KSTargetWebSocketManager alloc] init];
|
|
|
- }
|
|
|
- return _socketManager;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark --- lazying
|
|
|
-- (UIView *)viewContainer {
|
|
|
- if (!_viewContainer) {
|
|
|
- _viewContainer = [[UIView alloc] init];
|
|
|
- }
|
|
|
- return _viewContainer;
|
|
|
-}
|
|
|
-
|
|
|
-- (KSVideoRecordManager *)videoRecordManager {
|
|
|
- if (!_videoRecordManager) {
|
|
|
- MJWeakSelf;
|
|
|
- _videoRecordManager = [[KSVideoRecordManager alloc] initSessionRecordCallback:^(BOOL isSuccess, NSString * _Nullable message) {
|
|
|
- if (isSuccess) {
|
|
|
- [weakSelf showSuccessMessage:message];
|
|
|
- }
|
|
|
- else {
|
|
|
- if (![NSString isEmptyString:message]) {
|
|
|
- [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }];
|
|
|
- [_videoRecordManager errorMessageCallback:^(NSDictionary * _Nonnull errorParm) {
|
|
|
- [weakSelf uploadVideoRecordErrorMessage:errorParm];
|
|
|
- }];
|
|
|
- }
|
|
|
- return _videoRecordManager;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)uploadVideoRecordErrorMessage:(NSDictionary *)errorParm {
|
|
|
- NSMutableDictionary *parm = [NSMutableDictionary dictionaryWithDictionary:errorParm];
|
|
|
- [parm setValue:UserDefault(UIDKey) forKey:@"userId"];
|
|
|
- [parm setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"version"];
|
|
|
- NSString *content = [parm mj_JSONString];
|
|
|
- NSMutableDictionary *submitParm = [KSLogManager generateLogMessageWithContent:content type:@"ERROR"];
|
|
|
- NSMutableArray *uploadArray = [NSMutableArray arrayWithObject:submitParm];
|
|
|
- [KSNetworkingManager sysExceptionLogUpdate:KS_POST token:UserDefault(TokenKey) logArray:uploadArray success:^(NSDictionary * _Nonnull dic) {
|
|
|
- if ([dic ks_integerValueForKey:@"code"] == 200) {
|
|
|
-
|
|
|
- }
|
|
|
- } faliure:^(NSError * _Nonnull error) {
|
|
|
-
|
|
|
- }];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)showSuccessMessage:(NSString *)message {
|
|
|
- if (![NSString isEmptyString:message]) {
|
|
|
- [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
|
|
|
- }
|
|
|
- // 成功
|
|
|
- if (self.endRecordParm) {
|
|
|
- [self postMessage:self.endRecordParm];
|
|
|
- self.endRecordParm = nil;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (MetronomeType)getBeatTypeFromString:(NSString *)typeString {
|
|
|
- if ([typeString isEqualToString:@"1/4"]) {
|
|
|
- return MetronomeType1V4;
|
|
|
- }
|
|
|
- else if ([typeString isEqualToString:@"2/4"]) {
|
|
|
- return MetronomeType2V4;
|
|
|
- }
|
|
|
- else if ([typeString isEqualToString:@"3/4"]) {
|
|
|
- return MetronomeType3V4;
|
|
|
- }
|
|
|
- else if ([typeString isEqualToString:@"4/4"]) {
|
|
|
- return MetronomeType4V4;
|
|
|
- }
|
|
|
- else if ([typeString isEqualToString:@"3/8"]) {
|
|
|
- return MetronomeType3V8;
|
|
|
- }
|
|
|
- else if ([typeString isEqualToString:@"6/8"]) {
|
|
|
- return MetronomeType6V8;
|
|
|
- }
|
|
|
- else {
|
|
|
- return MetronomeType4V4;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-#pragma mark ------- midi 播放相关
|
|
|
-- (void)configPlayerEngineWithSong:(NSString *)songPath reportTime:(NSInteger)reportTime {
|
|
|
- self.initEngineSuccess = NO;
|
|
|
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
- self.playerEngine = [[MidiPlayerEngine alloc] init];
|
|
|
- self.playerEngine.reportTime = reportTime;
|
|
|
- self.playerEngine.delegate = self;
|
|
|
- [self.playerEngine configSoundFilePath:[[NSBundle mainBundle]
|
|
|
- pathForResource:@"synthgms" ofType:@"sf2"]];
|
|
|
- [self.playerEngine loadMIDIFileWithString:songPath];
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-- (void)configAudioSession {
|
|
|
- self.audioSessionManager = [[KSAudioSessionManager alloc] init];
|
|
|
- self.audioSessionManager.delegate = self;
|
|
|
- [self.audioSessionManager configAudioSession:AUDIOCONFIG_PLAYANDRECORD];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark ---- PlayerEngineDelegate
|
|
|
-/** 进度更新
|
|
|
- api: 'cloudTimeUpdae',
|
|
|
- content: {
|
|
|
- // 当前曲目id
|
|
|
- songID: 0,
|
|
|
- // 当前位置时间(ms)
|
|
|
- currentTime: 0
|
|
|
- }
|
|
|
- */
|
|
|
-/** 播放结束事件
|
|
|
- api: 'cloudplayed',
|
|
|
- content: {
|
|
|
- // 当前曲目id
|
|
|
- songID: 0,
|
|
|
- }
|
|
|
- */
|
|
|
-- (void)ProgressUpdated:(float)progress currentPlayTime:(MusicTimeStamp)currentPlayTime currentTime:(NSTimeInterval)currentTime {
|
|
|
-
|
|
|
- if (self.isPlaying == NO) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // 回调
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
|
|
|
- [sendParm setValue:@"cloudTimeUpdae" forKey:@"api"];
|
|
|
- NSMutableDictionary *content = [NSMutableDictionary dictionary];
|
|
|
- [content setValue:self.currentSongId forKey:@"songID"];
|
|
|
- [content setValue:@(currentPlayTime*1000) forKey:@"currentTime"];
|
|
|
- [sendParm setValue:content forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (void)playEnd {
|
|
|
- [self stopPlayAction];
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
|
|
|
- [sendParm setValue:@"cloudplayed" forKey:@"api"];
|
|
|
- NSMutableDictionary *content = [NSMutableDictionary dictionary];
|
|
|
- [content setValue:self.currentSongId forKey:@"songID"];
|
|
|
- [sendParm setValue:content forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)initPlayerEngineSuccess:(float)totalTime {
|
|
|
- self.initEngineSuccess = YES;
|
|
|
- if (self.configEngineParm) {
|
|
|
- NSMutableDictionary *sendParm = [NSMutableDictionary dictionaryWithDictionary:self.configEngineParm];
|
|
|
- NSMutableDictionary *content = [NSMutableDictionary dictionaryWithDictionary:[sendParm ks_dictionaryValueForKey:@"content"]];
|
|
|
- [content setValue:@(totalTime*1000) forKey:@"midiDuration"];
|
|
|
- [sendParm setValue:content forKey:@"content"];
|
|
|
- [self postMessage:sendParm];
|
|
|
- self.configEngineParm = nil;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 总时长
|
|
|
-- (void)GetMusicTotalTime:(float)time {
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-#pragma mark ----- 播放控制
|
|
|
-- (void)playAction {
|
|
|
- if (self.playerEngine) {
|
|
|
- self.isPlaying = YES;
|
|
|
- [self.playerEngine playMIDIFile];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)stopPlayAction {
|
|
|
- if (self.playerEngine) {
|
|
|
- self.isPlaying = NO;
|
|
|
- if ([self.playerEngine isPlayingFile]) {
|
|
|
- [self.playerEngine stopPlayingMIDIFile];
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-#pragma mark ----- 小酷AI loading
|
|
|
-- (AccompanyLoadingView *)loadingView {
|
|
|
- if (!_loadingView) {
|
|
|
- _loadingView = [AccompanyLoadingView shareInstance];
|
|
|
- MJWeakSelf;
|
|
|
- [_loadingView loadingCallback:^{
|
|
|
- [weakSelf backAction];
|
|
|
- }];
|
|
|
- }
|
|
|
- return _loadingView;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)showCustomLoading {
|
|
|
- if ([self.view.subviews containsObject:self.loadingView]) {
|
|
|
- return;
|
|
|
- }
|
|
|
- [self.view addSubview:self.loadingView];
|
|
|
- [self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
- make.left.top.right.bottom.mas_equalTo(self.view);
|
|
|
- }];
|
|
|
- [self.view bringSubviewToFront:self.loadingView];
|
|
|
- [self.loadingView showLoading];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)removeCustomLoadingView {
|
|
|
- [self.loadingView stopLoading];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark ----- 跟音模块
|
|
|
-- (void)startTuner {
|
|
|
- @try {
|
|
|
- if (self.isTunerRuning == NO) {
|
|
|
- self.isTunerRuning = YES;
|
|
|
- [self.tuner start];
|
|
|
- }
|
|
|
- } @catch (NSException *exception) {
|
|
|
- NSLog(@"----- exception --- %@", exception);
|
|
|
- } @finally {
|
|
|
-
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)stopTuner {
|
|
|
- if (self.isTunerRuning) {
|
|
|
- self.isTunerRuning = NO;
|
|
|
- [self.tuner stop];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (Tuner *)tuner {
|
|
|
- if (!_tuner) {
|
|
|
- _tuner = [[Tuner alloc] initWithThreshold:0 smoothing:0.25];
|
|
|
- _tuner.delegate = self;
|
|
|
- }
|
|
|
- return _tuner;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)tunerDidUpdate:(Tuner *)tuner output:(TunerOutput *)output {
|
|
|
- if (output.amplitude < 0.01) {
|
|
|
-
|
|
|
- }
|
|
|
- else {
|
|
|
- // 回调频率
|
|
|
- NSDictionary *parm = @{
|
|
|
- @"api" : @"cloudFollowTime",
|
|
|
- @"content" : @{@"frequency" : [NSNumber numberWithDouble:output.frequency]}
|
|
|
- };
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
- NSLog(@"-------- %@%zd --- distance :%f frequence : %f" , output.pitch, output.octave, output.distance, output.frequency);
|
|
|
-
|
|
|
-}
|
|
|
-#pragma mark ---- 保存伴奏
|
|
|
-- (BOOL)saveAccompanyFileWithUrl:(NSURL *)fileUrl accompanyUrl:(NSString *)accompanyUrl {
|
|
|
- NSData *sourceData = [NSData dataWithContentsOfURL:fileUrl];
|
|
|
- NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
|
|
|
- NSString *filePath= [cachePath stringByAppendingPathComponent:@"AccompanySong"];
|
|
|
- // 先创建子目录
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
- if (![fileManager fileExistsAtPath:filePath]) {
|
|
|
- [fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
|
|
|
- }else{
|
|
|
- NSLog(@"已创建文件夹");
|
|
|
- }
|
|
|
- NSString *fileName = [accompanyUrl getUrlFileName];
|
|
|
- NSString *tempPath = [filePath stringByAppendingPathComponent:fileName];
|
|
|
- BOOL success = [sourceData writeToFile:tempPath atomically:NO];
|
|
|
- return success;
|
|
|
-}
|
|
|
-- (NSString *)getAccompanyFilePathWithName:(NSString *)fileName {
|
|
|
- NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
|
|
|
- NSString *filePath= [cachePath stringByAppendingPathComponent:@"AccompanySong"];
|
|
|
- return [filePath stringByAppendingPathComponent:fileName];;
|
|
|
-}
|
|
|
-
|
|
|
-- (BOOL)checkSongHasSaveAccompanyWithSongUrl:(NSString *)songUrl {
|
|
|
- BOOL hasSaveFile = NO;
|
|
|
- NSString *fileName = [songUrl getUrlFileName];
|
|
|
- NSString *filePath = [self getAccompanyFilePathWithName:fileName];
|
|
|
-
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
- if ([fileManager fileExistsAtPath:filePath]) {
|
|
|
- hasSaveFile = YES;
|
|
|
- }
|
|
|
- return hasSaveFile;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark ------- Audio Engine player
|
|
|
-- (AudioEnginePlayer *)delayCheckPlayer {
|
|
|
- if (!_delayCheckPlayer) {
|
|
|
- _delayCheckPlayer = [[AudioEnginePlayer alloc] init];
|
|
|
- _delayCheckPlayer.delegate = self;
|
|
|
- }
|
|
|
- return _delayCheckPlayer;
|
|
|
-}
|
|
|
-- (AudioEnginePlayer *)musicPlayer {
|
|
|
- if (!_musicPlayer) {
|
|
|
- _musicPlayer = [[AudioEnginePlayer alloc] init];
|
|
|
- _musicPlayer.delegate = self;
|
|
|
- }
|
|
|
- return _musicPlayer;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark ---- Audio Engine player delegate
|
|
|
-- (void)enginePlayerIsReadyPlay:(AudioEnginePlayer *)player {
|
|
|
- if (player == self.delayCheckPlayer) {
|
|
|
- self.checkPlayerReady = YES;
|
|
|
- }
|
|
|
- else if (player == self.musicPlayer) {
|
|
|
- self.musicPlayerReady = YES;
|
|
|
- }
|
|
|
- // 如果都准备好
|
|
|
- if (self.musicPlayerReady && self.checkPlayerReady) {
|
|
|
- [self sendPlayerReadyMsg];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 播放进度
|
|
|
-- (void)updatePlayProgress:(NSInteger)playTime andTotalTime:(NSInteger)totalTime andProgress:(CGFloat)progress currentInterval:(NSTimeInterval)currentInterval inPlayer:(AudioEnginePlayer *)player {
|
|
|
- if (player == self.delayCheckPlayer) {
|
|
|
- if (playTime >= 300 && self.recordStartTime > 0 && self.hasRecordMusicOffset == NO) {
|
|
|
- self.hasRecordMusicOffset = YES;
|
|
|
- NSLog(@" --- check player start play time %f", currentInterval - playTime);
|
|
|
- self.playerStartTime = currentInterval - playTime;
|
|
|
- self.offsetTime = self.playerStartTime - self.recordStartTime;
|
|
|
- NSLog(@"--------- check player offset time -- %zd", self.offsetTime);
|
|
|
- }
|
|
|
- }
|
|
|
- // 如果未记录延迟
|
|
|
- if (playTime >= (self.musicStartTime + 300) && player == self.musicPlayer && self.hasRecordMusicOffset == NO) {
|
|
|
- if (self.recordStartTime > 0) {
|
|
|
- self.hasRecordMusicOffset = YES;
|
|
|
- NSInteger newPlayTime = (playTime - self.musicStartTime) / player.rate; // 选段
|
|
|
- NSLog(@" --- music player start play time %f", currentInterval - newPlayTime);
|
|
|
- self.playerStartTime = currentInterval - newPlayTime;
|
|
|
- self.offsetTime = self.playerStartTime - self.recordStartTime;
|
|
|
- NSLog(@"--------- music play offset time -- %zd", self.offsetTime);
|
|
|
- [self sendOffsetTimeToService];
|
|
|
- }
|
|
|
- NSLog(@"------- record start time %f", self.recordStartTime);
|
|
|
- }
|
|
|
-
|
|
|
- // 回调进度
|
|
|
- if (player == self.musicPlayer) {
|
|
|
-// NSLog(@"------ music play progress - %f", progress);
|
|
|
- // 回调进度
|
|
|
- NSDictionary *parm = @{
|
|
|
- @"api" : @"playProgress",
|
|
|
- @"content" : @{@"currentTime" : [NSNumber numberWithInteger:playTime],
|
|
|
- @"totalDuration" : [NSNumber numberWithInteger:totalTime],
|
|
|
- }
|
|
|
- };
|
|
|
-// NSLog(@" -----music play progress %@---- ", parm);
|
|
|
- [self postMessage:parm];
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-// 错误
|
|
|
-- (void)enginePlayerDidError:(AudioEnginePlayer *)player error:(NSError *)error {
|
|
|
- [self stopRecordService];
|
|
|
- [self stopMp3Player]; // 停止播放
|
|
|
- // 播放出现问题
|
|
|
- NSDictionary *postParm = @{@"api" : @"cancelEvaluating",
|
|
|
- @"content" : @{@"reson":@"播放已停止"}
|
|
|
- };
|
|
|
- [self postMessage:postParm];
|
|
|
-
|
|
|
- if (error) {
|
|
|
- NSLog(@"-- error desc - %@", error.description);
|
|
|
- NSMutableDictionary *parm = [NSMutableDictionary dictionary];
|
|
|
- [parm setValue:UserDefault(UIDKey) forKey:@"userId"];
|
|
|
- [parm setValue:@"KSCloudWebViewController_MP3Player" forKey:@"Location"];
|
|
|
- [parm setValue:@(error.code) forKey:@"errorCode"];
|
|
|
- [parm setValue:error.description forKey:@"errorDesc"];
|
|
|
- [parm setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"version"];
|
|
|
- NSString *content = [parm mj_JSONString];
|
|
|
- NSMutableDictionary *submitParm = [KSLogManager generateLogMessageWithContent:content type:@"ERROR"];
|
|
|
- NSMutableArray *uploadArray = [NSMutableArray arrayWithObject:submitParm];
|
|
|
- [KSNetworkingManager sysExceptionLogUpdate:KS_POST token:UserDefault(TokenKey) logArray:uploadArray success:^(NSDictionary * _Nonnull dic) {
|
|
|
- if ([dic ks_integerValueForKey:@"code"] == 200) {
|
|
|
-
|
|
|
- }
|
|
|
- } faliure:^(NSError * _Nonnull error) {
|
|
|
-
|
|
|
- }];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-- (void)sendPlayerReadyMsg {
|
|
|
- if (self.playerParm) {
|
|
|
- [self postMessage:self.playerParm];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (NSMutableArray *)delayArray {
|
|
|
- if (!_delayArray) {
|
|
|
- _delayArray = [NSMutableArray array];
|
|
|
- }
|
|
|
- return _delayArray;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- #pragma mark - Navigation
|
|
|
-
|
|
|
- // In a storyboard-based application, you will often want to do a little preparation before navigation
|
|
|
- - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
|
|
- // Get the new view controller using [segue destinationViewController].
|
|
|
- // Pass the selected object to the new view controller.
|
|
|
- }
|
|
|
- */
|
|
|
-
|
|
|
-@end
|