2023.01.04 - 关于Audio自动播放的方法以及文字转语音相关的知识记录
问题背景:
Chrome下音频无法自动播放的解决办法
Chrome浏览器无法自动播放音频视频的问题
利用Audio标签自动播放音频。
1、getUserMedia首次获取权限后,以后的操作就会自动播放
通过MediaDevices.getUserMedia(),获取到媒体权限,在浏览器中记录网站有媒体访问权限之后,会自动获取播放权限。
import evaluator_man from "@/assets/audio/evaluator_man.mp3";
function playVoice() {
// 创建音频
const audio = new Audio(evaluator_man);
audio.volume = 1;
// 自动播放音频失败走视频流
audio.play().catch(async e =>{
let mediaOpts = {
audio: false,
video: true,
};
// 获取用户媒体流(这里需要支持视频权限,因为我的业务中涉及视频流,所以这个权限获取是前置操作)
let stream = await navigator.mediaDevices.getUserMedia(mediaOpts);
audio.play();
// 播放完毕后,关闭视频流
stream.getVideoTracks().forEach((track) => {
track.stop();
});
});
}
缺点
- 通过录制操作将播放的声音通过录制方法播放,声音很小而且有损
- 媒体流的录制问题(该方法不是最优解)
2、通过页面的mousedown等可信任事件的监听取消静音
比较常规的做法是,为video标签设置muted属性,使它静音,这样视频就能自动播放了,但是没有声音。然后待用户在网页上有了任意触发后,再将muted去掉。或者让用户手动去打开音频(腾讯视频就是这样做的,包括b站和元神这样的网站也是这样实现的)。
这个方法适合大部分除首页以外的网页和非webscoket的跳转的页面。



做个简单的实现
3、通过iframe实现音视频文件实现自动播放
有位外国友人写的一篇文章中,提及到这种办法,我们把音频文件放入一个html文件,然后在我们需要使用的页面中用iframe引入此页面,这样可以实现自动播放,但是经过我的多番测试发现,当前引入的页面域名,不可以和iframe的src域名相等,不然的话会不太稳定,时而报错,时而正常。例如:
假如我们现在有a.html和b.html两个页面,现在我们在本地起了localhost:3000的服务
localhost:3000/a可以访问到a页面,localhost:3000/b可以访问到b页面
a页面:
<iframe allow="autoplay" src="http://localhost:3000/b.html"></iframe>
b页面:
<audio autoplay="autoplay" src="http://data.huiyi8.com/2017/gha/03/17/1702.mp3" controls="controls" preload id="auto"></audio>
那么此时,如果我们通过http://localhost:3000/a ,访问a页面则无法正常播放(时好时坏),但是a页面如果改为:
<iframe allow="autoplay" src="http://127.0.0.1:3000/b.html"></iframe>
JS写法:
const ifr = document.createElement('iframe');
ifr.setAttribute('src',"http://data.huiyi8.com/2017/gha/03/17/1702.mp3");
ifr.setAttribute('allow',"autoplay");
ifr.setAttribute('hidden',true);
document.body.appendChild(ifr);
这样的话,正常播放不会有问题。总结下来就是,父窗口(即a页面)使用域名访问,那么iframe引入b的话,就不可以使用同一个域名(使用ip或不同域名均可正常播放)。但是这样做非常麻烦。
4、iframe直接引入音频
我们可以通过如下这样引入音频:
<iframe allow="autoplay" hidden src="http://data.huiyi8.com/2017/gha/03/17/1702.mp3"></iframe>
这样iframe加载完毕就会自动播放音频,不过他的缺点也很明显,很多操作都没办法做。这样的引入视频,视频只能播放一次就结束。想要他多次播放,则需要手动重置iframe的src来实现。
总结:
4种方式总结下来,3和4两种通过iframe的方法都可以实现,但又各有优缺点,第三种虽然使用起来相对复杂一些,但是优势在于我们可以利用js对视频做相关操作。第四种引入方式简单,但是对于可操作性几乎没有操作性可言。不过对于我要实现的消息通知的需求来说,第四种是最佳的实现方案。前两种方案由于并不友好,就不过多说了。我们可以根据各自的使用场景来决定那种方案更合适。

浙公网安备 33010602011771号