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后的播报功能问题与实现相关推荐

  1. IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应

    (转)IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应 IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油 ...

  2. IOS开发百度地图API

    IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油站 IOS百度地图视角跳到用户当前位置 IOS百度地图开发实时路况 IO ...

  3. IOS开发百度地图API-用点生成路线,导航,气泡响应

    原地址:http://blog.sina.com.cn/s/blog_68661bd80101k4rx.html IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发 ...

  4. 安卓(Android)开发百度语音唤醒(识别)

    安卓(Android)开发百度语音唤醒(识别) 目录 安卓(Android)开发百度语音唤醒(识别) 一:准备 1:获取自定义唤醒词 2:SDK下载 3:将bdasr_V3_xxx_xxx.jar引入 ...

  5. iOS开发之语音说话

    iOS开发之语音说话 在开发中遇到一个要写语音说话的功能 .  其效果类似于QQ语音说话. 因为语音说话的手势较多  因此我写了一个单例 第一步: //语音说话要加入一个系统的第三方库AVFounda ...

  6. ios 开发百度地图的使用

    IOS开发百度地图API-用点生成路线,导航,气泡响应 IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油站 IOS百度地 ...

  7. 转:IOS开发百度地图API-用点生成路线,导航,气泡响应

    IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油站 IOS百度地图视角跳到用户当前位置 IOS百度地图开发实时路况 IO ...

  8. iOS开发UI篇-在UItableview中实现加载更多功能

    iOS开发UI篇-在UItableview中实现加载更多功能 一.实现效果 点击加载更多按钮,出现一个加载图示,三秒钟后添加两条新的数据. 二.实现代码和说明 当在页面(视图部分)点击加载更多按钮的时 ...

  9. iOS开发-面部距离识别 Vision 护眼模式 儿童防近视功能

    iOS开发-面部距离识别 Vision 护眼模式 儿童防近视功能 前言-基于Vision和CIDetector 举例 大概思路 API 使用 Demo 前言-基于Vision和CIDetector i ...

  10. iOS开发68-iOS 如何让UIScrollView在手指离开后立即停止滑动

    iOS开发68-iOS 如何让UIScrollView在手指离开后立即停止滑动 在Delegate里面 -(void)scrollViewWillBeginDecelerating: (UIScrol ...

最新文章

  1. 揭富人与穷人21个不同思维 看富豪如何脱颖而出
  2. oracle层次查询用处,Oracle描述层次查询(hierarchicalquery)
  3. 【Java多线程】高级主题:定时调度、quartz、指令重排、volatile、ThreadLocal
  4. Spring boot验证码前后端验证
  5. oracle获取一段时间内所有的小时、天、月
  6. ASN.1编解码:asn1c-ORAN-E2AP
  7. ali arthas 火焰图_阿里巴巴 Arthas 3.1.5版本支持火焰图,快速定位应用热点
  8. python服务器搭建qt搭建客户端_利用PythonQT,定制服务器启动工具
  9. Word 绘制三线格 调整磅数
  10. 音乐播放器代码和网页播放器代码
  11. hdfs 指令_HDFS之一:hdfs命令行操作
  12. 电视机和机顶盒等焦点问题
  13. 2022级-第2次作业-基本数据类型与表达式
  14. SPWM原理及STM32生成
  15. 正则匹配文本中的括号
  16. 安装sql server 2000时又出现:安装程序配置服务器失败。参考服务器错误日志和 C:/WINNT/sqlstp.log 了解更多信息。
  17. 地狱模式的居转户记录 02
  18. 关于oracle-ocp你要知道的都在这里
  19. WEB应用程序开发与部署
  20. linux su密码重置,Linux重置root用户密码

热门文章

  1. 通过网络启动计算机,实现通过局域网唤醒计算机的两种方法
  2. 网易云ncm转mp3
  3. 根据url链接来下载资源
  4. 微信小程序教程、微信小程序开发资源下载汇总
  5. FX DocuPrint M268 dw打印机硒鼓清零
  6. 由我国科学家研制的计算机,由我国科学家研制的系列超级计算机综合技术处于国际领先水平,2015年11月,全球超级计算机...
  7. 基于html的2048小游戏,基于jQuery的2048小游戏设计(网页版)
  8. unity 自动生成脚本
  9. 水面船舶雷达监视-信天翁雷达监视系统
  10. php smarty程序设计,Smarty程序设计-动态文件操作