javascript - 分析器未在音频传入时更新 Canvas 绘制速度

标签 javascript html streaming html5-canvas web-audio-api

每当我有一个新的缓冲区进入我的客户端时,我想将该音频实例重新绘制到我的 Canvas 上。我从 http://webaudioapi.com/samples/visualizer/ 获取了示例代码并尝试改变它以适应我在生活环境中的需求。我似乎有一些工作,因为当我调用 .draw() 时,我确实看到 Canvas 正在更新,但它的速度并没有应有的那么快。我看到的可能是 1 fps。如何加快 fps 并仍然为新缓冲区的每个实例调用绘制?

整个代码: https://github.com/grkblood13/web-audio-stream/tree/master/visualizer

这是为每个缓冲区调用 .draw() 的部分:

function playBuffer(audio, sampleRate) {
    var source      = context.createBufferSource();
    var audioBuffer = context.createBuffer(1, audio.length , sampleRate);
    source.buffer   = audioBuffer;
    audioBuffer.getChannelData(0).set(audio);

    source.connect(analyser);
    var visualizer = new Visualizer(analyser);
    visualizer.analyser.connect(context.destination);
    visualizer.draw(); // Draw new canvas for every new set of data

    if (nextTime == 0) {
        nextTime = context.currentTime + 0.05;  /// add 50ms latency to work well across systems - tune this if you like
    }
    source.start(nextTime);

    nextTime+=source.buffer.duration; // Make the next buffer wait the length of the last buffer before being played
}

这是 .draw() 方法:

Visualizer.prototype.draw = function() {
    function myDraw() {
        this.analyser.smoothingTimeConstant = SMOOTHING;
        this.analyser.fftSize = FFT_SIZE;

        // Get the frequency data from the currently playing music
        this.analyser.getByteFrequencyData(this.freqs);
        this.analyser.getByteTimeDomainData(this.times);

        var width = Math.floor(1/this.freqs.length, 10);

        // Draw the time domain chart.
        this.drawContext.fillStyle = 'black';
        this.drawContext.fillRect(0, 0, WIDTH, HEIGHT);

        for (var i = 0; i < this.analyser.frequencyBinCount; i++) {
            var value = this.times[i];
            var percent = value / 256;
            var height = HEIGHT * percent;
            var offset = HEIGHT - height - 1;
            var barWidth = WIDTH/this.analyser.frequencyBinCount;
            this.drawContext.fillStyle = 'green';
            this.drawContext.fillRect(i * barWidth, offset, 1, 2);
        }
    }
    requestAnimFrame(myDraw.bind(this));
}

最佳答案

您有可用的演示吗?因为您可以使用 Chrome 中的时间轴轻松调试它。您可以找出哪些过程需要很长时间。另外请去掉不必要的数学。大多数代码不需要每帧都执行。另外,从 playBuffer 调用绘图函数有多少次?当您调用 play 时,在该函数结束时它会请求一个新的动画帧。如果每次获得缓冲区时都调用 play,则会获得更多的数学->绘图->请求帧循环。这也使得它非常慢。如果您已经使用 requestanimationframe,则只需调用 play 函数一次。

要解决多帧问题:

window.animframe = requestAnimFrame(myDraw.bind(this));

在你的 playBuffer 上:

if(!animframe) visualizer.draw();

这确保它仅在没有请求时执行播放函数。

关于javascript - 分析器未在音频传入时更新 Canvas 绘制速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21606859/

相关文章:

javascript - 如何使用普通 javascript 检查数据属性是否存在?

javascript - 更改 <li> 元素的背景

android - 如何在所有智能设备上播放Red5流媒体?

javascript - 如何验证日期输入?

javascript - 将 Prop 从孙辈传递给 parent

javascript - 调整此代码,使视频只在网站上播放一次

javascript - 在 Dynamics CRM 中隐藏 div 内容

Java多线程: Passing camera frame to running worker thread

java - GStreamer 动态更改管道的 filesrc 位置 - 没有声音

javascript - 如何使用 TypeScript 解决 AngularJS 指令