[英]JS: play multiple audio sources simultaneously when loaded
我有一个带有三个音频源的 web 项目(仅限普通 HTML/CSS/JS)。 这个想法是让所有三个同时播放,但我注意到在移动设备上播放的文件不同步(即一个源会开始,然后几毫秒后第二个会开始,然后是第三个)。 我相信它们正在播放是因为单个文件在加载后就开始播放,所以我想请求在所有文件加载后同时在所有三个文件上调用 play() 方法,
使用 vanilla JS 实现这一目标的最佳方法是什么?
示例: https://jacksorjacksor.xyz/soundblocks/
回购: https://github.com/jacksorjacksor/jacksorjacksor/tree/master/soundblocks
蒂亚!
富有的
MediaElements 用于正常播放媒体,并没有优化到足够低的延迟。 最好是使用Web 音频 API和AudioBuffers 。
您将首先获取 memory 中每个文件的数据,然后从中解码音频数据,一旦所有音频数据都被解码,您就可以安排在同一时刻播放所有文件:
(async() => { const urls = [ "layer1_big.mp3", "layer2_big.mp3", "layer3_big.mp3" ].map( (url) => "https://cdn.jsdelivr.net/gh/jacksorjacksor/jacksorjacksor/soundblocks/audio/" + url ); // first, fetch each file's data const data_buffers = await Promise.all( urls.map( (url) => fetch( url ).then( (res) => res.arrayBuffer() ) ) ); // get our AudioContext const context = new (window.AudioContext || window.webkitAudioContext)(); // decode the data const audio_buffers = await Promise.all( data_buffers.map( (buf) => context.decodeAudioData( buf ) ) ); // to enable the AudioContext we need to handle a user gesture const btn = document.querySelector( "button" ); btn.onclick = (evt) => { const current_time = context.currentTime; audio_buffers.forEach( (buf) => { // a buffer source is a really small object // don't be afraid of creating and throwing it const source = context.createBufferSource(); // we only connect the decoded data, it's not copied source.buffer = buf; // in order to make some noise source.connect( context.destination ); // make it loop? //source.loop = true; // start them all 0.5s after we began, so we're sure they're in sync source.start( current_time + 0.5 ); } ); }; btn.disabled = false; })();
<button disabled>play</button>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.