SpeechPlugin.m 6.9 KB

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