Один пакет — один мини-плеер: почему мы перенесли голос БОЛТУНа в AudioWorklet
PAPADAN 29 минут назад Один пакет — один мини-плеер: почему мы перенесли голос БОЛТУНа в AudioWorklet Средний 4 мин 1.2K JavaScript * Rust * Звук Веб-разработка * Windows * Кейс В прошлой статье мы разбирались, почему...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Вот важная новость с фронта ИИ: PAPADAN 29 минут назад Один пакет — один мини-плеер: почему мы перенесли голос БОЛТУНа в AudioWorklet Средний 4 мин 1. 2K JavaScript * Rust * Звук Веб-разработка * Windows * Кейс В прошлой статье мы разбирались, почему после сборки БОЛТУНа на Tauri трещал голос, автокалибровка вмешивалась в разговор, а демонстрация экрана через минуту превращалась в чёрный прямоугольник. После тех исправлений мы продолжили разбирать звуковой тракт и нашли ещё одну проблему.
Сам аудиопакет мог прийти вовремя, успешно декодироваться и содержать нормальные сэмплы — а на выходе всё равно появлялся короткий щелчок. Причина оказалась не в сети и не в кодеке. Мы слишком буквально превратили сетевые пакеты в единицы воспроизведения.
Технические детали
Один пакет — один плеерБОЛТУН передаёт голос кадрами по 20 мс. При частоте 16 кГц в одном кадре находится 320 сэмплов. Старая схема воспроизведения выглядела примерно так:WebSocket ↓ декодирование пакета ↓ новый AudioBuffer ↓ новый AudioBufferSourceNode ↓ планирование времени запуска ↓ общий микшер На каждый пакет создавался отдельный AudioBufferSourceNode:const buffer = context.
createBuffer(1, samples. length, sampleRate); buffer. copyToChannel(samples, 0); const source = context.
createBufferSource(); source. buffer = buffer; source. connect(peerGain); source.
Отраслевые последствия
start(startTime); Для одного говорящего это 50 маленьких источников звука в секунду. Для четырёх собеседников — уже 200. Каждый из них нужно создать, подключить к графу Web Audio и вовремя запустить.
Чтобы пакеты не сталкивались друг с другом, мы хранили для каждого участника расчётное время следующего запуска. Перед началом речи накапливали запас примерно в 180 мс, а при опозданиях увеличивали его до 300 мс. На бумаге всё выглядело разумно.
В обычном браузере схема действительно могла долго работать нормально. Но внутри WebView2 основной поток занят не только голосом: он обновляет интерфейс, принимает сообщения, рисует визуализацию и иногда останавливается на сборку мусора. Если JavaScript запланировал очередной источник слишком поздно, браузер уже не мог вернуть пропущенные несколько миллисекунд.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.






