ios电子书语音阅读

news/2024/11/28 5:31:58/

非常感谢大家利用自己宝贵的时间来阅读我的文章 ,  上一篇文章写了Epub的加密一个实现方式,《ios Epub加密及解密阅读的一种实现方式》,今天这篇文章主要说一下电子书的语音阅读,这个功能也基本上是阅读器的标配了。希望这篇文章能给你的开发过程带来一些帮助。喜欢的可以关注一下我的简书我的博客   

先看下效果图,声音没法展示,下载ZQReaderDemo运行看效果吧



关于电子书阅读这这块就不说了,还是在XDSReader的基础上修改,添加了语音阅读的功能

在网上查了些资料,IOS7.0之后系统添加了文字转语音的API,AVFoundation框架下的AVSpeechSynthesizer,具体使用代码如下,也可参考ZQReaderDemo中的ZQAVSpeechTool

//初始化语音合成器_avSpeaker = [[AVSpeechSynthesizer alloc] init];_avSpeaker.delegate = self;//初始化要说出的内容AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:_paragraphs[_currentParagraphs]];//设置语速,语速介于AVSpeechUtteranceMaximumSpeechRate和AVSpeechUtteranceMinimumSpeechRate之间//AVSpeechUtteranceMaximumSpeechRate//AVSpeechUtteranceMinimumSpeechRate//AVSpeechUtteranceDefaultSpeechRateutterance.rate = _rate;//设置音高,[0.5 - 2] 默认 = 1//AVSpeechUtteranceMaximumSpeechRate//AVSpeechUtteranceMinimumSpeechRate//AVSpeechUtteranceDefaultSpeechRateutterance.pitchMultiplier = 1;//设置音量,[0-1] 默认 = 1utterance.volume = 1;//读一段前的停顿时间utterance.preUtteranceDelay = 0.5;//读完一段后的停顿时间utterance.postUtteranceDelay = 0;//设置声音,是AVSpeechSynthesisVoice对象//AVSpeechSynthesisVoice定义了一系列的声音, 主要是不同的语言和地区.//voiceWithLanguage: 根据制定的语言, 获得一个声音.//speechVoices: 获得当前设备支持的声音//currentLanguageCode: 获得当前声音的语言字符串, 比如”ZH-cn”//language: 获得当前的语言//通过特定的语言获得声音AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];//通过voicce标示获得声音//AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithIdentifier:AVSpeechSynthesisVoiceIdentifierAlex];utterance.voice = voice;//开始朗读[_avSpeaker speakUtterance:utterance];

既然语音转文字实现方法找到了,那么剩下的都是逻辑上的问题了,最后整理了一下实现思路,用户在阅读菜单上点击语音按钮,开始语音阅读当前页内容,首先取出当前页的所有文本,当前页读完跳转下一页继续阅读,后考虑到高亮问题,又把每一页的文本拆分成段落进行阅读,当读完一段开始读下一段,当前页读完就继续读下一页,当前章读完就读下一章,整体思路想好了就开整。

1、创建了一个单例工具类ZQAVSpeechTool,代码如下

.h

#import <Foundation/Foundation.h>@interface ZQAVSpeechTool : NSObject+(instancetype)shareSpeechTool;//开始朗读
- (void)speechTextWith:(NSString *)text;
//暂停朗读
- (void)pauseSpeech;
//继续朗读
- (void)continueSpeech;
//结束朗读
- (void)StopSpeech;
//切换语速
- (void)changeRate:(CGFloat)rate;@end

.m

