這篇文章主要解決在實(shí)現(xiàn)語音播報(bào)的基礎(chǔ)上出現(xiàn)的三個(gè)問題.
1.手機(jī)靜音狀態(tài)下不能播報(bào)(全部使用的系統(tǒng)方法,沒有使用其他第三方);
2.電話接入時(shí)暫停,掛斷后繼續(xù)播報(bào)(幾率很小,但是還要處理);
3.手機(jī)正在播放音樂,收到離線推送,播報(bào)推送內(nèi)容,完畢后繼續(xù)播放音樂;
4.如果手機(jī)音量過小,調(diào)節(jié)音量
處理以上4個(gè)問題廢了很大功夫,雖然代碼很少.
demo已上傳到github←戳
再此之前已經(jīng)做好離線播報(bào)的功能,只是還沒有完善,會(huì)有上述幾個(gè)問題.
使用的是NotificationService模塊,然后在獲取推送后,文字轉(zhuǎn)語音進(jìn)行語音播報(bào).(實(shí)現(xiàn)離線播報(bào)的過程)
1.解決方案,設(shè)置語音播報(bào)的模式,查看AVAudioSession文檔
[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
[[AVAudioSession sharedInstance]setActive:YES error:nil];
2.解決方案,注冊通知來監(jiān)聽AVAudioSessionInterruptionTypeKey類型
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
- (void)handleInterruption:(NSNotification *)notificaiton{
NSLog(@"%@",notificaiton.userInfo);
AVAudioSessionInterruptionType type = [notificaiton.userInfo[AVAudioSessionInterruptionTypeKey] intValue];
if (type == AVAudioSessionInterruptionTypeBegan) {//1是被系統(tǒng)占用 有電話進(jìn)入
//暫停播報(bào),并保存進(jìn)度
[_synth pauseSpeakingAtBoundary:AVSpeechBoundaryImmediate];
} else {
//恢復(fù)播報(bào)
[_synth continueSpeaking];
}
}
3.解決方案,使用AVSpeechSynthesizer代理來監(jiān)聽當(dāng)前播報(bào)是否完成
//播報(bào)結(jié)束后 關(guān)閉播報(bào)線程 繼續(xù)播放音樂
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance*)utterance{
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}
4.解決方案,使用MPVolumeView用來控制播報(bào)時(shí)的音量
_volumeView = [[MPVolumeView alloc]init];
_volumeView.showsRouteButton = NO;
//默認(rèn)YES僵刮,這里為了突出笼才,故意設(shè)置一遍
_volumeView.showsVolumeSlider = YES;
[_volumeView sizeToFit];
[_volumeView setFrame:CGRectMake(-100, -100, 10, 10)];
[_volumeView userActivity];
for (UIView *view in [_volumeView subviews]){
if ([[view.class description] isEqualToString:@"MPVolumeSlider"]){
_volumeSlider = (UISlider*)view;
break;
}
}
//輸出當(dāng)前音量 保存 改變后再改回之前音量
_volValue = [[AVAudioSession sharedInstance] outputVolume];
//設(shè)置默認(rèn)打開視頻時(shí)聲音為0.3旁蔼,如果不設(shè)置的話,獲取的當(dāng)前聲音始終是0
[_volumeSlider setValue:1];
//獲取最是剛打開時(shí)的音量值
_volumeValue = _volumeSlider.value;
//設(shè)置展示音量條的值
_showVolueSlider.value = _volumeValue;
播報(bào)完成后,恢復(fù)之前音量
//播報(bào)結(jié)束后 關(guān)閉播報(bào)線程 繼續(xù)播放音樂
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance*)utterance{
[[AVAudioSession sharedInstance] setActive:NO error:nil];
[_volumeSlider setValue:_volValue];//恢復(fù)之前音量
}
以上就是解決四個(gè)問題的方案.如果有其他bug,會(huì)持續(xù)補(bǔ)充,實(shí)現(xiàn)離線播報(bào)也會(huì)找時(shí)間整理一下.
不想下載demo的,下面是整段代碼 本人QQ 1165889915
@interface ViewController ()<AVAudioSessionDelegate,AVSpeechSynthesizerDelegate>
@property (nonatomic, strong)AVSpeechSynthesizer *synth;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn =[UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:btn];
btn.frame =CGRectMake(100, 200, 70, 40);
[btn setTitle:@"測試" forState:UIControlStateNormal];
btn.backgroundColor =[UIColor orangeColor];
[btn addTarget:self action:sel_registerName("btnClick") forControlEvents:UIControlEventTouchUpInside];
}
- (void)btnClick{
//設(shè)置語音播報(bào)的模式 主要處理靜音模式
[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
[[AVAudioSession sharedInstance]setActive:YES error:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
NSString *str =[NSString stringWithFormat:@"知君仙骨無寒暑探孝。千載相逢猶旦暮"];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:str];
AVSpeechSynthesisVoice*voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];//設(shè)置發(fā)音荣挨,這是中文普通話
utterance.voice = voice;
_synth = [[AVSpeechSynthesizer alloc] init];
_synth.delegate =self;
[_synth speakUtterance:utterance];
}
- (void)handleInterruption:(NSNotification *)notificaiton{
NSLog(@"%@",notificaiton.userInfo);
AVAudioSessionInterruptionType type = [notificaiton.userInfo[AVAudioSessionInterruptionTypeKey] intValue];
if (type == AVAudioSessionInterruptionTypeBegan) {//1是被系統(tǒng)占用 有電話進(jìn)入
//暫停播報(bào),并保存進(jìn)度
[_synth pauseSpeakingAtBoundary:AVSpeechBoundaryImmediate];
} else {
//恢復(fù)播報(bào)
[_synth continueSpeaking];
}
}
//播報(bào)結(jié)束后 關(guān)閉播報(bào)線程 繼續(xù)播放音樂
- (void)speechSynthesizer:(AVSpeechSynthesizer*)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance*)utterance{
[[AVAudioSession sharedInstance] setActive:NO error:nil];
}