Friday, 15 July 2011

javascript - HTML5 Audio API - "audio resources unavailable for AudioContext construction" -



javascript - HTML5 Audio API - "audio resources unavailable for AudioContext construction" -

i'm trying create graphic equalizer type visualization html5 sound - chrome @ point, using webkitaudiocontext.

i'm finding unusual , unpredictable behaviour when seek alter source of sound i.e. play different song. read somewhere should wait until "canplay" event on sound triggered before connecting context / analyser:

var context, sourcenode, analyser, javascriptnode, audio; var ctx = $("#songcanvas").get()[0].getcontext("2d"); function loadsong(url) { if (audio!=undefined) { audio.pause(); } sound = new audio(); audio.src = url; audio.addeventlistener("canplay", function(e) { setupaudionodes(); }, false); } function setupaudionodes() { context = new webkitaudiocontext(); javascriptnode = context.createjavascriptnode(2048, 1, 1); javascriptnode.connect(context.destination); analyser = context.createanalyser(); analyser.smoothingtimeconstant = 0.3; analyser.fftsize = 512; sourcenode = context.createmediaelementsource(audio); sourcenode.connect(analyser); analyser.connect(javascriptnode); sourcenode.connect(context.destination); javascriptnode.onaudioprocess = function() { var array = new uint8array(analyser.frequencybincount); analyser.getbytefrequencydata(array); ctx.clearrect(0, 0, 1000, 325); ctx.fillstyle="rgba(32, 45, 21,1)"; drawspectrum(array); } audio.play(); } function drawspectrum(array) { ( var = 0; < (array.length); i++ ){ var value = array[i]; ctx.fillrect(i*5,325-value,3,325); } };

the first 3 or 4 times alter source, works, fails "uncaught syntaxerror: sound resources unavailable audiocontext construction"

full demo here http://jsfiddle.net/eagqn/

i'd recommend staying away creating javascriptnode if you're going drawing spectrum. instead seek utilizing requestanimationframe method save cpu cycles , closer constant 60fps (is useful if window/tab in background function wrapped in requestanimationframe wait until window in focus 1 time again before firing).

the reason you're getting error because a) can create single audiocontext per window, b) should disconnecting mediaelementsource when you're finished using it, , c) should removing actual audio element too.

here's demo changes outlined above: http://jsbin.com/acolet/1/

class="snippet-code-js lang-js prettyprint-override">window.audiocontext = window.audiocontext || window.webkitaudiocontext; var context = new audiocontext(), audioanimation, sourcenode, analyser, audio, songs = document.getelementbyid('songs'), canvas = document.getelementbyid('songcanvas'), width = canvas.width, height = canvas.height, // context canvas draw on ctx = canvas.getcontext('2d'), gradient = ctx.createlineargradient(0, 0, 0, height), bar = { width: 2, gap: 2, ratio: height / 256 }; gradient.addcolorstop(1.00,'#000000'); gradient.addcolorstop(0.75,'#ff0000'); gradient.addcolorstop(0.25,'#ffff00'); gradient.addcolorstop(0.00,'#ffff00'); ctx.fillstyle = gradient; songs.addeventlistener('click', loadsong, false); function loadsong(e) { e.preventdefault(); var url = e.target.href; if (!url) homecoming false; if (audio) audio.remove(); if (sourcenode) sourcenode.disconnect(); cancelanimationframe(audioanimation); sound = new audio(); audio.src = url; audio.addeventlistener('canplay', setupaudionodes, false); } function setupaudionodes() { analyser = (analyser || context.createanalyser()); analyser.smoothingtimeconstant = 0.8; analyser.fftsize = 512; sourcenode = context.createmediaelementsource(audio); sourcenode.connect(analyser); sourcenode.connect(context.destination); audio.play(); drawspectrum(); } function drawspectrum() { var freq = new uint8array(analyser.frequencybincount); analyser.getbytefrequencydata(freq); ctx.clearrect(0, 0, width, height); audioanimation = requestanimationframe(drawspectrum); ( var = freq.length - 1; >= 0 ; i-- ){ var x = * (bar.width + bar.gap); var y = height - (freq[i] * bar.ratio); ctx.fillrect(x, y, bar.width, height); } } class="snippet-code-css lang-css prettyprint-override">body { font-family: sans-serif; background-color: #000; } { color: #fff; text-decoration: none; } ul { padding: 20px 0; width: 100px; } ul, canvas { float: left; } class="snippet-code-html lang-html prettyprint-override"><ul id="songs"> <li><a class="song" href="http://upload.wikimedia.org/wikipedia/en/4/45/acdc_-_back_in_black-sample.ogg">acdc</a></li> <li><a class="song" href="http://upload.wikimedia.org/wikipedia/en/9/9f/sample_of_%22another_day_in_paradise%22.ogg">phil collins</a></li> <li><a class="song" href="http://upload.wikimedia.org/wikipedia/en/1/1f/%22layla%22%2c_derek_and_the_dominos_song_%28sample%29.ogg">clapton</a></li> </ul> <canvas id="songcanvas" width="400" height="128"></canvas>

javascript html5 html5-audio webkitaudiocontext

No comments:

Post a Comment