IOS开发 百度语音实现播报及IOS12.1后的播报功能问题与实现
iOS 百度語音實現播報及iOS12.1后的播報功能問題與實現
?
最近碰到個接收到推送要實現語音播報的需求,需要后臺推送通知,APP客戶端收到通知之后語音播放:“您的賬戶收到一筆巨款”的功能。使用到了Notification Service Extension服務。
在之前的記錄使用AVSpeechUtterance 來進行語音播報。
文章地址:http://www.laileshuo.com/?p=1324
經過實驗AVSpeechUtterance語音聲音很奇怪,于是考慮使用百度語音合成來實現播報。使用到的即是語音合成系統(TTS):語音合成(Text To Speech,TTS):將文本合成為語音,即聲音文件。
集成百度語音合成地址:https://ai.baidu.com/docs#/TTS-iOS-SDK/top
?
一、集成百度TTS
?
- 加入sdk
下載百度語音合成的SDK,我們需要BDSClientLib中的libBaiduSpeechSDK,Headers中的TTS文件夾下的文件,Resource文件夾的資源。將這些文件放到NotificationService文件夾下
如圖所示
- 添加依賴庫
使用到的依賴庫libsqlite3.0.tbd、libiconv.2.4.0.tbd、libc++.tbd、libz.1.2.5.tbd、GLKit.framework、SystemConfiguration.framework、AudioToolbox.framework、AVFoundation.framework、CFNetwork.framework、CoreLocation.framework、CoreTelephony.framework
?
二、代碼實現
?
在NotificationService上實現代碼
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {self.contentHandler = contentHandler;self.bestAttemptContent = [request.content mutableCopy];// 語音合成,使用AVAudioPlayer播放,成功[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];[self configureSDK];// 這個info 內容就是通知信息攜帶的數據,后面我們取語音播報的文案,通知欄的title,以及通知內容都是從這個info字段中獲取NSString *alert = self.bestAttemptContent.userInfo[@"alert"];// 播報語音//百度語音TTSNSError *err = nil;NSInteger sentenceID = [[BDSSpeechSynthesizer sharedInstance] speakSentence: alert withError:&err];NSLog(@"sentenceID:%ld error:%@",(long)sentenceID,err);self.contentHandler(self.bestAttemptContent); }-(void)configureSDK{NSLog(@"TTS version info: %@", [BDSSpeechSynthesizer version]);if (!self.baiduPlayer) {self.baiduPlayer = [[BDSBuiltInPlayer alloc] init];self.baiduPlayer.delegate = self;}[BDSSpeechSynthesizer setLogLevel:BDS_PUBLIC_LOG_VERBOSE];[[BDSSpeechSynthesizer sharedInstance] setSynthesizerDelegate:self];[self configureOnlineTTS];[self configureOfflineTTS]; }-(void)configureOnlineTTS {[[BDSSpeechSynthesizer sharedInstance] setApiKey:NS_Baidu_API_KEY withSecretKey:NS_Baidu_SECRET_KEY];[[BDSSpeechSynthesizer sharedInstance] setSynthParam:@(BDS_SYNTHESIZER_SPEAKER_FEMALE) forKey:BDS_SYNTHESIZER_PARAM_SPEAKER]; }-(void)configureOfflineTTS {NSError *err = nil;// 在這里選擇不同的離線音庫(請在XCode中Add相應的資源文件),同一時間只能load一個離線音庫。根據網絡狀況和配置,SDK可能會自動切換到離線合成。NSString* offlineEngineSpeechData = [[NSBundle mainBundle] pathForResource:@"Chinese_And_English_Speech_Female" ofType:@"dat"];NSString* offlineChineseAndEnglishTextData = [[NSBundle mainBundle] pathForResource:@"Chinese_And_English_Text" ofType:@"dat"];err = [[BDSSpeechSynthesizer sharedInstance] loadOfflineEngine:offlineChineseAndEnglishTextData speechDataPath:offlineEngineSpeechData licenseFilePath:self.localPath withAppCode:NS_Baidu_APP_ID];if(err){return;} }?
三、測試
?
首先選中主app運行到手機上,之后運行NotificationService
最后在極光上進行推送。
最后收到播放聲音。
?
四、特別注意的事情
?
下面是關于iOS12.1之后:在12.1之后,在這個推送擴展就無法在后臺進行播放了.
?
1、在12.1之后 推送擴展就無法在后臺進行播放
?
下圖是官方給出的說明,之前給出這個拓展推送主要是為了豐富推送的UI樣式,推送信息加密之類的,結果卻被用做推送語音播報,所以就發了這個聲明,在12.1之后,在這個推送擴展就無法在后臺進行播放了.
所以 iOS12.1使用百度語音無法播報。
?
2、測試遇到的現象
/ 12.1版本,AVAudioPlayer后臺播放會失敗NSString *path = [[NSBundle mainBundle] pathForResource:@"audio" ofType:@"mp3"];NSURL *url = [NSURL fileURLWithPath:outPutFilePath];self.myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];self.myPlayer.delegate = self; [self.myPlayer play];// 12.1版本,AudioServicesPlayAlertSoundWithCompletion后臺播放會失敗static SystemSoundID soundID = 0;AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);AudioServicesPlayAlertSoundWithCompletion(soundID, ^{NSLog(@"播放完成"); });既然12.1,NotificationService中無法進行后臺播報,所以使用AVAudioPlayer、AudioServicesCreateSystemSoundID都會失敗
如果在NotificationService中info.plist文件中加入
plist里面需要加UIBackgroundModes的 audio 就可以播放了
但是:
這個當打包上傳到Appstore上就會出現錯誤了,提示說NotificationService中的UIBackgroundModes的Audio這個字段是非法的,無法添加的。
?
3、解決方案之修改通知的UNNotificationSound
?
在收到推送后,我們可以將消息拆成多個本地,每個通知NotificationContent的Sound都對應工程資源的一個音頻文件。
代碼所示:
- (void)playWithRegisterNotifications:(NSString *)content {NSArray *array = @[@"shoukuan",@"2",@"bai",@"5",@"shi",@"dian",@"0",@"8",@"yuan"];for (NSString *string in array) {dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);[self registerNotificationWithString:string completeHandler:^{//延遲大于1秒感覺更好一點dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{dispatch_semaphore_signal(semaphore);});}];dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);} }- (void)registerNotificationWithString:(NSString *)string completeHandler:(dispatch_block_t)complete {[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {if (granted) {UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init];content.title = @"";content.subtitle = @"";content.body = @"";content.sound = [UNNotificationSound soundNamed:[NSString stringWithFormat:@"%@.mp3",string]];content.categoryIdentifier = [NSString stringWithFormat:@"categoryIndentifier%@",string];UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:[NSString stringWithFormat:@"categoryIndentifier%@",string] content:content trigger:trigger];[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {if (error == nil) {if (complete) {complete();}}}];}}]; }經過測試,可以播放,但是:
dispatch_after在0.25秒后執行一個本地通知,但是這個情況很容易出現第語音播放不完整的情況,如果時間設置過大,語音播放的語速就很慢,體驗極差。聲音的大小也無法調整。
這種情況下可以采用通用的提示,如:您有一筆收款。這樣的語音提示體驗會好點,但是不是最優的方式
?
4、關于支付寶或者微信語音播報
?
經過查找,大概率支付寶、微信使用的使用voip模式,通過查找微信與支付寶的ipa,ipa中配置的文件都UIBackgroundModes(后臺模式)包含voip。
所以大概率支付寶與微信都使用的是Voip PushKit實現的收款的語音播報功能
之后也會調查下Voip PushKit實現的收款的語音播報功能,PushKit和極光推送還不太一樣。持續關注中。。。
本文地址:http://www.laileshuo.com/?p=1347
博客地址:www.laileshuo.com
總結
以上是生活随笔為你收集整理的IOS开发 百度语音实现播报及IOS12.1后的播报功能问题与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: word2计算机fx公式,Word的fx
- 下一篇: 整理:C primer plus 学习笔