TTS(Text To Speech 文本轉(zhuǎn)語音縮寫)
簡(jiǎn)介
涉及到AVFoundatio框架中的AVSpeechSynthesizer、AVSpeechUtterance、AVSpeechSynthesisVoice三個(gè)類,這三個(gè)類的聲明都在AVSpeechSynthesis.h里,這三個(gè)類比較簡(jiǎn)單。
需要用到的一些枚舉與宏
-
播放暫停時(shí)是立即停止播放語音還是播放完當(dāng)前詞再暫停。
typedef NS_ENUM(NSInteger, AVSpeechBoundary) { AVSpeechBoundaryImmediate, AVSpeechBoundaryWord }
-
語音質(zhì)量
typedef NS_ENUM(NSInteger, AVSpeechSynthesisVoiceQuality) { AVSpeechSynthesisVoiceQualityDefault = 1, AVSpeechSynthesisVoiceQualityEnhanced }
-
速率
AVF_EXPORT const float AVSpeechUtteranceMinimumSpeechRate NS_AVAILABLE_IOS(7_0); AVF_EXPORT const float AVSpeechUtteranceMaximumSpeechRate NS_AVAILABLE_IOS(7_0); AVF_EXPORT const float AVSpeechUtteranceDefaultSpeechRate NS_AVAILABLE_IOS(7_0);
-
注意:設(shè)置屬性字符串時(shí),AVSpeechSynthesisIPANotationAttribute的正確使用,最后會(huì)有Demo傳送門
AVF_EXPORT NSString *const AVSpeechSynthesisIPANotationAttribute;
AVSpeechUtterance
要開始說話,請(qǐng)指定AVSpeechSynthesisVoice和要說出的字符串,然后根據(jù)需要隨意更改速率,音高或音量。
四種初始化方法
+ (instancetype)speechUtteranceWithString:(NSString *)string;
+ (instancetype)speechUtteranceWithAttributedString:(NSAttributedString *)string API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0));
- (instancetype)initWithString:(NSString *)string;
- (instancetype)initWithAttributedString:(NSAttributedString *)string API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0));
通過以上創(chuàng)建出來的實(shí)例,其語音、語速、音調(diào)、音量都是默認(rèn)的,可以通過屬性進(jìn)行定制,但是在入隊(duì)后設(shè)置這些值將不起作用。其中rate的值應(yīng)該介于AVSpeechUtteranceMinimumSpeechRate和AVSpeechUtteranceMaximumSpeechRate之間
@property(nonatomic, retain, nullable) AVSpeechSynthesisVoice *voice;
@property(nonatomic) float rate;
@property(nonatomic) float pitchMultiplier; // [0.5 - 2] Default = 1
@property(nonatomic) float volume; // [0-1] Default = 1
@property(nonatomic) NSTimeInterval preUtteranceDelay; // Default is 0.0
@property(nonatomic) NSTimeInterval postUtteranceDelay; // Default is 0.0
有兩個(gè)屬性可以獲得當(dāng)前播放的字符串或?qū)傩宰址?/p>
@property(nonatomic, readonly) NSString *speechString;
@property(nonatomic, readonly) NSAttributedString *attributedSpeechString
AVSpeechSynthesisVoice
通過指定應(yīng)該在其中說出文本的語言代碼來檢索語音,或者通過使用voiceWithIdentifier來獲取已知語音標(biāo)識(shí)符。
現(xiàn)支持的語音語言37種,可以用類方法speechVoices獲取
+ (NSArray<AVSpeechSynthesisVoice *> *)speechVoices;
language | name | quality | identifier |
---|---|---|---|
ar-SA | Maged | Default | com.apple.ttsbundle.Maged-compact |
cs-CZ | Zuzana | 同上 | com.apple.ttsbundle.Zuzana-compact |
ar-SA | Maged | 同上 | com.apple.ttsbundle.Maged-compact |
cs-CZ | Zuzana | 同上 | com.apple.ttsbundle.Zuzana-compact |
da-DK | Sara | 同上 | com.apple.ttsbundle.Sara-compact |
de-DE | Anna | 同上 | com.apple.ttsbundle.Anna-compact |
el-GR | Melina | 同上 | com.apple.ttsbundle.Melina-compact |
en-AU | Karen | 同上 | com.apple.ttsbundle.Karen-compact |
en-GB | Daniel | 同上 | com.apple.ttsbundle.Daniel-compact |
en-IE | Moira | 同上 | com.apple.ttsbundle.Moira-compact |
en-US | Samantha | 同上 | com.apple.ttsbundle.Samantha-compact |
en-ZA | Tessa | 同上 | com.apple.ttsbundle.Tessa-compact |
es-ES | Monica | 同上 | com.apple.ttsbundle.Monica-compact |
es-MX | Paulina | 同上 | com.apple.ttsbundle.Paulina-compact |
fi-FI | Satu | 同上 | com.apple.ttsbundle.Satu-compact |
fr-CA | Amelie | 同上 | com.apple.ttsbundle.Amelie-compact |
fr-FR | Thomas | 同上 | com.apple.ttsbundle.Thomas-compact |
he-IL | Carmit | 同上 | com.apple.ttsbundle.Carmit-compact |
hi-IN | Lekha | 同上 | com.apple.ttsbundle.Lekha-compact |
hu-HU | Mariska | 同上 | com.apple.ttsbundle.Mariska-compact |
id-ID | Damayanti | 同上 | com.apple.ttsbundle.Damayanti-compact |
it-IT | Alice | 同上 | com.apple.ttsbundle.Alice-compact |
ja-JP | Kyoko | 同上 | com.apple.ttsbundle.Kyoko-compact |
ko-KR | Yuna | 同上 | com.apple.ttsbundle.Yuna-compact |
nl-BE | Ellen | 同上 | com.apple.ttsbundle.Ellen-compact |
nl-NL | Xander | 同上 | com.apple.ttsbundle.Xander-compact |
no-NO | Nora | 同上 | com.apple.ttsbundle.Nora-compact |
pl-PL | Zosia | 同上 | com.apple.ttsbundle.Zosia-compact |
pt-BR | Luciana | 同上 | com.apple.ttsbundle.Luciana-compact |
pt-PT | Joana | 同上 | com.apple.ttsbundle.Joana-compact |
ro-RO | Ioana | 同上 | com.apple.ttsbundle.Ioana-compact |
ru-RU | Milena | 同上 | com.apple.ttsbundle.Milena-compact |
sk-SK | Laura | 同上 | com.apple.ttsbundle.Laura-compact |
sv-SE | Alva | 同上 | com.apple.ttsbundle.Alva-compact |
th-TH | Kanya | 同上 | com.apple.ttsbundle.Kanya-compact |
tr-TR | Yelda | 同上 | com.apple.ttsbundle.Yelda-compact |
zh-CN | Ting-Ting | 同上 | com.apple.ttsbundle.Ting-Ting-compact |
zh-HK | Sin-Ji | 同上 | com.apple.ttsbundle.Sin-Ji-compact |
zh-TW | Mei-Jia | 同上 | com.apple.ttsbundle.Mei-Jia-compact |
獲取設(shè)備當(dāng)前語言語音碼
+ (NSString *)currentLanguageCode;
根據(jù)指定的語言語音碼獲取語音
+ (nullable AVSpeechSynthesisVoice *)voiceWithLanguage:(nullable NSString *)languageCode;
根據(jù)指定的語言語音標(biāo)識(shí)碼獲取語音 iOS9.0之后可用
+ (nullable AVSpeechSynthesisVoice *)voiceWithIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(9_0);
獲取某個(gè)語音的信息,只讀
@property(nonatomic, readonly) NSString *language;
@property(nonatomic, readonly) NSString *identifier NS_AVAILABLE_IOS(9_0);
@property(nonatomic, readonly) NSString *name NS_AVAILABLE_IOS(9_0);
@property(nonatomic, readonly) AVSpeechSynthesisVoiceQuality quality NS_AVAILABLE_IOS(9_0);
AVSpeechSynthesizer
合成器
是否正在播放、暫停
@property(nonatomic, readonly, getter=isSpeaking) BOOL speaking;
@property(nonatomic, readonly, getter=isPaused) BOOL paused;
將已加入或正在講話的相同AVSpeechUtterance加入會(huì)引發(fā)異常。
- (void)speakUtterance:(AVSpeechUtterance *)utterance;
以下方法只對(duì)正在講話的語音進(jìn)行操作才有效。 如果成功則返回YES,失敗則返回NO。
- (BOOL)stopSpeakingAtBoundary:(AVSpeechBoundary)boundary;
- (BOOL)pauseSpeakingAtBoundary:(AVSpeechBoundary)boundary;
- (BOOL)continueSpeaking;
指定要用于合成語音的音頻通道,如AVAudioSession當(dāng)前路徑中的通道描述所述。
語音音頻將復(fù)制到每個(gè)指定的頻道。默認(rèn)值為nil,表示系統(tǒng)默認(rèn)值。
@property(nonatomic, retain, nullable) NSArray<AVAudioSessionChannelDescription *> *outputChannels;
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property(nonatomic, strong) AVSpeechSynthesizer *speechSynthesizer;
@property(nonatomic, strong) AVSpeechUtterance *utterance;
@property(nonatomic, strong) UILabel *label;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
[self commonInit];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)commonInit {
UISwitch *senderSwitch = [[UISwitch alloc] init];
senderSwitch.on = YES;
senderSwitch.frame = CGRectMake(0, 0, 100, 20);
senderSwitch.center = self.view.center;
[senderSwitch addTarget:self action:@selector(updateUtterance:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:senderSwitch];
self.label = [[UILabel alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - 200)/2.0f, CGRectGetMaxY(senderSwitch.frame) - 80, 200, 20)];
self.label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.label];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake((self.view.bounds.size.width - 128)/2.0f, CGRectGetMaxY(senderSwitch.frame) + 20, 128, 128);
[btn setImage:[UIImage imageNamed:@"audio"] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[self updateUtterance:senderSwitch];
}
- (void)updateUtterance:(UISwitch *)sender {
sender.on = !sender.isOn;
if (sender.on) {
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:@"Tsutsumi"];
// 這里的國際音標(biāo)可以隨意修改 eg:"t?n.t?n.m?" "t?n.m?" ... 可以多試試其他的情況
[attString addAttribute:AVSpeechSynthesisIPANotationAttribute value:@"t?n.t?n.mi" range:NSMakeRange(0, attString.length)];
self.utterance = [AVSpeechUtterance speechUtteranceWithAttributedString:attString];
self.label.text = @"Tsutsumi(Attributed)";
} else {
self.utterance = [AVSpeechUtterance speechUtteranceWithString:@"Tsutsumi"];
self.label.text = @"Tsutsumi";
}
}
- (void)btnClick:(UIButton *)sender {
if (self.speechSynthesizer.isSpeaking) {
NSLog(@"正在朗讀中....");
return;
}
[self.speechSynthesizer speakUtterance:self.utterance];
}
@end
想看Demo的同學(xué)請(qǐng)移駕-->TTS