近期项目中有个需求,需要点击按钮播放文字答案,然后开始了填坑之旅
首先使用h5的audio标签,由于后台返回音频格式为base64格式,原格式为wav,开始不确定是否可以直接播放base64格式的音频,前端通过npm的base64ToBlob的方式解码,并赋值给audio的src,具体代码如下:
playVoice(text,e){
let audio = this.$refs.audio;
let reg = /<[^<>]+>/g;
if(text.answerMsg || text.promptVagueMsg){
text = text.answerMsg.replace(reg,'') + text.promptVagueMsg.replace(reg,'') + text.vagueList.toString();
}
document.querySelectorAll('.voiceBtn').forEach(item => {
item.className = 'voiceBtn play';
})
e.target.className = 'voiceBtn pause'
if(this.audioText !== text){
let params = {
text
};
params = pushDataFormat(params);
this.$axios.post('ncfNewTimeRobot/textToVoice.do',{
params: params
}).then(res => {
console.log(res.data)
this.audioText = text;
if(res.errCode == 0){
audio.load();
audio.play();
audio.addEventListener("canplay", () => {
console.log('canplay')
window.URL.revokeObjectURL(audio.src);
});
audio.addEventListener('ended', function () {
e.target.className = 'voiceBtn play'
}, false);
}
})
}else{
if(audio.paused){
audio.play();
e.target.className = 'voiceBtn pause'
}else{
audio.pause();
e.target.className = 'voiceBtn play'
}
}
}
以上代码测试中发现在android中能够播放,但是在IOS下无法播放,播放没有声音,继续查找解决方案
第二阶段一致怀疑是IOS不支持wav格式的播放,经过查资料,发现是支持的,然后各种查找解决方案,例如:判断如果是ios,需要先调用播放,在调用暂停,然后获取音频给src赋值,具体代码如下:
playVoice(text,e){
let audio = this.$refs.audio;
let reg = /<[^<>]+>/g;
audio.load();
audio.play();
audio.pause();
if(text.answerMsg || text.promptVagueMsg){
text = text.answerMsg.replace(reg,'') + text.promptVagueMsg.replace(reg,'') + text.vagueList.toString();
}
document.querySelectorAll('.voiceBtn').forEach(item => {
item.className = 'voiceBtn play';
})
e.target.className = 'voiceBtn pause'
if(this.audioText !== text){
let params = {
text
};
params = pushDataFormat(params);
this.$axios.post('ncfNewTimeRobot/textToVoice.do',{
params: params
}).then(res => {
console.log(res.data)
this.audioText = text;
if(res.errCode == 0){
let audioBlob = base64ToBlob(res.data.data, 'wav');
audio.src = window.URL.createObjectURL(audioBlob);
audio.load();
audio.play();
audio.addEventListener("canplay", () => {
console.log('canplay')
window.URL.revokeObjectURL(audio.src);
});
audio.addEventListener('ended', function () {
e.target.className = 'voiceBtn play'
}, false);
}
})
}else{
if(audio.paused){
audio.play();
e.target.className = 'voiceBtn pause'
}else{
audio.pause();
e.target.className = 'voiceBtn play'
}
}
}
后经测试并没有什么效果,最终怀疑是由于解码问题导致的损坏不能播放,然后直接通过直接播放base64格式的形式去尝试,具体代码如下:
playVoice(text,e){
let audio = this.$refs.audio;
let reg = /<[^<>]+>/g;
if(text.answerMsg || text.promptVagueMsg){
text = text.answerMsg.replace(reg,'') + text.promptVagueMsg.replace(reg,'') + text.vagueList.toString();
}
document.querySelectorAll('.voiceBtn').forEach(item => {
item.className = 'voiceBtn play';
})
e.target.className = 'voiceBtn pause'
if(this.audioText !== text){
let params = {
text
};
params = pushDataFormat(params);
this.$axios.post('ncfNewTimeRobot/textToVoice.do',{
params: params
}).then(res => {
console.log(res.data)
this.audioText = text;
if(res.errCode == 0){
audio.src = `data:audio/wav;base64,${res.data.data}`
audio.load();
audio.play();
audio.addEventListener("canplay", () => {
console.log('canplay')
window.URL.revokeObjectURL(audio.src);
});
audio.addEventListener('ended', function () {
e.target.className = 'voiceBtn play'
}, false);
}
})
}else{
if(audio.paused){
audio.play();
e.target.className = 'voiceBtn pause'
}else{
audio.pause();
e.target.className = 'voiceBtn play'
}
}
}
至此,经过测试发现问题完美解决。 ps:采用第二种方法测试中发现没有声音,但是使用耳机可以进行播放,感觉很疑惑,后来发现是由于测试使用的ios手机开启了静音模式
|