h5集成音频合成遇到IOS无法播放问题记录

问题

开发随身译h5,根据产品需求需要实现文本框的文本进行语音合成播报能力。实现完成后在测试阶段发现ios端无法播放音频,遂开始一系列的找虫之旅。

UTOOLS1568706033087.png

发生问题原因分析

1.ios限制自动播放

根据查阅资料,直接通过js直接调用audio.play()方法会被浏览器内核block,(估计是为了防止恶意网站恶意播放音频的问题吧,想想当年弹小窗的那个声音)。

ios想要在js里面直接调用audio.play()需要用户主动触发,比如通过 onmousedown、onmouseup、onclick 或 ontouchstart 触发事件。但是由于我们的h5是在ajax异步调用音频合成接口后生成blob临时文件进行调用播放,不是在事件内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
xhr.open('POST', url, true);//get请求,请求地址,是否异步
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.responseType = "blob"; // 返回类型blob
xhr.onload = function () {// 请求完成处理函数
console.log(this.status)
if (this.status === 200) {
var blob = this.response;// 获取返回值
var blobURL = window.URL.createObjectURL(blob);
_this.audio0.src=blobURL;
_this.audio0.load();
var playPromise = _this.audio0.play();
if (playPromise !== undefined) {
playPromise.then(_=> {
}).catch(error => {
console.error(error)
});
}
}
};
// 发送ajax请求
let params = {destEnt: destEnt, text: texg}
xhr.send(qs.stringify(params));

但是当我把调用方式调整为同步时,发现问题也无法解决,每当调用play函数会提示The operation is not supported.此时我怀疑是音频文件的问题

2.合成后的音频文件不支持

网上找到一段铃音文件,将其下载下来并通过前端click事件进行播放,发现可播放。替换为合成的音频文件发现无法播放,至此,确定的确是合成的音频文件在IOS下不支持播放。

解决方案

通过查看开发平台文档,调用合成接口时设置的音频编码为wav,可能做了什么特殊编码,导致ios端无法播放,将接口入参调整为lame,返回mp3类型的音频资源。替换完成后使用click时间点击播放出声音

问题总结

一直囿于ios内核权限控制里面,以为是脱离了点击触发事件导致音频无法播放,一直没有想到是音频文件本身的问题(因为安卓和pc均可播放)。当实在无法解决只有更换解决问题思路,通过追本溯源,从最简单的点击触发事件播放音频来一步步找实现过程中的漏洞,最终发现音频文件问题。

在后续的开发工作中,遇到难以解决的问题,没有思路的时候,可能是因为你走入了思维的误区,跳出泥潭,以整体流程为思考,重新整理解决问题的思路,不要害怕麻烦,从头开始一步步重新整理思路,并一个代码一个代码进行实操,找到问题的根源,方能最终解决问题。