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> 由于后面我们需要将拍摄好的照片写入系统相册中,所以我们在这里还需要导入一个相册需要的头文件 ...
随机推荐
- jackjson学习2+CVE-2019-14379漏洞分析
最近想着分析jackson,jackson和fastjson有点相似,浅蓝大神的文章很好,个人受益匪浅 昨天简单说了下jackson的用法,现在继续拓扑,补充前置知识,前置知识补充的足够多,那么漏洞分 ...
- JavaSE-QuickStart
老话常说:基础不牢地动山摇,于是我在b站上看杨中科老师的课程脑补一下,便记录这岁月的点滴 1.什么是编程 ? 编程:编写能够控制计算机来执行特定任务的代码. 2.什么是编程语言 ? 编程语言:是指程序 ...
- GO学习-(14) Go语言基础之接口
Go语言基础之接口 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节. 接口 接口类型 在Go语言中接口(interface)是一种类型,一种抽象的类 ...
- 用OpenCV进行摄像机标定
用OpenCV进行摄像机标定 照相机已经存在很长时间了.然而,随着廉价针孔相机在20世纪末的引入,日常生活中变得司空见惯.不幸的是,这种廉价伴随着它的代价:显著的扭曲.幸运的是,这些常数,通过校准和一 ...
- cuDNN 功能模块解析
Abstract 本cuDNN 8.0.4开发人员指南概述了cuDNN功能,如可自定义的数据布局.支持灵活的dimension ordering,striding,4D张量的子区域,这些张量用作其所有 ...
- pytest的allure的环境配置
一.下载地址: https://github.com/allure-framework/allure2/releases 二.配置环境变量: 三.验证allure安装成功
- [Linux]经典面试题 - 网络基础 - TCP三次握手
[Linux]经典面试题 - 网络基础 - TCP三次握手 目录 [Linux]经典面试题 - 网络基础 - TCP三次握手 一.TCP报文格式 1.1 TCP报头 1.2 报文图例 二.TCP三次握 ...
- HR面试:过五关斩六将后,小心阴沟翻船!(史上最全、避坑宝典)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 4.3CNN卷积神经网络最详细最容易理解--tensorflow源码MLP对比
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1 CNN卷积神经网络 ...
- 撸了几天的sofa-tracer之后,我悟了!
什么是分布式链路跟踪 简而言之,在分布式系统下,用于跟踪链路而衍生出的一项技术. 应用场景如下: 应用A,B,C,D,E 以一个层级关系依赖, 当用户向 应用A 发起请求,但是返回了个异常,为了排查这 ...