#import "ZQAVSpeechTool.h"
#import <AVFoundation/AVFoundation.h>@interface ZQAVSpeechTool ()<AVSpeechSynthesizerDelegate>@property (nonatomic ,strong)AVSpeechSynthesizer *avSpeaker;@property (nonatomic ,strong)NSArray *paragraphs;@property (nonatomic ,assign)NSInteger currentParagraphs;@property (nonatomic ,assign)CGFloat rate;@end@implementation ZQAVSpeechTool// 单例
+(instancetype)shareSpeechTool {static ZQAVSpeechTool *instance;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[ZQAVSpeechTool alloc]init];});return instance;
}- (void)speechTextWith:(NSString *)text
{if (!(text.length>0)) {return;}if (_avSpeaker) {//把每一页文字拆分成段_paragraphs =[text componentsSeparatedByString:@"\n"];_currentParagraphs = 0;[self speechParagraphWith:_paragraphs[_currentParagraphs]];}else{//初次阅读NSUserDefaults *useDef = [NSUserDefaults standardUserDefaults];_rate = [useDef floatForKey:@"speechRate"];if (!_rate) {_rate = 0.5;}_paragraphs =[text componentsSeparatedByString:@"\n"];_currentParagraphs = 0;[[NSNotificationCenter defaultCenter] postNotificationName:@"speechParagraph" object:_paragraphs[_currentParagraphs]];//初始化语音合成器_avSpeaker = [[AVSpeechSynthesizer alloc] init];_avSpeaker.delegate = self;//初始化要说出的内容AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:_paragraphs[_currentParagraphs]];//设置语速,语速介于AVSpeechUtteranceMaximumSpeechRate和AVSpeechUtteranceMinimumSpeechRate之间//AVSpeechUtteranceMaximumSpeechRate//AVSpeechUtteranceMinimumSpeechRate//AVSpeechUtteranceDefaultSpeechRateutterance.rate = _rate;//设置音高,[0.5 - 2] 默认 = 1//AVSpeechUtteranceMaximumSpeechRate//AVSpeechUtteranceMinimumSpeechRate//AVSpeechUtteranceDefaultSpeechRateutterance.pitchMultiplier = 1;//设置音量,[0-1] 默认 = 1utterance.volume = 1;//读一段前的停顿时间utterance.preUtteranceDelay = 0.5;//读完一段后的停顿时间utterance.postUtteranceDelay = 0;//设置声音,是AVSpeechSynthesisVoice对象//AVSpeechSynthesisVoice定义了一系列的声音, 主要是不同的语言和地区.//voiceWithLanguage: 根据制定的语言, 获得一个声音.//speechVoices: 获得当前设备支持的声音//currentLanguageCode: 获得当前声音的语言字符串, 比如”ZH-cn”//language: 获得当前的语言//通过特定的语言获得声音AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];//通过voicce标示获得声音//AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithIdentifier:AVSpeechSynthesisVoiceIdentifierAlex];utterance.voice = voice;//开始朗读[_avSpeaker speakUtterance:utterance];}}- (void)speechParagraphWith:(NSString *)Paragraph
{[[NSNotificationCenter defaultCenter] postNotificationName:@"speechParagraph" object:Paragraph];AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:Paragraph];utterance.rate = _rate;[_avSpeaker speakUtterance:utterance];
}
//切换语速
- (void)changeRate:(CGFloat)rate
{_rate = rate;//[_avSpeaker stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];    //初始化语音合成器
//    _avSpeaker = [[AVSpeechSynthesizer alloc] init];
//    _avSpeaker.delegate = self;AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:_paragraphs[_currentParagraphs]];utterance.rate = rate;utterance.pitchMultiplier = 1;utterance.volume = 1;utterance.preUtteranceDelay = 0.5;utterance.postUtteranceDelay = 0;[_avSpeaker speakUtterance:utterance];NSUserDefaults *useDef = [NSUserDefaults standardUserDefaults];[useDef setFloat:rate forKey:@"speechRate"];[useDef synchronize];}- (void)pauseSpeech
{//暂停朗读//AVSpeechBoundaryImmediate 立即停止//AVSpeechBoundaryWord    当前词结束后停止[_avSpeaker pauseSpeakingAtBoundary:AVSpeechBoundaryImmediate];
}- (void)continueSpeech
{[_avSpeaker continueSpeaking];}- (void)StopSpeech
{//AVSpeechBoundaryImmediate 立即停止//AVSpeechBoundaryWord    当前词结束后停止[_avSpeaker stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];_avSpeaker = nil;[XDSReadManager sharedManager].speeching = NO;[[NSNotificationCenter defaultCenter] postNotificationName:@"speechDidStop" object:nil];}#pragma mark -
#pragma mark - AVSpeechSynthesizerDelegate
//已经开始
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance{}
//已经说完
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{_currentParagraphs+=1;if (_currentParagraphs<_paragraphs.count) {//读下一段[self speechParagraphWith:_paragraphs[_currentParagraphs]];}else{NSInteger currentPage = CURRENT_RECORD.currentPage;NSInteger currentChapter = CURRENT_RECORD.currentChapter;if (currentPage < CURRENT_RECORD.totalPage - 1) {//下一页currentPage += 1;}else{if (currentChapter < CURRENT_RECORD.totalChapters - 1) {//下一章currentChapter += 1;currentPage = 0;}else{//全书读完[self StopSpeech];return;}}[[XDSReadManager sharedManager] readViewJumpToChapter:currentChapter page:currentPage];NSString *content = CURRENT_RECORD.chapterModel.pageStrings[currentPage];[self speechTextWith:content];}}//已经暂停
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance{}
//已经继续说话
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance{}
//已经取消说话
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance{}
//将要说某段话
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance{//    DebugLog(@"%@",utterance.speechString);}@end

2、为XDSReadManager添加开始语音阅读的方法,并添加一个用于判断当前阅读状态的属性

- (void)begainSpeech;@property (nonatomic ,assign)BOOL speeching;

方法的实现

//开始语音阅读
- (void)begainSpeech
{//取出当前页文字内容XDSChapterModel *currentChapterModel = _bookModel.record.chapterModel;NSInteger currentPage = _bookModel.record.currentPage;NSString *content = currentChapterModel.pageStrings[currentPage];//开始朗读本页文字[[ZQAVSpeechTool shareSpeechTool] speechTextWith:content];self.speeching = YES;}

3、在弹出菜单时判断是否正在朗读,是则弹出语音阅读菜单ZQSpeechMenuView,因为AVSpeechSynthesizer只有女声,所以菜单只是加了调节语速和暂停/播放、退出的功能,没有添加切换男女声的功能

主要功能实现

//暂停/播放
- (void)pauseBtnClick:(UIButton *)sender
{if (_pauseBtn.selected) {[[ZQAVSpeechTool shareSpeechTool] continueSpeech];}else{[[ZQAVSpeechTool shareSpeechTool] pauseSpeech];}_pauseBtn.selected = !_pauseBtn.selected;
}//退出
- (void)stopBtnClick
{_pauseBtn.selected = NO;[[ZQAVSpeechTool shareSpeechTool] StopSpeech];[self removeFromSuperview];
}//切换语速
- (void)sliderValueChanged:(UISlider *)slider{[[ZQAVSpeechTool shareSpeechTool] changeRate:slider.value];_pauseBtn.selected = NO;
}

4、高亮正在阅读段落

- (void)highlightTextWith:(NSString *)text{//移除上一段背景色if (_currentRange.length>0) {[_readAttributedContent removeAttribute:NSBackgroundColorAttributeName range:_currentRange];}//设置当前朗读段落背景色NSRange range = [_content rangeOfString:text];_currentRange = range;[_readAttributedContent addAttribute:NSBackgroundColorAttributeName value:RGB(150, 220, 240) range:range];self.readAttributedContent = _readAttributedContent;[self reloadView];
}

大工搞成,具体的实现逻辑及代码见ZQReaderDemo,语音菜单界面约束使用的SDAutoLayout,可以根据自己习惯进行更改。





 


http://www.ppmy.cn/news/559777.html

相关文章

光影魔术手快速批量压缩图片

现在的数码设备很多&#xff0c;DC&#xff0c;DV等等&#xff0c;尤其是数码相机更是应用广泛&#xff0c;但是在数码相机带给你清晰的照片的同时&#xff0c;庞大的照片会占掉你PC很大的空间&#xff0c;倘若有些照片你并不想后期进行处理&#xff0c;但又想保留作为纪念&…

【光影魔术手】简单使用

OutLine 这个软件是大一时见舍友在用(迅雷旗下的一款产品&#xff0c;貌似已经4年没更新了&#xff0c;但不影响使用)&#xff0c;同比Photoshop(PS)&#xff0c;操作简单&#xff0c;占用内存小&#xff0c;适合作图难度小&#xff0c;需求不大的小伙伴。 抠图、滤镜、剪裁、旋…

用光影魔术手制作一寸照片(8张一寸)

一、常见证件照对应尺寸   1英寸25mm35mm 2英寸35mm49mm 3英寸35mm52mm 港澳通行证33mm48mm 赴美签证50mm50mm 日本签证45mm45mm 大二寸35mm45mm 护照33mm48mm 毕业生照33mm48mm ***22mm32mm 驾照21mm26mm 车照60mm91mm 第二代居民***照片标准要求 1、居民***制证用数字照片样…

如何让文字变成语音?推荐三个免费把文字变成音频软件

日常生活中&#xff0c;我们不论是在办公还是在学习都经常会与文字打交道&#xff0c;有时候需要把文字变为音频来使用&#xff0c;但是自己去录制的话&#xff0c;不仅麻烦还容易出错&#xff0c;其实我们可以借助工具来完成文字变语音的操作。那么今天就让我来教教大家如何让…

光影魔术手-批量-修改图片大小-小于1000k

光影魔术手(V4.4.1)批量修改图片大小小于1000k 注意点&#xff1a; 光影魔术手版本&#xff1a;4.4.1. 其他版本不保证操作正确。操作系统&#xff1a;win7-64位最后在选择“是否覆盖原文件”时&#xff0c;做好备份&#xff0c;小心误操作带来不必要的麻烦 步骤如下1.找到批…

➤mobi➢azw3➢epub⇨电子书阅读器 转换器

文章目录 ➤mobi➢azw3➢epub⇨电子书阅读器 & 转换器➤mobi➢azw3➢epub 格式的区别➤阅读器&#xff5c;介绍 & 推荐➣Kindle for PC →mobi➣Kindle Previewer 3 →azw3➣Calibre →convert ➤mobi➢azw3➢epub⇨电子书阅读器 & 转换器 ➤mobi➢azw3➢epub 格式…

AutoJs学习-变声器模板

往期文章分享 点击跳转>《导航贴》- Unity手册&#xff0c;系统实战学习点击跳转>《导航贴》- Android手册&#xff0c;重温移动开发 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断反思前进的过程。在这个过…

证件照处理神器-光影魔术手

推荐一个图片处理软件、光影魔术手 这个软件是我之前用过算是比较容易上手的照片处理软件&#xff0c;功能强大。之前换电脑找不到了。突然查到了。 1、证件照 换底色 现在证件照都是自己拿手机站在一个白墙后面拍一张&#xff0c;然后用该软件生成一寸照&#xff0c;然后换照片…