“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情”
引言
-
付费方案(付费离线SDK+Service Extension):kunnan.blog.csdn.net/article/det…
-
免费方案:(本地拼接音频+Service Extension)download.csdn.net/download/u0…
采用语音合成音频文件后,将文件写到AppGroups的Library/Sounds文件夹下,最后更改UNNotificationSound属性来自定义的收款到账语音。
如果无法下载,可通过添加WX:iosrev
修订版demo:iOS15 消息推送语言播报【修订版】(处于后台/被杀死的状态仍可进行语言播报)
download.csdn.net/download/u0…
原理: 本地离线合成音频+Service Extension
⭕ 解决离线合成比较成本昂贵问题:采用本地拼接音频实现。
⭕ 解决iOS15之后本地通知通知栏弹出多次的问题:使用Service Extension拦截消息推送,修改UNNotificationSound为本地拼接的音频,来避免产生多条横幅。
合并的音频保存在AppGroup:
⭕ 解决金额转换为对应的文字的细节问题(numFormatter的兼容处理)
I 后台语音播报推送信息
1.1 实现原理
iOS12.1 以下使用AVAudioPlayer进行语音播报,iOS12.1 - iOS14 可以使用本地通知进行语音播报,iOS15 通过修改推送sounds字段来播报自定义的语音。
-
在iOS10中推出的Notification Service Extension(以下简称NSE),当apns的payload上带上"mutable-content"的值为1时,就会进入NSE的代码中。
-
在NSE中通过给UNNotificationContent中的Sound属性赋值来达到在通知弹出时播放一段自定义音频的目的。
利用离线合成或者从后台下载的方式,生成需要播报的内容,通过自定义通知铃声的方式,达到语音播报提醒的目的。
- 音频存储在AppGroups中: 通过离线语音合成库生成wav音频文件后,将文件写到AppGroups的Library/Sounds文件夹下,最后更改UNNotificationSound属性即可使通知播报一段自定义的收款到账语音。
扩展和主应用都要配置AppGroupsID,否则获取不到groupURL。
NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kAppGroupID];
1.2 推送语音播报总控制逻辑
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
UNMutableNotificationContent *bestAttemptContent = [request.content mutableCopy];
NSLog(@"NotificationService_%@: dict->%@", NSStringFromClass([self class]), bestAttemptContent.userInfo);
bestAttemptContent.sound = nil;
[YJAudioTool.sharedPlayer.userInfos addObject: bestAttemptContent];
if (@available(iOS 15.0, *)) {
// self.contentHandler(bestAttemptContent);
// 调用iOS15之后的递归方法处理消息
[self processNotificationContent4ios15];
return;
}
// 调用iOS14之前的递归方法处理消息
[self processNotificationContent];
}
-
原来iOS14之前的旧方式实现demo下载地址:download.csdn.net/download/u0…
-
iOS15的实现demo下载地址:download.csdn.net/download/u0…
- (void)processNotificationContent4ios15{
__weak __typeof__(self) weakSelf = self;
if(YJAudioTool.sharedPlayer.userInfos.count<1){// 递归的退出条件
return ;
}
请查看原文:https://blog.csdn.net/z929118967/article/details/123325914
}
1.3 合并音频到在AppGroup中
合并音频:
- sourceURLsArr的元素是全路径 NSString *mp3Path1 = [[NSBundle mainBundle] pathForResource:audioFileURL ofType:nil];
- AppGroups共享目录:
NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kAppGroupID];
- (void)mergeAVAssetWithSourceURLs:(NSArray *)sourceURLsArr completed:(void (^)(NSString * soundName,NSURL * soundsFileURL)) completed{
//创建音频轨道,并获取多个音频素材的轨道
AVMutableComposition *composition = [AVMutableComposition composition];
请查看原文:https://blog.csdn.net/z929118967/article/details/123325914
}
通过NSFileManager把输出音频保存在【AppGroup】的/Library/Sounds/里面.
AVAssetExportSession的输出路径必须要保证文件夹存在,不然会提示操作有误。
II 实现细节
将金额转换为对应的文字(numFormatter的兼容处理)
blog.csdn.net/z929118967/…
查找金额文字对应的音频文件
+ (NSString *)audioFileWithString:(NSString *)fileName {
if([fileName isEqualToString:@"零"] || [fileName isEqualToString:@"〇"]) return @"tts_0.mp3";//兼容0
//https://kunnan.blog.csdn.net/article/details/123330008
}
iOS15 消息推送语言播报【修订版】(处于后台/被杀死的状态仍可进行语言播报)
原理: 本地离线合成音频+Service Extension
⭕ 解决离线合成比较成本昂贵问题:采用本地拼接音频实现。
⭕ 解决iOS15之后本地通知通知栏弹出多次的问题:使用Service Extension拦截消息推送,修改UNNotificationSound为本地拼接的音频,来避免产生多条横幅。
合并的音频保存在AppGroup:
⭕ 解决金额转换为对应的文字的细节问题(numFormatter的兼容处理)
———————————————— 版权声明:本文为CSDN博主「iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/z929118967/…