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

Javascript 如何在HTML上无延迟地传输PCM音频?,javascript,unity3d,video-streaming,streaming,audio-streaming,Javascript,Unity3d,Video Streaming,Streaming,Audio Streaming,PCM音频数据在Unity3D中实时捕获。所有这些数据都将通过WebSockets流式传输到HTML。一般设置是Socket.IO和node.js服务器 我的主要任务是在所有平台上为实时视频+音频流解决方案添加平滑的音频播放。这是我的工作进度(视频流): 音频和视频流部分在非html/非WebGL平台上运行良好 然而,我无法使用javascript在html上进行平滑的音频播放。它实时运行,但我发现一些滞后的问题,如噪音。。。 我关注的一个问题是Web浏览器不支持多线程,它在接收流数据和同时播放

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

我的主要任务是在所有平台上为实时视频+音频流解决方案添加平滑的音频播放。这是我的工作进度(视频流):

音频和视频流部分在非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;
        }
var startTime=0;
var audioCtx=新的AudioContext();
函数ProcessAudioData(_字节){
ReadyGetFrame_aud=false;
//读取元数据
SourceSampleRate=bytePoint32(_字节,0);
SourceChannels=bytepoint32(_字节,4);
//将字节[]转换为浮点
var BufferData=_byte.slice(8,_byte.length);
AudioFloat=新的Float32Array(BufferData.buffer);
//===============================播放=====================
如果(AudioFloat.length>0)流音频(SourceChannels、AudioFloat.length、SourceSampleRate、AudioFloat);
//===============================播放=====================
ReadyToGetFrame_aud=true;
}
函数StreamAudio(NUM_通道、NUM_采样、采样率、音频块){
var audioBuffer=audioCtx.createBuffer(NUM_CHANNELS,(NUM_SAMPLES/NUM_CHANNELS),采样率);
用于(var通道=0;通道
如何在HTML上无延迟地传输PCM音频

无论你做什么,数字音频总是有些滞后。这与web浏览器本身无关

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

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

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

这不是很准确

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

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

传统上,这意味着要自己进行缓冲,并设置ScriptProcessorNode来读取这些缓冲区。然而,这也需要一些DIY重采样,因为编码速率可能与回放速率不同


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

您有ScriptProcessorNode的示例吗?我想我以前试过,但它的速度和延迟都是一半。可能采样率不同,需要一种重新采样的方法。我必须使用WebSocket,因为我将在我的项目中使用它,就像UDP/TCP通信一样。