U.Dev
U.Dev

Reputation: 113

How to get frequency from user's media file with vanilla javascript?

I need get frequency from user's media file with vanilla javascript. because, I will draw spectrum on canvas.

I did use createMediaElementSource and getByteTimeDomainData on Web audio API. but, I could not solve this issue.

<!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>

I Thought dataArray have frequency of media file. but, dataArray is have only 128.

Upvotes: 1

Views: 241

Answers (1)

Jaromanda X
Jaromanda X

Reputation: 1

You missed a few important steps

  1. decodeAudioData
  2. you want to createBufferSource if you're supplying buffer
  3. you want to source.start() to start playing

So - this sort of does what you want, but I'm using setInterval instead of whatever it is you'll want to do to display the analyser output

    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);
    });

Upvotes: 1

Related Questions