Пространственное звучание — это эффект полного погружения, который помещает пользователей в центр событий, делая ваш контент более реалистичным. Звук «пространственно» «пространственно» преобразуется для создания эффекта многоканального звучания, аналогичного системе объемного звучания, но через наушники.
Например, в фильме звук автомобиля может начинаться позади пользователя, распространяться вперед и затихать вдали. В видеочате голоса можно разделить и расположить вокруг пользователя, что облегчает идентификацию говорящих.
Если ваш контент использует поддерживаемый аудиоформат, вы можете добавить пространственное звучание в свое приложение, начиная с Android 13 (уровень API 33).
Запрос на проверку возможностей
Используйте класс Spatializer для запроса возможностей и поведения устройства в области пространственного звучания. Для начала получите экземпляр класса Spatializer из AudioManager :
Котлин
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
После приобретения Spatializer проверьте выполнение четырех условий, необходимых для того, чтобы устройство воспроизводило пространственный звук:
| Критерии | Проверять |
|---|---|
| Поддерживает ли устройство пространственное позиционирование? | getImmersiveAudioLevel() не является SPATIALIZER_IMMERSIVE_LEVEL_NONE |
| Доступна ли пространственная визуализация? Доступность зависит от совместимости с существующей системой маршрутизации аудиовыхода. | isAvailable() равно true |
| Включена ли функция пространственного отображения? | isEnabled() равно true |
| Можно ли пространственно обработать звуковую дорожку с заданными параметрами ? | canBeSpatialized() равно true |
Эти условия могут не выполняться, например, если пространственная модуляция недоступна для текущей звуковой дорожки или полностью отключена на устройстве вывода звука.
Отслеживание положения головы
При использовании поддерживаемых гарнитур платформа может регулировать пространственное звучание в зависимости от положения головы пользователя. Чтобы проверить, доступен ли трекер положения головы для текущего маршрута вывода звука, вызовите метод isHeadTrackerAvailable() .
Совместимый контент
Spatializer.canBeSpatialized() указывает, можно ли пространственно преобразовать аудиосигнал с заданными свойствами в соответствии с маршрутизацией текущего выходного устройства. Этот метод принимает объекты AudioAttributes и AudioFormat , которые более подробно описаны ниже.
AudioAttributes
Объект AudioAttributes описывает использование аудиопотока (например, игрового звука или стандартных медиафайлов ), а также его поведение при воспроизведении и тип содержимого .
При вызове метода canBeSpatialized() используйте тот же экземпляр AudioAttributes , что и для вашего Player . Например, если вы используете библиотеку Jetpack Media3 и не настроили AudioAttributes , используйте AudioAttributes.DEFAULT .
Отключение пространственного звука
Чтобы указать, что ваш контент уже был пространственно обработан, вызовите setIsContentSpatialized(true) , чтобы избежать двойной обработки звука. В качестве альтернативы, настройте поведение пространственной обработки, чтобы полностью отключить её, вызвав setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) .
AudioFormat
Объект AudioFormat описывает подробности о формате и конфигурации каналов звуковой дорожки.
При создании экземпляра AudioFormat для передачи в canBeSpatialized() установите кодировку в соответствии с форматом вывода, ожидаемым от декодера. Также следует установить маску каналов , соответствующую конфигурации каналов вашего контента. Для получения рекомендаций по использованию конкретных значений обратитесь к разделу «Поведение пространственной обработки по умолчанию» .
Прислушивайтесь к изменениям в Spatializer
Чтобы отслеживать изменения состояния Spatializer , можно добавить слушатель с помощью Spatializer.addOnSpatializerStateChangedListener() . Аналогично, чтобы отслеживать изменения доступности трекера головы, вызовите Spatializer.addOnHeadTrackerAvailableListener() .
Это может быть полезно, если вы хотите корректировать выбор треков во время воспроизведения, используя коллбэки слушателя. Например, когда пользователь подключает или отключает гарнитуру от устройства, коллбэк onSpatializerAvailableChanged указывает, доступен ли эффект пространственного звучания для нового маршрута вывода звука. На этом этапе вы можете рассмотреть возможность обновления логики выбора треков в вашем плеере в соответствии с новыми возможностями устройства. Подробную информацию о поведении ExoPlayer при выборе треков см. в разделе «ExoPlayer и пространственное звучание» .
ExoPlayer и пространственное аудио
В последних версиях ExoPlayer упрощена поддержка пространственного звука. Если вы используете автономную библиотеку ExoPlayer (пакет com.google.android.exoplayer2 ), версия 2.17 настраивает платформу для вывода пространственного звука, а версия 2.18 вводит ограничения на количество аудиоканалов . Если вы используете модуль ExoPlayer из библиотеки Media3 (пакет androidx.media3 ), версии 1.0.0-beta01 и более новые включают эти же обновления.
После обновления зависимости ExoPlayer до последней версии вашему приложению останется только добавить контент, который можно пространственно интерпретировать.
Ограничения на количество аудиоканалов
Когда выполняются все четыре условия для пространственного звука, ExoPlayer выбирает многоканальную звуковую дорожку. В противном случае ExoPlayer выбирает стереодорожку. Если свойства Spatializer изменяются, ExoPlayer инициирует новый выбор дорожки, чтобы выбрать звуковую дорожку, соответствующую текущим свойствам. Обратите внимание, что этот новый выбор дорожки может вызвать короткий период повторной буферизации.
Чтобы отключить ограничения по количеству аудиоканалов, установите параметры выбора треков в плеере, как показано ниже:
Котлин
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Аналогичным образом, вы можете обновить параметры существующего селектора дорожек, чтобы отключить ограничения по количеству аудиоканалов, следующим образом:
Котлин
val trackSelector = DefaultTrackSelector(context) ... trackSelector.parameters = trackSelector.buildUponParameters() .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context); ... trackSelector.setParameters( trackSelector .buildUponParameters() .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
При отключенных ограничениях на количество аудиоканалов, если контент содержит несколько аудиодорожек, ExoPlayer изначально выбирает дорожку с наибольшим количеством каналов, воспроизводимую на устройстве. Например, если контент содержит многоканальную аудиодорожку и стереофоническую аудиодорожку, и устройство поддерживает воспроизведение обеих, ExoPlayer выберет многоканальную дорожку. Подробную информацию о настройке этого поведения см. в разделе « Выбор аудиодорожки» .
выбор аудиодорожки
Если в ExoPlayer отключено ограничение количества аудиоканалов , программа не выбирает автоматически аудиодорожку, соответствующую свойствам пространственного модулятора устройства. Вместо этого вы можете настроить логику выбора дорожек в ExoPlayer, задав параметры выбора дорожек до или во время воспроизведения. По умолчанию ExoPlayer выбирает аудиодорожки, идентичные исходной дорожке по типу MIME (кодировке), количеству каналов и частоте дискретизации.
Изменение параметров выбора трассы
Чтобы изменить параметры выбора трека в ExoPlayer, используйте Player.setTrackSelectionParameters() . Аналогично, вы можете получить текущие параметры ExoPlayer с помощью Player.getTrackSelectionParameters() . Например, чтобы выбрать стереофонический аудиотрек во время воспроизведения:
Котлин
exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters .buildUpon() .setMaxAudioChannelCount(2) .build()
Java
exoPlayer.setTrackSelectionParameters( exoPlayer.getTrackSelectionParameters() .buildUpon() .setMaxAudioChannelCount(2) .build() );
Обратите внимание, что изменение параметров выбора треков во время воспроизведения может привести к прерыванию воспроизведения. Более подробная информация о настройке параметров выбора треков в плеере доступна в разделе выбора треков документации ExoPlayer.
Поведение пространственной обработки по умолчанию
В Android стандартное поведение пространственного отображения включает следующие параметры, которые могут быть настроены производителями оборудования:
Пространственное звучание применяется только к многоканальному контенту, а не к стерео. Если вы не используете ExoPlayer, в зависимости от формата вашего многоканального аудиоконтента, вам может потребоваться установить большое значение максимального количества каналов , которые может выводить аудиодекодер. Это гарантирует, что аудиодекодер будет выводить многоканальный PCM-сигнал для пространственного звучания на платформе.
Котлин
val mediaFormat = MediaFormat() mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99)
Java
MediaFormat mediaFormat = new MediaFormat(); mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
Пример работы можно посмотреть в файле
MediaCodecAudioRenderer.javaкомпонента ExoPlayer. Чтобы отключить пространственное звучание самостоятельно, независимо от настроек производителя, см. раздел «Отключение пространственного звука» .AudioAttributes: Пространственная обработка звука возможна, если дляusageустановлено значениеUSAGE_MEDIAилиUSAGE_GAME.AudioFormat: Используйте маску каналов, содержащую как минимум каналыAudioFormat.CHANNEL_OUT_QUAD(передний левый, передний правый, задний левый и задний правый), чтобы звук подходил для пространственной обработки. В приведенном ниже примере мы используемAudioFormat.CHANNEL_OUT_5POINT1для аудиодорожки 5.1. Для стереофонической аудиодорожки используйтеAudioFormat.CHANNEL_OUT_STEREO.Если вы используете Media3, вы можете использовать
Util.getAudioTrackChannelConfig(int channelCount)для преобразования количества каналов в маску каналов.Кроме того, если вы настроили декодер на вывод многоканального PCM, установите кодировку на
AudioFormat.ENCODING_PCM_16BITКотлин
val audioFormat = AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1) .build()
Java
AudioFormat audioFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1) .build();
Тестирование пространственного звука
Убедитесь, что на вашем тестовом устройстве включен пространственный звук:
- Для проводных гарнитур перейдите в «Системные настройки» > «Звук и вибрация» > «Пространственный звук» .
- Для беспроводных гарнитур перейдите в «Системные настройки» > «Подключенные устройства» > значок шестеренки вашего беспроводного устройства > «Пространственный звук» .
Чтобы проверить доступность пространственного звука для текущей маршрутизации, выполните команду adb shell dumpsys audio на вашем устройстве. Во время воспроизведения в выводе должны отобразиться следующие параметры:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)