#import "SpeechPlugin.h" #import #import "M4aToPcmHelper.h" #import "Mp4ToPcmHelper.h" #import "Results/ISEResult.h" #import "Results/ISEResultXmlParser.h" #import "Results/ISEResultTools.h" @interface SpeechPlugin () @property (nonatomic, strong) IFlySpeechEvaluator *iFlySpeechEvaluator; @property (nonatomic, strong) NSNumber *index; @end @implementation SpeechPlugin + (void)registerWithRegistrar:(NSObject*)registrar { _channel = [FlutterMethodChannel methodChannelWithName:@"speech_plugin" binaryMessenger:[registrar messenger]]; SpeechPlugin* instance = [[SpeechPlugin alloc] init]; [registrar addMethodCallDelegate:instance channel: _channel]; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { if ([@"getPlatformVersion" isEqualToString:call.method]) { result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); } else if ([@"initSpeechSdk" isEqualToString:call.method]) { [self iflyInit]; } else if ([@"evaluatorByAudio" isEqualToString:call.method]) { NSNumber* index = call.arguments[@"index"]; NSString* recordPath = call.arguments[@"recordPath"]; NSString* text = call.arguments[@"en"]; [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:false]; } else if ([@"evaluatorByMp4" isEqualToString:call.method]) { NSNumber* index = call.arguments[@"index"]; NSString* recordPath = call.arguments[@"recordPath"]; NSString* text = call.arguments[@"en"]; [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:true]; } else { result(FlutterMethodNotImplemented); } } #pragma mark - Bridge Actions - (void)iflyInit { [IFlySpeechUtility createUtility:@"appid=5db7af6b"]; self.iFlySpeechEvaluator = [IFlySpeechEvaluator sharedInstance]; self.iFlySpeechEvaluator.delegate = self; [self configEvaluator]; } - (void) configEvaluator { [self.iFlySpeechEvaluator setParameter:@"" forKey:[IFlySpeechConstant PARAMS]]; [self.iFlySpeechEvaluator setParameter:@"read_sentence" forKey:[IFlySpeechConstant ISE_CATEGORY]]; [self.iFlySpeechEvaluator setParameter:@"en_us" forKey:[IFlySpeechConstant LANGUAGE]]; [self.iFlySpeechEvaluator setParameter:@"5000" forKey:[IFlySpeechConstant VAD_BOS]]; [self.iFlySpeechEvaluator setParameter:@"1800" forKey:[IFlySpeechConstant VAD_EOS]]; [self.iFlySpeechEvaluator setParameter:@"-1" forKey:[IFlySpeechConstant SPEECH_TIMEOUT]]; [self.iFlySpeechEvaluator setParameter:@"complete" forKey:[IFlySpeechConstant ISE_RESULT_LEVEL]]; [self.iFlySpeechEvaluator setParameter:@"16000" forKey:[IFlySpeechConstant SAMPLE_RATE]]; [self.iFlySpeechEvaluator setParameter:@"xml" forKey:[IFlySpeechConstant ISE_RESULT_TYPE]]; [self.iFlySpeechEvaluator setParameter:@"0" forKey:@"plev"]; [self.iFlySpeechEvaluator setParameter:@"-1" forKey:@"audio_source"]; } - (void) evaluateVoice: (NSNumber*)index andPath:(NSString*)path andText:(NSString*)text andIsVideo:(BOOL) isVideo { self.index = index; if(isVideo) { [Mp4ToPcmHelper Mp4ToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path] completion:^(NSData *data) { if(data == nil) { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; return; } NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]]; [self.iFlySpeechEvaluator startListening:buffer params:nil]; [self.iFlySpeechEvaluator writeAudio:data]; [self.iFlySpeechEvaluator stopListening]; }]; } else { NSData *voiceData = [M4aToPcmHelper M4aToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path]]; if(voiceData == nil) { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; return; } NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]]; [self.iFlySpeechEvaluator startListening:buffer params:nil]; [self.iFlySpeechEvaluator writeAudio:voiceData]; [self.iFlySpeechEvaluator stopListening]; } } #pragma mark - iFly delegate // 评测结果回调 - (void)onResults:(NSData *)results isLast:(BOOL)isLast { if (isLast) { if(results) { const char* chResult = [results bytes]; NSString* strResults = nil; NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); strResults = [[NSString alloc] initWithBytes:chResult length:[results length] encoding:encoding]; if(strResults != nil) { ISEResultXmlParser *parser = [ISEResultXmlParser alloc]; [parser setDelegate:self]; [parser parserXml:strResults]; } else { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; } } else { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; } } } - (void)onCompleted:(IFlySpeechError *)errorCode { if (errorCode.errorCode != 0) { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; } } - (void)onCancel {} - (void)onBeginOfSpeech {} - (void)onEndOfSpeech {} - (void)onVolumeChanged:(int)volume buffer:(NSData *)buffer {} #pragma mark - ISEResultXmlParser delegate -(void)onISEResultXmlParser:(NSXMLParser *)parser Error:(NSError*)error { if (error.code != 0) { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; } } -(void)onISEResultXmlParserResult:(ISEResult*)result { if (result.is_rejected) { [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]]; } else { NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setValue:self.index forKey:@"index"]; [dic setValue:@(result.total_score) forKey:@"score"]; [dic setValue:@(result.accuracy_score) forKey:@"accuracy_score"]; [dic setValue:@(result.fluency_score) forKey:@"fluency_score"]; [dic setValue:@(result.integrity_score) forKey:@"integrity_score"]; NSString* words = [ISEResultTools formatDetailsForLanguageEN: result.sentences]; [dic setValue:words forKey:@"words"]; [_channel invokeMethod:@"evaluatorResult" arguments: dic]; } } @end