我正在努力编写一个简单的HTML页面,其形式是将音频文件作为输入并将其传递给JavaScript文件进行操作。
我有什么
index.html
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<main role="main" class="container">
<form action="#" method="POST" enctype="multipart/form-data" class="audio-input-form">
<label>Audio File:</label>
<input accept="audio/*" type="file" name="audio_file"/>
<input type="submit" value="Get BPM" />
</form>
</main>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
app.js
// Package from NPM I import
import { analyze } from 'web-audio-beat-detector';
## here I want to be able to get and manipulate the audio data
所需结果
提交表单时,我只希望实际的文件数据在JavaScript文件中可用(我想是数组缓冲区)。我希望使用this tutorial将其转换为AudioBuffer但我不清楚如何实际传递数据。
我曾尝试将表单操作设为我的JS文件中的一个函数,并且也使用了onClick函数,但似乎都无法正常工作。我需要某种形式的XHR吗?我对他们的目的感到困惑,我不希望为此运行任何类型的服务器,而只是在浏览器中运行的HTML页面和JavaScript文件。
我创建了一个甚至不使用表单的小示例。如果只有一个输入,则可以收听其onchange
事件。至少对于本演示而言,此方法有效。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<input id="audio-file" accept="audio/*" disabled type="file"/>
<script>
import('https://dev.jspm.io/web-audio-beat-detector')
.then(({ default: { analyze }}) => {
const $audioFileInput = document.getElementById('audio-file');
$audioFileInput.disabled = false;
$audioFileInput.onchange = async () => {
const file = $audioFileInput.files[0];
if (file !== undefined) {
$audioFileInput.disabled = true;
const arrayBuffer = await file.arrayBuffer();
const audioContext = new AudioContext();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
alert(await analyze(audioBuffer));
$audioFileInput.disabled = false;
}
};
});
</script>
</body>
</html>
我也通过jspm.io加载了web-audio-beat-detector
,但在实际应用中,您可能希望将其与webpack捆绑在一起。
每次您要像我在这里解码音频数据时创建AudioContext都是非常浪费的。如果您打算解码多个文件,则重用一个AudioContext会更有意义。
请注意,我仅在最新版本的Firefox和Chrome中对此进行了测试。不幸的是,它不能在Safari中使用。使它在Safari中工作将需要更多代码,这就是我省略它的原因。
文件有多大?理想情况下,您将分析文件的第一部分,而无需上传整个文件。不知道节拍检测算法如何工作,但是您可以创建一个读取缓冲区来获取要分析的文件的前N个字节/秒。