Как транслировать звук PCM на HTML без задержки? - PullRequest
0 голосов
/ 16 октября 2019

Аудиоданные PCM записываются в Unity3D в режиме реального времени. Все эти данные будут передаваться в HTML через WebSockets. Общая настройка - Socket.IO с сервером node.js.

Моя основная задача - добавить плавное воспроизведение звука для живого видео + решение для потоковой передачи звука на любой платформе. Это мой рабочий прогресс (потоковое видео): https://youtu.be/82_-a7WF3vs

Потоковая часть аудио и видео хорошо работает на платформах, отличных от html / non-WebGL.

Однако я не смогплавное воспроизведение аудио на HTML с помощью JavaScript. Он работает в режиме реального времени, но я обнаружил некоторые проблемы с запаздыванием, такие как шум ... Одной из моих проблем является то, что веб-браузеры не поддерживают многопоточность, это добавило некоторую задержку при получении потоковых данных и воспроизведения одновременно.

ниже - мой основной скрипт для воспроизведения 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;
        }

1 Ответ

0 голосов
/ 17 октября 2019

Как транслировать звук PCM на HTML без задержки?

С цифровым аудио всегда есть лаги, независимо от того, что вы делаете. Это не имеет никакого отношения к самому веб-браузеру.

Все эти данные будут передаваться в HTML через WebSockets.

Почему? Данные идут только в одном направлении, поэтому вы можете использовать обычный HTTP-ответ и не беспокоиться о накладных расходах веб-сокетов.

Одна из моих проблем заключается в том, что веб-браузеры не поддерживают многопоточность

Это не совсем точно.

Он работает в режиме реального времени, но я обнаружил некоторые проблемы с запаздыванием, такие как шум ...

То, что ваш код делает, это берет кадр PCM, который он получает, и немедленно воспроизводит его. Это не хорошо, так как звук разрушается, если вы не проигрываете полученные буферы непрерывно. Вы должны взять данные и запланировать их воспроизведение сразу после завершения текущих данных, а не выборки рано или слишком поздно.

Традиционно это означает выполнение собственной буферизации и настройку ScriptProcessorNode для чтения из этих буферов. ,Тем не менее, это также требует некоторой самостоятельной передискретизации, потому что скорость кодирования может не совпадать со скоростью воспроизведения.

В наши дни, я думаю, что MediaSource Extensions поддерживает декодирование PCM, так что вы можете просто передавать данные через него ипусть основная система сделает всю работу за вас.

...