最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - I'm trying to use the HTML5 Web Audio API to create an equalizer type graphic, but the data is never brough

programmeradmin2浏览0评论

I'm trying to use the HTML5 Web Audio API to create an equalizer type graphic, but for some reason the data is never brought into the MediaElementSource.

$('.table').on('click', 'tr', function() {
    if ($(this) != $('.table tr:first-child')) {
        var src = $(this).children().first().attr('data-src');
        var audio = new Audio();
        audio.src = src;
        audio.controls = true;
        $('.file-playlist').append(audio);
        console.log(audio);         
        audio.load();
        audio.play();
        context = new webkitAudioContext();
        console.log(context);
        analyser = context.createAnalyser();
        console.log(analyser);
        source = context.createMediaElementSource(audio);
        console.log(source);
        source.connect(analyser);
        console.log(source);
        analyser.connect(context.destination);
        console.log(analyser);
        rafCallback();
    }
});

In the function above I have created an audio element and used that as the source for the context's MediaElementSource however there is some issue that I cannot find because in the console, the activeSourceCount attribute of the AudioContext is always 0, which means that it never received the audio element that I gave it as a parameter.

EDIT:

I modified my code according to what idbehold said; however, now I have 2 errors, an InvalidStateError: DOM Exception 11 on the source = context.createMediaElementSource(audio); line, and a TypeError: Cannot read property 'frequencyBinCount' of undefined at the line var freqByteData = new Uint8Array(analyser.frequencyBinCount); Additionally, the MediaElementSource still has 0 activeSourceCounts.

$(document).ready(function() {
    var context = new webkitAudioContext();
    console.log(context);
    var audio;
    var source;
    $('.table').on('click', 'tr', function() {
        if ($(this) != $('.table tr:first-child')) {
            var src = $(this).children().first().attr('data-src');
            if (audio) {
                audio.remove();
                audio = new Audio();
                audio.src = src;
                audio.controls = true;
                $('.file-playlist').append(audio);
                console.log(audio);
                audio.addEventListener("canplay", function(e) {
                    analyser = context.createAnalyser();
                    console.log(analyser);
                    source.disconnect();
                    source = context.createMediaElementSource(audio);
                    console.log(source);
                    source.connect(analyser);
                    console.log(source);
                    analyser.connect(context.destination);
                    console.log(analyser);
                    audio.load();
                    audio.play();
                }, false);
            }
            else {
                audio = new Audio();
                audio.src = src;
                audio.controls = true;
                $('.file-playlist').append(audio);
                console.log(audio);
                audio.addEventListener("canplay", function(e) {
                    analyser = (analyser || context.createAnalyser());
                    console.log(analyser);
                    source = context.createMediaElementSource(audio);
                    console.log(source);
                    source.connect(analyser);
                    console.log(source);
                    analyser.connect(context.destination);
                    console.log(analyser);
                    audio.load();
                    audio.play();
               }, false);
            }
        }
        rafCallback();
    });
});

EDIT 2:

in my rafCallback() function, I noticed that the data from the Uint8Array was never being processed, so I added the getByteFrequencyData(analyser.frequencyBinCount); which fixed everything.

I'm trying to use the HTML5 Web Audio API to create an equalizer type graphic, but for some reason the data is never brought into the MediaElementSource.

$('.table').on('click', 'tr', function() {
    if ($(this) != $('.table tr:first-child')) {
        var src = $(this).children().first().attr('data-src');
        var audio = new Audio();
        audio.src = src;
        audio.controls = true;
        $('.file-playlist').append(audio);
        console.log(audio);         
        audio.load();
        audio.play();
        context = new webkitAudioContext();
        console.log(context);
        analyser = context.createAnalyser();
        console.log(analyser);
        source = context.createMediaElementSource(audio);
        console.log(source);
        source.connect(analyser);
        console.log(source);
        analyser.connect(context.destination);
        console.log(analyser);
        rafCallback();
    }
});

In the function above I have created an audio element and used that as the source for the context's MediaElementSource however there is some issue that I cannot find because in the console, the activeSourceCount attribute of the AudioContext is always 0, which means that it never received the audio element that I gave it as a parameter.

EDIT:

I modified my code according to what idbehold said; however, now I have 2 errors, an InvalidStateError: DOM Exception 11 on the source = context.createMediaElementSource(audio); line, and a TypeError: Cannot read property 'frequencyBinCount' of undefined at the line var freqByteData = new Uint8Array(analyser.frequencyBinCount); Additionally, the MediaElementSource still has 0 activeSourceCounts.

$(document).ready(function() {
    var context = new webkitAudioContext();
    console.log(context);
    var audio;
    var source;
    $('.table').on('click', 'tr', function() {
        if ($(this) != $('.table tr:first-child')) {
            var src = $(this).children().first().attr('data-src');
            if (audio) {
                audio.remove();
                audio = new Audio();
                audio.src = src;
                audio.controls = true;
                $('.file-playlist').append(audio);
                console.log(audio);
                audio.addEventListener("canplay", function(e) {
                    analyser = context.createAnalyser();
                    console.log(analyser);
                    source.disconnect();
                    source = context.createMediaElementSource(audio);
                    console.log(source);
                    source.connect(analyser);
                    console.log(source);
                    analyser.connect(context.destination);
                    console.log(analyser);
                    audio.load();
                    audio.play();
                }, false);
            }
            else {
                audio = new Audio();
                audio.src = src;
                audio.controls = true;
                $('.file-playlist').append(audio);
                console.log(audio);
                audio.addEventListener("canplay", function(e) {
                    analyser = (analyser || context.createAnalyser());
                    console.log(analyser);
                    source = context.createMediaElementSource(audio);
                    console.log(source);
                    source.connect(analyser);
                    console.log(source);
                    analyser.connect(context.destination);
                    console.log(analyser);
                    audio.load();
                    audio.play();
               }, false);
            }
        }
        rafCallback();
    });
});

EDIT 2:

in my rafCallback() function, I noticed that the data from the Uint8Array was never being processed, so I added the getByteFrequencyData(analyser.frequencyBinCount); which fixed everything.

Share Improve this question edited Sep 16, 2013 at 15:29 Robert Harvey 181k48 gold badges348 silver badges513 bronze badges asked Jul 2, 2013 at 21:27 Ilan BialaIlan Biala 3,4175 gold badges37 silver badges45 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 6

You can only create a single AudioContext per window and you should be waiting until the audio's canplay event fires before setting up your MediaElementSource. You should also be disconnecting the MediaElementSource when you're finished using it.

Here's an example that I used to answer a similar question: http://jsbin./acolet/1/

发布评论

评论列表(0)

  1. 暂无评论