本文为做者行舟客投稿,原文地址为https://yunxiaomeng.blog.csdn.net/article/details/108672415前端
欢迎点赞!web
不说废话,实现过程当中却是遇到了一点小问题:canvas
原本嘛觉得是很简单的:就像通常给网页添加背景音乐,先动态建立一个audio元素,让其隐藏起来,而后用js添加一个event事件,并触发(事实上如今广泛认为的是:不能给网页添加背景音乐。但通过猜测和实践发现,也可经过下文第一种解决方式实现):后端
let event = new MouseEvent("click"); // 建立一个单击事件
//给触发元素添加属性或者回调事件
//好比:a.download = xxx / div.onclick=function(){}
触发元素.dispatchEvent(event); // 触发单击事件
可是当笔者用Google浏览器打卡后发现:浏览器禁止audio/video自动播放了:autoplay被禁用了! 除非用户主动打开设置api
好吧听着就有点匪夷所思,通过笔者屡次测试得出——跨域
因此咱们能够换句话说:mp3等音频格式的autoplay被Google禁用了!promise
没有办法,我只能将目光移向“元素click事件”,后来想来是我多想了——由于上面第四点的缘故,任何非用户手动操做的“动做”都会被浏览器禁止。浏览器
Google浏览器为其取了一个颇有意义的名字 —— 自动播放阻止。微信
可是我仍是发现了文档中的一个“新”成员:web Audio API。虽然文档中没有描述什么相关原理,可是经过这段描述:这让我忽然的就想到了HTML5的另外一个“大杀器”:canvas。他也是经过一个上下文对象context凌驾于浏览器图像/视频流之上。app
★web audio api怎么说呢,感受至少目前对大多数人用处真不大——文档中&被广大开发者发掘的各类骚操做canvas能作的都用canvas了,canvas不能作的对绝大多数开发者来讲也不重要。
”
顺着这个思路,我想到了“建立一个音轨上下文,在其中用 createBufferSource()
方法用于建立一个新的AudioBufferSourceNode接口—— 该接口能够经过AudioBuffer对象 来播放音频数据,以突破浏览器限制”,AudioBuffer对象怎么获取?web audio API为了解决音频源的问题,提出了“向音频url发送一个请求,将数据以arraybuffer返回,再解码获得元数据”这样看似复杂的方法,具体过程是这样的:
方法使用XHR加载一个音轨,设置请求的responsetype为ArrayBuffer使它返回一个arraybuffer数据,而后存储在audioData变量中。而后咱们将这个arraybuffer数据置于decodeAudioData()方法中使用,当成功解码PCM Data后经过promise回调返回, 将返回的结果经过AudioContext.createBufferSource()接口进行处理并得到一个AudioBufferSourceNode,,将源链接至AudioContext.destination造成一个完整的音频流。
var context = new (window.AudioContext || window.webkitAudioContext)();
var soundBuffer = null;
function loadSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response).then((buffer)=>{
soundBuffer = buffer;
playSound(soundBuffer);
});
};
request.send();
}
function playSound(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source[source.start?"start":"noteOn"](0);
}
//你也能够将init放在某个按钮触发事件上
window.addEventListener('DOMContentLoaded', init, false);
function init() {
try {
var url = "audio/1.mp3";
loadSound(url);
} catch (e) {
alert('你的浏览器不支持Web Audio API');
}
}
这里有两个注意点:
init()
函数增长txt参数,并调用百度转化接口,将文字先用encodeURI API转化为uri格式,再接入百度接口 var url = "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=" + encodeURI('这里是字符串文本');
转化为url连接这段代码很神奇:google不支持,可是控制台里面“万恶的报错”也没有了,会给你一个提示:总之就是我不给你播放。
因此,在除了Google的其他浏览器中,建议将上面的API和下面这段HTML代码一块儿写上:
<video controls autoplay style="display:none;"> /** 或者将controls和style都去掉 */
<source src="这里写要播放的音频路径,如:http://m10.music.126.net/20200926133756/cba79f37e90871df07cd582befe27723/ymusic/obj/w5zDlMODwrDDiGjCn8Ky/2920523350/fd2a/c111/aae2/5542b627692d3df8d63bbaeb1c73711a.mp3" type="audio/mp3"></source>
</video>
而后你应该就能够听到美妙动听的背景音了!
★Firefox和Edge虽然禁掉了autoplay,可是它也是支持AudioContext API的!Google中禁止了一切不符合规范的API,并且多是由于某些不知名缘由,上面这段HTML代码在Google中是时而能够时而不行的,就很迷惑。。。
”
补充其实这个API最大的做用是用于音频可视化领域——它有一个函数是这样的:createAnalyser()
用来建立一个音域可视化对象,能够将它链接到context流上:
var gainNode=context[context.createGain?"createGain":"createGainNode"]();
gainNode.connect(context.destination);
//操做完上一步后,咱们已经将音域加载到context流上,之后的操做就能够直接链接这个音域对象
var analyser=context.createAnalyser();
analyser.fftSize=512;
analyser.connect(gainNode);
发现浏览器中有了部分实现的相关API——它曾经一直在逃避浏览器音频播放政策:
function speak(sentence,pitch,volume) { //使用时调用这个函数便可
const utterance = new SpeechSynthesisUtterance(sentence);
//音调
utterance.pitch = pitch;
//音量
utterance.volume = volume;
window.speechSynthesis.speak(utterance)
}
参数 sentence 是一个字符串格式文本。
只要调用了这个函数并传入参数,你就能在浏览器中听到动听的、求之不得的声音了!(仍是个女声,嘿嘿嘿) 目前, Chrome70已经废弃这个API了。。。(由于它能够不通过用户主动触发而直接播放)
固然还有稳妥一些的作法,也是个让人比较眼前一亮的操做:是MDN文档中提到的 Feature-Policy
头——HTTP头信息,可设置自动播放相关:这个属性是给后端用的:在response中设置header!
最后
欢迎加我微信(winty230),拉你进技术群,长期交流学习...
欢迎关注「前端Q」,认真学前端,作个专业的技术人...