Демонстрация экрана со звуком приложения: как это устроено
Опубликовано
Показать экран умеет любой голосовой чат. Показать экран так, чтобы собеседники услышали звук игры или видео отдельно от вашего микрофона, — умеют немногие, и это не лень разработчиков. Задача упирается в то, как операционные системы устроены внутри: захват звука конкретного приложения — принципиально более сложная операция, чем захват картинки. Разберём, почему.
Три разных «поделиться звуком»
Под одной кнопкой обычно скрываются три несовместимые вещи.
Звук вкладки браузера. Проще всего: браузер сам сводит звук своих вкладок и может отдать поток одной из них. Работает надёжно, но только для того, что играет в браузере. Игру или локальный плеер так не захватить.
Звук всей системы. Забирается всё, что выводится на устройство воспроизведения, — вместе с уведомлениями, музыкой в другом окне и звуком самого голосового чата. Последнее особенно неприятно: в поток попадают голоса собеседников, и получается петля.
Звук конкретного приложения. То, что нужно на практике: только игра, без уведомлений, без музыки и без чужих голосов. Технически — самый сложный вариант.
Почему картинку захватить легко, а звук трудно
Разница в том, где именно данные находятся в момент захвата.
Изображение окна существует как отдельный буфер: у каждого окна свои пиксели, композитор собирает из них итоговую картинку. Попросить у системы содержимое одного окна — штатная операция, ради которой всё и устроено.
Звук по умолчанию так не хранится. Приложения отдают свои потоки звуковой подсистеме, та микширует их в один и отправляет на устройство. К моменту, когда звук доходит до места, откуда его удобно забрать, он уже смешан — разделить обратно нельзя. Захват «звука приложения» означает перехват до микширования, а это уже вмешательство в чужой звуковой конвейер.
Как это устроено в Windows
В Windows начиная со сборки 2004 (это Windows 10 версии 20H1, номер сборки 19041) в WASAPI появился режим замкнутого цикла с фильтрацией по процессу. Он позволяет попросить у системы: дай мне то, что выводит вот этот процесс, включая его дочерние.
Именно на этом построен захват звука приложения в настольном клиенте Discourse. Отсюда следуют практические ограничения, которые стоит знать заранее:
- Нужна Windows 10 сборки 19041 или новее. На более старых версиях режима просто нет, и никакая программа его не изобретёт.
- Нужен настольный клиент. Браузер такого доступа к системе не имеет и иметь не должен — это была бы дыра в изоляции вкладок.
- Захват идёт по процессу. Если игра запускается через лаунчер и звук выводит отдельный дочерний процесс, выбирать надо тот процесс, который реально играет.
На macOS до недавнего времени эквивалента не было вовсе, и все решения строились на установке виртуального аудиоустройства — то есть системного драйвера, через который приходилось перенаправлять звук вручную.
Почему звук идёт отдельной дорожкой
Захватить звук — половина дела. Вторая половина: отправить его так, чтобы он не смешался с микрофоном.
Смешивать нельзя по нескольким причинам сразу.
Громкость. Игра и голос имеют разные уровни. Смешанные в один поток, они конкурируют: либо голос тонет, либо игра еле слышна.
Обработка. Микрофонная цепочка содержит шумоподавление и шумовой гейт, настроенные на человеческую речь. Пропустив через них музыку, вы получите ровно то, для чего эти алгоритмы предназначены: всё, что не похоже на речь, будет подавлено. Музыка звучит «подводно», а гейт вырезает тихие места.
Управление на приёме. Отдельные дорожки позволяют слушателю самому решать баланс — сделать игру тише, а собеседника громче. Смешанный поток такой возможности не оставляет.
Поэтому в Discourse звук демонстрируемого приложения передаётся отдельной дорожкой от микрофона: он не проходит через микрофонную обработку и регулируется независимо.
Типовые проблемы и что с ними делать
Экран показывается, звука нет. Чаще всего выбран не тот источник: захват окна вместо захвата приложения, или выбран лаунчер, а звук выводит игровой процесс. Проверьте, какой именно процесс сейчас играет.
Звук идёт, но вместе с ним слышны собеседники. Признак того, что захватывается системный вывод, а не конкретное приложение. В системный вывод попадает и звук голосового чата.
Собеседники слышат игру, но не слышат вас. Дорожки независимы, значит и ломаются независимо: звук приложения захватился, а микрофон — нет. Это отдельная поломка, разобранная в пошаговой диагностике микрофона.
Картинка рассыпается на квадраты. Это уже не про звук. Демонстрация экрана — самый требовательный к каналу поток в созвоне: 1080p в динамике на порядок «дороже» голоса. Разбор — в статье про задержку, джиттер и потери пакетов.
Игра в полноэкранном режиме перестаёт отдавать картинку. Эксклюзивный полноэкранный режим отдаёт видеокарту игре напрямую в обход композитора. Лечится переводом игры в оконный режим без рамки — визуально то же самое, а захват работает.
Что спрашивать, выбирая сервис
Если совместный просмотр для вас важен, вопрос «есть ли демонстрация экрана» слишком грубый. Разница между сервисами лежит в трёх деталях:
- Захватывается ли звук отдельного приложения — или только вкладка либо вся система.
- Идёт ли он отдельной дорожкой от микрофона.
- Проходит ли он мимо микрофонной обработки — иначе шумоподавление превратит музыку в кашу.
Первое обычно указано в описании. Второе и третье проверяются за минуту практикой: включите музыку, поделитесь звуком и спросите собеседника, как это звучит. Если музыка «булькает» и проваливается в паузах — она идёт через микрофонную цепочку, и хорошего совместного просмотра не получится.