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> 由于后面我们需要将拍摄好的照片写入系统相册中,所以我们在这里还需要导入一个相册需要的头文件 ...
随机推荐
- 圆盘时钟效果 原生JS
圆盘时钟 旋转时钟 数字时钟 写在前面 仿荣耀手机时钟,设计的同款时钟效果 实现效果 实现原理 数字时钟 利用Date内置对象获取当下的时间,通过处理呈现在页面上 这一步获取时间是非常简单的,通过Da ...
- Java读取SQL server数据库
要打开SQL server 的三个服务,然后再执行代码. package com.sql; import java.sql.SQLException; import java.sql.Statemen ...
- 自监督学习(Self-Supervised Learning)多篇论文解读(下)
自监督学习(Self-Supervised Learning)多篇论文解读(下) 之前的研究思路主要是设计各种各样的pretext任务,比如patch相对位置预测.旋转预测.灰度图片上色.视频帧排序等 ...
- 一、安装Tomcat服务器
[root@ web1 ~]# yum -y install java-1.8.0-openjdk #安装jdk [root@web1 ~]# yum -y install java-1.8.0- ...
- (5)使用自定Web根目录
调整 Web 站点 http://server0.example.com 的网页目录,要求如下: 1) 新建目录 /webroot,作为此站点新的网页文件根目录 # mkdir /webroot # ...
- 【NX二次开发】Block UI 字符串
属性说明: BlockID String 控件ID Enable Logical 是否可操作 Group Logical 是否分组 Label ...
- 【转】【NX二次开发】UFUN进度中断,单击停止可中断此操作
队长的博客: https://www.cnblogs.com/nxopen2018/p/13174207.html 显示此对话框,点击可中断操作: 用到的ufun函数: UF_ABORT_ask_fl ...
- Java后端精选技术:SpringBoot配置读取
在早前的博客中曾经写过 Spring 程序通过 Bean 映射实现配置信息的读取. 在SpringBoot 框架中读取配置的方式变得非常多样,这导致读者在搜寻资料时反而容易迷糊. 到底,SpringB ...
- WEB安全新玩法 [1] 业务安全动态加固平台
近年来,信息安全体系建设趋于完善,以注入攻击.跨站攻击等为代表的传统 Web 应用层攻击很大程度上得到了缓解.但是,Web 应用的业务功能日益丰富.在线交易活动愈加频繁,新的安全问题也随之呈现:基于 ...
- 飞(fly)(数学推导,liu_runda的神题)
大概看了两三个小时的题解,思考量很大,实现简单........ 20分: 明显看出,每个点的贡献是x*(x-1)/2;即组合数C(x,2),从x个线段中选出2个的方案数,显然每次相交贡献为1,n^2枚 ...