SpeechPlugin.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #import "SpeechPlugin.h"
  2. #import <iflyMSC/iflyMSC.h>
  3. #import "M4aToPcmHelper.h"
  4. #import "Mp4ToPcmHelper.h"
  5. #import "Results/ISEResult.h"
  6. #import "Results/ISEResultXmlParser.h"
  7. #import "Results/ISEResultTools.h"
  8. @interface SpeechPlugin () <IFlySpeechEvaluatorDelegate, ISEResultXmlParserDelegate>
  9. @property (nonatomic, strong) IFlySpeechEvaluator *iFlySpeechEvaluator;
  10. @property (nonatomic, strong) NSNumber *index;
  11. @end
  12. @implementation SpeechPlugin
  13. + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  14. _channel = [FlutterMethodChannel
  15. methodChannelWithName:@"speech_plugin"
  16. binaryMessenger:[registrar messenger]];
  17. SpeechPlugin* instance = [[SpeechPlugin alloc] init];
  18. [registrar addMethodCallDelegate:instance channel: _channel];
  19. }
  20. - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  21. if ([@"getPlatformVersion" isEqualToString:call.method]) {
  22. result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  23. } else if ([@"initSpeechSdk" isEqualToString:call.method]) {
  24. [self iflyInit];
  25. } else if ([@"evaluatorByAudio" isEqualToString:call.method]) {
  26. NSNumber* index = call.arguments[@"index"];
  27. NSString* recordPath = call.arguments[@"recordPath"];
  28. NSString* text = call.arguments[@"en"];
  29. [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:false];
  30. } else if ([@"evaluatorByMp4" isEqualToString:call.method]) {
  31. NSNumber* index = call.arguments[@"index"];
  32. NSString* recordPath = call.arguments[@"recordPath"];
  33. NSString* text = call.arguments[@"en"];
  34. [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:true];
  35. } else {
  36. result(FlutterMethodNotImplemented);
  37. }
  38. }
  39. #pragma mark - Bridge Actions
  40. - (void)iflyInit {
  41. [IFlySpeechUtility createUtility:@"appid=5db7af6b"];
  42. self.iFlySpeechEvaluator = [IFlySpeechEvaluator sharedInstance];
  43. self.iFlySpeechEvaluator.delegate = self;
  44. [self configEvaluator];
  45. }
  46. - (void) configEvaluator {
  47. [self.iFlySpeechEvaluator setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
  48. [self.iFlySpeechEvaluator setParameter:@"read_sentence" forKey:[IFlySpeechConstant ISE_CATEGORY]];
  49. [self.iFlySpeechEvaluator setParameter:@"en_us" forKey:[IFlySpeechConstant LANGUAGE]];
  50. [self.iFlySpeechEvaluator setParameter:@"5000" forKey:[IFlySpeechConstant VAD_BOS]];
  51. [self.iFlySpeechEvaluator setParameter:@"1800" forKey:[IFlySpeechConstant VAD_EOS]];
  52. [self.iFlySpeechEvaluator setParameter:@"-1" forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];
  53. [self.iFlySpeechEvaluator setParameter:@"complete" forKey:[IFlySpeechConstant ISE_RESULT_LEVEL]];
  54. [self.iFlySpeechEvaluator setParameter:@"16000" forKey:[IFlySpeechConstant SAMPLE_RATE]];
  55. [self.iFlySpeechEvaluator setParameter:@"xml" forKey:[IFlySpeechConstant ISE_RESULT_TYPE]];
  56. [self.iFlySpeechEvaluator setParameter:@"0" forKey:@"plev"];
  57. [self.iFlySpeechEvaluator setParameter:@"-1" forKey:@"audio_source"];
  58. }
  59. - (void) evaluateVoice: (NSNumber*)index andPath:(NSString*)path andText:(NSString*)text andIsVideo:(BOOL) isVideo
  60. {
  61. self.index = index;
  62. if(isVideo) {
  63. [Mp4ToPcmHelper Mp4ToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path] completion:^(NSData *data) {
  64. if(data == nil) {
  65. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  66. return;
  67. }
  68. NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  69. NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]];
  70. [self.iFlySpeechEvaluator startListening:buffer params:nil];
  71. [self.iFlySpeechEvaluator writeAudio:data];
  72. [self.iFlySpeechEvaluator stopListening];
  73. }];
  74. } else {
  75. NSData *voiceData = [M4aToPcmHelper M4aToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path]];
  76. if(voiceData == nil) {
  77. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  78. return;
  79. }
  80. NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  81. NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]];
  82. [self.iFlySpeechEvaluator startListening:buffer params:nil];
  83. [self.iFlySpeechEvaluator writeAudio:voiceData];
  84. [self.iFlySpeechEvaluator stopListening];
  85. }
  86. }
  87. #pragma mark - iFly delegate
  88. // 评测结果回调
  89. - (void)onResults:(NSData *)results isLast:(BOOL)isLast {
  90. if (isLast) {
  91. if(results) {
  92. const char* chResult = [results bytes];
  93. NSString* strResults = nil;
  94. NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  95. strResults = [[NSString alloc] initWithBytes:chResult length:[results length] encoding:encoding];
  96. if(strResults != nil) {
  97. ISEResultXmlParser *parser = [ISEResultXmlParser alloc];
  98. [parser setDelegate:self];
  99. [parser parserXml:strResults];
  100. } else {
  101. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  102. }
  103. } else {
  104. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  105. }
  106. }
  107. }
  108. - (void)onCompleted:(IFlySpeechError *)errorCode {
  109. if (errorCode.errorCode != 0) {
  110. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  111. }
  112. }
  113. - (void)onCancel {}
  114. - (void)onBeginOfSpeech {}
  115. - (void)onEndOfSpeech {}
  116. - (void)onVolumeChanged:(int)volume buffer:(NSData *)buffer {}
  117. #pragma mark - ISEResultXmlParser delegate
  118. -(void)onISEResultXmlParser:(NSXMLParser *)parser Error:(NSError*)error {
  119. if (error.code != 0) {
  120. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  121. }
  122. }
  123. -(void)onISEResultXmlParserResult:(ISEResult*)result {
  124. if (result.is_rejected) {
  125. [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
  126. } else {
  127. NSMutableDictionary *dic = [NSMutableDictionary dictionary];
  128. [dic setValue:self.index forKey:@"index"];
  129. [dic setValue:@(result.total_score) forKey:@"score"];
  130. [dic setValue:@(result.accuracy_score) forKey:@"accuracy_score"];
  131. [dic setValue:@(result.fluency_score) forKey:@"fluency_score"];
  132. [dic setValue:@(result.integrity_score) forKey:@"integrity_score"];
  133. NSString* words = [ISEResultTools formatDetailsForLanguageEN: result.sentences];
  134. [dic setValue:words forKey:@"words"];
  135. [_channel invokeMethod:@"evaluatorResult" arguments: dic];
  136. }
  137. }
  138. @end