【问题标题】:How to stream PCM audio on HTML without lag?如何在 HTML 上无延迟地流式传输 PCM 音频?
【发布时间】:2020-02-13 09:52:54
【问题描述】:

在 Unity3D 中实时捕获 PCM 音频数据。所有这些数据都将通过 WebSockets 流式传输到 HTML。一般设置是 Socket.IO 和 node.js 服务器。

我的主要任务是为所有平台上的实时视频+音频流解决方案添加流畅的音频播放。这是我的工作进度(视频流):https://youtu.be/82_-a7WF3vs

音频和视频流部分在非 html/非 WebGL 平台上运行良好。

但是,我无法使用 javascript 在 html 上进行流畅的音频播放。它是实时运行的,但我发现了一些滞后的问题,比如噪音...... 我担心的一个问题是 Web 浏览器不支持多线程,它在同时接收流数据和播放时增加了一些延迟。

以下是我的 PCM 播放核心脚本。希望有人可以帮助我改进它。

        var startTime = 0;
        var audioCtx = new AudioContext();

        function ProcessAudioData(_byte) {
            ReadyToGetFrame_aud = false;

            //read meta data
            SourceSampleRate = ByteToInt32(_byte, 0);
            SourceChannels = ByteToInt32(_byte, 4);

            //conver byte[] to float
            var BufferData = _byte.slice(8, _byte.length);
            AudioFloat = new Float32Array(BufferData.buffer);

            //=====================playback=====================
            if(AudioFloat.length > 0) StreamAudio(SourceChannels, AudioFloat.length, SourceSampleRate, AudioFloat);
            //=====================playback=====================

            ReadyToGetFrame_aud = true;
        }

        function StreamAudio(NUM_CHANNELS, NUM_SAMPLES, SAMPLE_RATE, AUDIO_CHUNKS) {
            var audioBuffer = audioCtx.createBuffer(NUM_CHANNELS, (NUM_SAMPLES / NUM_CHANNELS), SAMPLE_RATE);
            for (var channel = 0; channel < NUM_CHANNELS; channel++) {
                // This gives us the actual ArrayBuffer that contains the data
                var nowBuffering = audioBuffer.getChannelData(channel);
                for (var i = 0; i < NUM_SAMPLES; i++) {
                    var order = i * NUM_CHANNELS + channel;
                    nowBuffering[i] = AUDIO_CHUNKS[order];
                }
            }

            var source = audioCtx.createBufferSource();
            source.buffer = audioBuffer;

            source.connect(audioCtx.destination);
            source.start(startTime);

            startTime += audioBuffer.duration;
        }

【问题讨论】:

    标签: javascript unity3d video-streaming streaming audio-streaming


    【解决方案1】:

    如何在 HTML 上无延迟地流式传输 PCM 音频?

    无论您做什么,数字音频总会有一些延迟。这与网络浏览器本身无关。

    所有这些数据都将通过 WebSockets 流式传输到 HTML。

    为什么?数据只向一个方向传输,因此您可以使用常规 HTTP 响应,而不必担心 Web Sockets 的开销。

    我担心的一个问题是 Web 浏览器不支持多线程

    这并不准确。

    它是实时运行的,但我发现了一些滞后问题,例如噪音...

    您的代码似乎做的是获取它接收到的 PCM 帧并立即播放。这不好,因为如果您不连续播放接收到的缓冲区,声音就会被破坏。您必须获取数据并安排在当前数据完成后立即播放,而不是过早或过晚采样。

    传统上,这意味着您自己进行缓冲并设置 ScriptProcessorNode 以从这些缓冲区中读取。但是,这也需要一些 DIY 重新采样,因为编码速率可能与播放速率不同。

    现在,我认为 MediaSource Extensions 支持 PCM 解码,因此您可以通过它管道传输数据,让底层系统为您完成所有工作。

    【讨论】:

    • 你有 ScriptProcessorNode 的例子吗?我想我以前试过,但它的播放速度像半速和延迟。可能采样率不同,需要一种重新采样的方法。
    • 我必须使用 WebSockets,因为我将在我的项目中像 UDP/TCP 通信一样使用它。
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 2015-07-28
    • 2012-09-16
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多