2016-02-18 12 views
2

我已经谷歌所有这个问题,但找不到任何东西。 我处于这种情况,我需要删除source = createMediaElementSource以便我可以再次创建它。我使用的音频分析器必须在每次使用ajax加载指定音轨时加载。只要你进入另一页面,然后返回,分析仪就不见了。因此我需要以某种方式重新初始化它。删除createMediaElementSource

我的代码:

var analyserElement = document.getElementById('analyzer'); 
var canvas, ctx, source, context, analyser, fbc_array, bars, bar_x, 
    bar_width, bar_height; 

function analyzerSetElements() { 
    var analyserElement = document.getElementById('analyzer'); 
} 

function analyzerInitialize() { 
    if (context == undefined) { 
    context = new AudioContext(); 
    } 
    analyser = context.createAnalyser(); 
    canvas = analyserElement; 
    ctx = canvas.getContext('2d'); 
    source = context.createMediaElementSource(audio); 
    source.connect(analyser); 
    analyser.connect(context.destination); 
    frameLooper(); 
} 

function analyzerStop(){ 
    context = undefined; 
    analyser = undefined; 
    source = undefined; 
} 

function frameLooper() { 
    canvas.width = canwidth; 
    canvas.height = canheight; 
    ctx.imageSmoothingEnabled = false; 
    fbc_array = new Uint8Array(analyser.frequencyBinCount); 
    analyser.getByteFrequencyData(fbc_array); 
    ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas 
    ctx.fillStyle = "white"; // Color of the bars 
    function valBetween(v, min, max) { 
     return (Math.min(max, Math.max(min, v))); 
    } 
    var beatc = fbc_array[2]/4; 
    var beatround = Math.round(beatc); 
    //if (beatround < 10) { 
    // ctx.globalAlpha = '0.1125'; 
    //} 
    //else { 
    // ctx.globalAlpha = '0.' + beatround; 
    //} 
    bars = canbars; 
    for (var i = 0; i < bars; i += canmultiplier) { 
     bar_x = i * canspace; 
     bar_width = 2; 
     bar_height = -3 - (fbc_array[i]/2); 
     ctx.fillRect(bar_x, canvas.height, bar_width, bar_height); 
    } 
    window.requestAnimationFrame(frameLooper); 
    console.log('Looped') 
} 

所以,当我跑analyzerStop()后运行analyzerInitialize()我仍然得到这个错误:

audio.js:179 Uncaught DOMException: Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode

我怎样才能使它如此运行analyzerInitialize()永远不会失败?

+0

你可能需要断开上卸载或某事()的东西。 – dandavis

+0

如何?你能给我正确的语法吗? –

+0

我不知道,我没有把它弄糟,但像'window.onunload = function(){source.disconnect();};'(做了一个更清洁和更专业)。请参阅https://developer.mozilla.org/en-US/docs/Web/API/AudioNode/disconnect。你可能也可以在connect()之前调用它...... – dandavis

回答

0

我遇到了同样的问题。不幸的是,我没有找到如何从音频元素中创建MediaElementSourceNode。尽管如此,它是可以通过使用WeakMap记得MediaElementSourceNode来解决此问题:

var MEDIA_ELEMENT_NODES = new WeakMap(); 

function analyzerInitialize() { 
    if (context == undefined) { 
    context = new AudioContext(); 
    } 
    analyser = context.createAnalyser(); 
    canvas = analyserElement; 
    ctx = canvas.getContext('2d'); 
    if (MEDIA_ELEMENT_NODES.has(audio)) { 
    source = MEDIA_ELEMENT_NODES.get(audio); 
    } else { 
    source = context.createMediaElementSource(audio); 
    MEDIA_ELEMENT_NODES.set(audio, source); 
    } 
    source.connect(analyser); 
    analyser.connect(context.destination); 
    frameLooper(); 
} 

通过使用WeakMap我避免内存问题。

0

您可以设置contextsource全局定义变量,而不是重新定义变量

context = context || new AudioContext(); 
source = source || context.createMediaElementSource(audio);