gpt4 book ai didi

javascript - 如何在移动设备上按下 Web Audio 元素时立即发出声音?

转载 作者:行者123 更新时间:2023-12-03 00:03:21 24 4
gpt4 key购买 nike

我正在使用网络音频和 JavaScript 完成一个节拍/样本垫项目。当我点击采样垫时,我希望它立即发出声音,这在桌面版本上运行良好,但是,在移动设备上,只有当我将手指从屏幕上移开时,采样才会发出声音。然后,这会产生某种滞后,例如,您肯定无法及时播放任何音乐。有没有办法让样本在移动设备上按下后立即发出声音?我发现“mousedown”事件似乎最适合台式机,但我在移动设备上尝试过的任何东西都无法获得相同的结果。

请随时查看 Beat pad 项目:http://beatpad.dwcreate.co.uk/

如果需要,我稍后会发布代码。

非常感谢任何可以帮助我解决这个问题的人!

最佳答案

Audio element 似乎在 Apple 触摸设备上存在延迟问题……不确定其他设备。 AudioBuffer将提供更可靠的跨浏览器播放即时性。经过一番摆弄,似乎“touchstart”事件必须绑定(bind)在文档上,并且在绑定(bind)到元素上时不起作用。

// samples identified by keyboard key code
const samples = [49,50,51,52,53,54,55,56,57,48,45,61,113,119,101,114,116,121,117,105,111,112,91,93,97,115,100,102,103,104,106,107,108,59,39,122,120,99,118,98,110,109,44,46,47]

// audio contect for decoding and playback
const ctx = new (window.AudioContext || window.webkitAudioContext)({ latencyHint: 'playback' })

// decoded AudioBuffers we'll create for each sample
audioBuffers = {}

// keyboard keys to render
keys = {}

// track download/decode progress
let totalLoaded = 0

init()

function init() {
samples.forEach(async keyCode => {
const url = `https://cøder.com/static/61881209/${keyCode}.mp3`
const buffer = await (await fetch(url)).arrayBuffer()
ctx.decodeAudioData(buffer, decoded => {
audioBuffers[keyCode] = decoded
fileLoaded()
})
})
}

// keyboard press
document.addEventListener('keypress', playSample)

function fileLoaded() {
totalLoaded++
document.querySelector('#progress').innerText = `Samples Loaded: ${totalLoaded} / ${samples.length}`

if (totalLoaded === samples.length) {
initKeyboard()
}
}

function playSample({ keyCode }) {
// play audio sample from beginning
const [audioBuffer, key] = [audioBuffers[keyCode], keys[keyCode]]
if (audioBuffer) {
const bufferSource = ctx.createBufferSource()
bufferSource.buffer = audioBuffer;
bufferSource.connect(ctx.destination);
bufferSource.start(0);

requestAnimationFrame(_ => {
key.classList.remove('pressed')
requestAnimationFrame(_ => {
key.classList.add('pressed')
})
})
}
}

// draw keyboard on screen
function initKeyboard() {
const keyboard = document.createElement('div')
keyboard.className = 'keyboard'

let row = 0 // keyboard row
const breakOn = ['q', 'a', 'z'] // start new row

// render each keyboard key
samples.forEach(keyCode => {
const char = String.fromCharCode(keyCode)
const key = document.createElement('div')

key.className = 'key'
key.innerText = char
key.dataset.code = keyCode

// start new row
if (breakOn.includes(char)) {
row++
key.style.clear = 'both'
key.style.marginLeft = `${20*row}px`
}

keys[keyCode] = key
keyboard.append(key)
})

// bind click or touch if it's a tablet
if ('ontouchstart' in window) {
document.addEventListener('touchstart', handleClick)
} else {
document.addEventListener('mousedown', handleClick)
}

function handleClick(e) {
const {dataset: {code}} = e.target
if (code) {
playSample({ keyCode: code })
}
}

document.body.innerHTML = ''
document.body.append(keyboard)
}
body {
font-family: 'open sans light', arial, sans-serif;
background: #f9f9f9;
}
.keyboard {
width: 620px;
overflow: hidden;
white-space: nowrap;
}
.key {
background: #fff;
cursor: pointer;
height: 40px;
width: 40px;
margin: 2px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #ccc;
float: left;
border-radius: 6px;
user-select: none;
}
.key.pressed {
animation: keyPress .5s ease-out;
}

@keyframes keyPress {
0% {
background: lime;
}
100% {
background: #fff;
}
}
<div id="progress">Loading...</div>

关于javascript - 如何在移动设备上按下 Web Audio 元素时立即发出声音?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61881209/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com