我有一个Object
,里面有几个base64(音频)。 base64将开始播放keydown
事件。在某些情况下(Base64大小有点高),播放之前会发生延迟。有什么方法可以消除这种延迟,或者至少可以减少延迟?
在JavaScript中运行并在Electron上运行的应用
//audio base64s object
var audio = {A: new Audio('base64[1]'), B: new Audio('base64[2]'), C: new Audio('base64[3]')};
//audio will start plying with key down
function keydown(ev) {
if (audio[String.fromCharCode(ev.keyCode)].classList.contains('holding') == false) {
audio[String.fromCharCode(ev.keyCode)].classList.add('holding');
if (audio[String.fromCharCode(ev.keyCode)].paused) {
playPromise = audio[String.fromCharCode(ev.keyCode)].play();
if (playPromise) {
playPromise.then(function() {
setTimeout(function() {
// Follow up operation
}, audio.duration * 1000);
}).catch(function() {
// Audio loading failure
});
} else {
audio[String.fromCharCode(ev.keyCode)].currentTime = 0;
}
}
}
答案 0 :(得分:1)
我为您写了一个完整的示例,并在下面加上注释。
一些关键要点:
如果您需要任何便利或对时间的控制,则需要使用Web Audio API。没有它,您将无法控制音频播放的缓冲或其他行为。
请勿为此使用base64。不用了Base64编码是一种将二进制数据编码为文本格式的方法。这里没有文本格式,因此没有必要。使用base64编码时,会增加33%的存储开销,使用CPU,内存等。这里没有理由。
请使用适当的文件API来获取所需的内容。要解码音频样本,我们需要一个数组缓冲区。因此,我们可以在文件本身上使用.arrayBuffer()
方法来获取该信息。这样会始终将内容保留为二进制格式,并允许浏览器在需要时进行内存映射。
代码:
const audioContext = new AudioContext();
let buffer;
document.addEventListener('DOMContentLoaded', (e) => {
document.querySelector('input[type="file"]').addEventListener('change', async (e) => {
// Start the AudioContext, now that we have user ineraction
audioContext.resume();
// Ensure we actually have at least one file before continuing
if ( !(e.currentTarget.files && e.currentTarget.files[0]) ) {
return;
}
// Read the file and decode the audio
buffer = await audioContext.decodeAudioData(
await e.currentTarget.files[0].arrayBuffer()
);
});
});
document.addEventListener('keydown', (e) => {
// Ensure we've loaded audio
if (!buffer) {
return;
}
// Create the node that will play our previously decoded buffer
bufferSourceNode = audioContext.createBufferSource();
bufferSourceNode.buffer = buffer;
// Hook up the buffer source to our output node (speakers, headphones, etc.)
bufferSourceNode.connect(audioContext.destination);
// Adjust pitch based on the key we pressed, just for fun
bufferSourceNode.detune.value = (e.keyCode - 65) * 100;
// Start playing... right now
bufferSourceNode.start();
});