如何使用 vanilla javascript 从用户的媒体文件中获取频率?
How to get frequency from user's media file with vanilla javascript?
我需要使用 vanilla javascript 从用户的媒体文件中获取频率。
因为,我会在 canvas.
上绘制光谱
我确实在 Web 音频上使用了 createMediaElementSource 和 getByteTimeDomainData API。但是,我无法解决这个问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="file" id="file">
<canvas id="canvas" width="500" height="250"></canvas>
<script>
// draw an oscilloscope of the current audio source
var canvas = document.getElementById('canvas');
var canvasCtx = canvas.getContext('2d');
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var audio = null;
document.getElementById('file').addEventListener('change', function(e) {
var audioCtx = new AudioContext();
var file = e.target.files[0];
var fileName = file.name;
var fileReader = new FileReader();
var audio = new Audio(fileName);
var analyser = audioCtx.createAnalyser();
fileReader.onload = function(e) {
var buffer = e.target.result;
var source = audioCtx.createMediaElementSource(audio);
var dataArray = new Uint8Array(analyser.fftSize);
source.connect(analyser);
analyser.connect(audioCtx.destination);
analyser.getByteTimeDomainData(dataArray);
console.log(dataArray);
}
fileReader.readAsArrayBuffer(file);
});
</script>
</body>
</html>
我以为 dataArray 有媒体文件的频率。
但是,dataArray 只有 128.
您错过了几个重要步骤
- 解码音频数据
- 如果要提供缓冲区,则需要创建 BufferSource
- 您想 source.start() 开始播放
所以 - 这种方法可以满足您的需求,但我使用的是 setInterval 而不是您想要显示分析器输出的任何方法
document.getElementById('file').addEventListener('change', function(e) {
var audioCtx = new AudioContext();
var file = e.target.files[0];
var fileName = file.name;
var fileReader = new FileReader();
// you don't need this next line at all
// var audio = new Audio(fileName);
var analyser = audioCtx.createAnalyser();
fileReader.onload = function(e) {
var buffer = e.target.result;
console.log(buffer);
audioCtx.decodeAudioData(buffer).then(audioBuffer => {
console.log(audioBuffer);
var source = audioCtx.createBufferSource();
var dataArray = new Uint8Array(analyser.fftSize);
source.buffer = audioBuffer;
source.connect(analyser);
analyser.connect(audioCtx.destination);
source.start();
setInterval(() => {
console.log(source.context.currentTime);
analyser.getByteTimeDomainData(dataArray);
console.log(dataArray);
}, 1000);
});
}
fileReader.readAsArrayBuffer(file);
});
我需要使用 vanilla javascript 从用户的媒体文件中获取频率。 因为,我会在 canvas.
上绘制光谱我确实在 Web 音频上使用了 createMediaElementSource 和 getByteTimeDomainData API。但是,我无法解决这个问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="file" id="file">
<canvas id="canvas" width="500" height="250"></canvas>
<script>
// draw an oscilloscope of the current audio source
var canvas = document.getElementById('canvas');
var canvasCtx = canvas.getContext('2d');
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var audio = null;
document.getElementById('file').addEventListener('change', function(e) {
var audioCtx = new AudioContext();
var file = e.target.files[0];
var fileName = file.name;
var fileReader = new FileReader();
var audio = new Audio(fileName);
var analyser = audioCtx.createAnalyser();
fileReader.onload = function(e) {
var buffer = e.target.result;
var source = audioCtx.createMediaElementSource(audio);
var dataArray = new Uint8Array(analyser.fftSize);
source.connect(analyser);
analyser.connect(audioCtx.destination);
analyser.getByteTimeDomainData(dataArray);
console.log(dataArray);
}
fileReader.readAsArrayBuffer(file);
});
</script>
</body>
</html>
我以为 dataArray 有媒体文件的频率。 但是,dataArray 只有 128.
您错过了几个重要步骤
- 解码音频数据
- 如果要提供缓冲区,则需要创建 BufferSource
- 您想 source.start() 开始播放
所以 - 这种方法可以满足您的需求,但我使用的是 setInterval 而不是您想要显示分析器输出的任何方法
document.getElementById('file').addEventListener('change', function(e) {
var audioCtx = new AudioContext();
var file = e.target.files[0];
var fileName = file.name;
var fileReader = new FileReader();
// you don't need this next line at all
// var audio = new Audio(fileName);
var analyser = audioCtx.createAnalyser();
fileReader.onload = function(e) {
var buffer = e.target.result;
console.log(buffer);
audioCtx.decodeAudioData(buffer).then(audioBuffer => {
console.log(audioBuffer);
var source = audioCtx.createBufferSource();
var dataArray = new Uint8Array(analyser.fftSize);
source.buffer = audioBuffer;
source.connect(analyser);
analyser.connect(audioCtx.destination);
source.start();
setInterval(() => {
console.log(source.context.currentTime);
analyser.getByteTimeDomainData(dataArray);
console.log(dataArray);
}, 1000);
});
}
fileReader.readAsArrayBuffer(file);
});