iOS基于AVFoundation实现朗读文字
iOS基于AVFoundation实现朗读文字
1.心理建设
众所周知AVFoundation的朗读是个智障语气,所以想不花钱就只能忍着。
2.speechManager
@import AVFoundation;
@protocol TJSpeechManagerDelegate <NSObject>
@optional
- (void)didStartSpeechUtterance:(AVSpeechUtterance*)utterance;
- (void)didFinishSpeechUtterance:(AVSpeechUtterance*)utterance;
- (void)didPauseSpeechUtterance:(AVSpeechUtterance*)utterance;
- (void)didCancelSpeechUtterance:(AVSpeechUtterance*)utterance;
- (void)willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance;
- (void)needRepeatSpeech:(AVSpeechUtterance *)utterance;
@end
@interface TJSpeechManager : NSObject <AVSpeechSynthesizerDelegate>
@property (nonatomic, strong) AVSpeechSynthesizer *avSpeech;
@property (nonatomic, strong) AVSpeechUtterance *speechUtt;
@property (nonatomic, assign) id <TJSpeechManagerDelegate> delegate;
- (void)setSpeechContent:(NSString *)content;
- (void)pauseSpeech;
- (void)beginSpeech;
- (void)continueSpeech;
- (void)endSpeech;
@end
#import "TJSpeechManager.h"
@implementation TJSpeechManager
- (void)setSpeechContent:(NSString *)content {
AVSpeechUtterance *speechUtt = [AVSpeechUtterance speechUtteranceWithString:content];
speechUtt.rate = 0.5;
speechUtt.pitchMultiplier = 1;
//设置音量,[0-1] 默认 = 1
speechUtt.volume = 1;
//读一段前的停顿时间
speechUtt.preUtteranceDelay = 1;
//读完一段后的停顿时间
speechUtt.postUtteranceDelay = 1;
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
speechUtt.voice = voice;
self.speechUtt = speechUtt;
}
- (void)beginSpeech {
//这里需要注意一下,一个avspeech对象只能播放一次,同一个对象中途不能重新播放。
AVSpeechSynthesizer *avSpeech = [[AVSpeechSynthesizer alloc] init];
avSpeech.delegate = self;
[avSpeech speakUtterance:self.speechUtt];
self.avSpeech = avSpeech;
}
- (void)pauseSpeech {
[self.avSpeech pauseSpeakingAtBoundary:AVSpeechBoundaryImmediate];
}
- (void)continueSpeech {
if(self.avSpeech.isPaused) {
[self.avSpeech continueSpeaking];
[NSThread sleepForTimeInterval:0.25f];
}
}
- (void)endSpeech {
if(self.avSpeech.isSpeaking) {
[self.avSpeech stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
[NSThread sleepForTimeInterval:0.25f];
}
}
//代理主要是返回给controller,用来和UI交互
#pragma mark - AVSpeechSynthesizerDelegate;
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didStartSpeechUtterance:(AVSpeechUtterance*)utterance{
NSLog(@"---开始播放");
if(self.delegate && [self.delegate respondsToSelector:@selector(didStartSpeechUtterance:)]) {
[self.delegate didStartSpeechUtterance:utterance];
}
}
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance*)utterance{
NSLog(@"---完成播放");
if(self.delegate && [self.delegate respondsToSelector:@selector(didFinishSpeechUtterance:)]) {
[self.delegate didFinishSpeechUtterance:utterance];
}
}
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance*)utterance{
NSLog(@"---播放中止");
if(self.delegate && [self.delegate respondsToSelector:@selector(didPauseSpeechUtterance:)]) {
[self.delegate didPauseSpeechUtterance:utterance];
}
}
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance*)utterance{
NSLog(@"---恢复播放");
}
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance*)utterance{
NSLog(@"---播放取消");
if(self.delegate && [self.delegate respondsToSelector:@selector(didCancelSpeechUtterance:)]) {
[self.delegate didCancelSpeechUtterance:utterance];
}
}
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance {
if(self.delegate && [self.delegate respondsToSelector:@selector(willSpeakRangeOfSpeechString:utterance:)]) {
[self.delegate willSpeakRangeOfSpeechString:characterRange utterance:utterance];
}
}
@end
3.使用范例
//分页控制器获取到当前页内容
-(void)pageReadViewControllerSpeechContent:(NSString *)content
{
//先停止语音 防止用户翻页造成声音重叠
[self.speechManager endSpeech];
//当期是否开启了朗读功能
if (self.isSpeechNextPage == YES ) {
//内容不为空 代表可以朗读下一页
if ( content && content.length > 0) {
//设置朗读内容
[self.speechManager setSpeechContent:content];
//开始朗读
[self.speechManager beginSpeech];
}else{
self.isSpeechNextPage = NO;
[self.speechManager endSpeech];
}
}
}
///朗读按钮开启
-(void)readMenuDidOpenSpeechRead
{
self.isSpeechNextPage = YES;
//用于刷新当前页内容 从而调用pageReadViewControllerSpeechContent
[self speechNextPage:self.book.page];
}
//用户关闭朗读
-(void)readMenuDidCloseSpeechRead
{
[self.speechManager pauseSpeech];
self.isSpeechNextPage = NO;
}
//当前页内容读完
- (void)didFinishSpeechUtterance:(AVSpeechUtterance *)utterance
{
//我这里的逻辑是用于控制翻页还是下一章
//下一章或者下一页都会重绘pageViewControl内容 从而继续响应 pageReadViewControllerSpeechContent 的回调代理
if ([TJReadRecordManager recordWithBookId:self.book.bookId].page + 2 > [TJReadRecordManager recordWithBookId:self.book.bookId].chapter.pageModels.count) {
[self readMenuDidChangeChapter:YES];
}else{
[self speechNextPage:[TJReadRecordManager recordWithBookId:self.book.bookId].page + 1];
}
}
4.简单使用
如果各位想简单应用一下
初始化 manager
-(TJSpeechManager *)speechManager
{
if (!_speechManager) {
_speechManager = [[TJSpeechManager alloc]init];
_speechManager.delegate = self;
}
return _speechManager;
}
然后直接开始朗读就行了
[self.speechManager setSpeechContent:@"想说的话"];
//开始朗读
[self.speechManager beginSpeech];
5.退出
退出页面记得停止播放
-(void)dealloc
{
self.speechManager.delegate = nil;
[self.speechManager endSpeech];
}
附上APP地址: 一阅阅读有想看小说的小伙伴可以试下 支持换源 支持自定义书源
iOS基于AVFoundation实现朗读文字的更多相关文章
- 使用安卓中的TextToSpeech控件实现朗读文字
首先感谢原文的博主,本文中的代码均来自该博主:(原文地址)http://flycatdeng.iteye.com/blog/1827245 朗读文字不需要任何的权限,这个控件的好处是首先不要权限,其次 ...
- iOS 基于MVC设计模式的基类设计
iOS 基于MVC设计模式的基类设计 https://www.jianshu.com/p/3b580ffdae00
- IOS基于XMPP协议开发--XMPPFramewok框架(一):基础知识
最近蘑菇街团队的TT的开源,使我对im产生了兴趣,然后在网上找到了XMPPFramework进行学习研究, 并写了以下系列教程供大家参考,有写的不对的地方,请大家多多包涵指正. 目录索引 IOS基于X ...
- 手淘架构组最新实践 | iOS基于静态库插桩的⼆进制重排启动优化 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 编译期插桩
抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 原创 Leo 字节跳动技术团队 2019-08-09 https://mp.weixin.qq.com/s/Drmmx5JtjG ...
- iOS基于MVC的项目重构总结
关于MVC的争论 关于MVC的争论已经有很多,对此我的观点是:对于iOS开发中的绝大部分场景来说,MVC本身是没有问题的,你认为的MVC的问题,一定是你自己理解的问题(资深架构师请自动忽略本文). 行 ...
- 转:iOS基于MVC的项目重构总结
转:http://www.cocoachina.com/ios/20160519/16346.html 关于MVC的争论 关于MVC的争论已经有很多,对此我的观点是:对于iOS开发中的绝大部分场景来说 ...
- iOS基于B站的IJKPlayer框架的流媒体探究
阅读数:6555 学习交流及技术讨论可新浪微博关注:极客James 一.流媒体 流媒体技术从传输形式上可以分为:渐进式下载和实施流媒体. 1.渐进式下载 它是介于实时播放和本地播放之间的一种播放方式, ...
- iOS 基于 MVC 的项目重构总结
关于MVC的争论 关于MVC的争论已经有非常多,对此我的观点是:对于iOS开发中的绝大部分场景来说,MVC本身是没有问题的,你觉得的MVC的问题,一定是你自己理解的问题(资深架构师请自己主动忽略本文) ...
- iOS开发--AVFoundation自定义相机
首先导入一个头文件 #import <AVFoundation/AVFoundation.h> 由于后面我们需要将拍摄好的照片写入系统相册中,所以我们在这里还需要导入一个相册需要的头文件 ...
随机推荐
- Java处理Excel中的日期格式
Java处理Excel中的日期格式 2011-12-23 17:34:03| 分类: java |举报 |字号 订阅 下载LOFTER 我的照片书 | 在Excel中的日期格式,其数值为距离1 ...
- Amazon SageMaker和NVIDIA NGC加速AI和ML工作流
Amazon SageMaker和NVIDIA NGC加速AI和ML工作流 从自动驾驶汽车到药物发现,人工智能正成为主流,并迅速渗透到每个行业.但是,开发和部署AI应用程序是一项具有挑战性的工作.该过 ...
- java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- 在spring配置文件中引入外部properties配置文件 context:property-placeholder
在spring的配置文件中,有时我们需要注入很多属性值,这些属性全都写在spring的配置文件中的话,后期管理起来会非常麻烦.所以我们可以把某一类的属性抽取到一个外部配置文件中,使用时通用spring ...
- Python 5种方法实现单例模式
基本介绍 一个对象只允许被一次创建,一个类只能创建一个对象,并且提供一个全局访问点. 单例模式应该是应用最广泛,实现最简单的一种创建型模式. 特点:全局唯一,允许更改 优缺点 优点: 避免对资源的多重 ...
- 重新整理 .net core 实践篇—————异常中间件[二十]
前言 简单介绍一下异常中间件的使用. 正文 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } 这样写入中间件哈,那么在env环 ...
- 实验1、初入Flask
实验介绍 1. 实验内容 Flask是一个用Python编写的Web应用程序框架.Armin Ronacher带领一个名为Pocco的国际Python爱好者团队开发了Flask.Flask基于Werk ...
- 【NX二次开发】Block UI 图层
属性说明 常规 类型 描述 BlockID String 控件ID Enable Logical 是否可操作 Group Logical ...
- 【NX二次开发】缝合片体例子UF_MODL_create_sew
缝合片体,没有成功缝合的片体涂绿色. 效果: 源码: extern DllExport void ufusr(char *param, int *returnCode, int rlen) { UF ...
- windows 7系统安装与配置Tomcat服务器环境
windows 7系统安装与配置Tomcat服务器环境 学习了一个月的java基础,终于要迈向java web领域.学习java web开发就离不开服务器的支持,由于本人是菜鸟,只好求助度娘谷哥.在此 ...