Пространственное звучание — это эффект полного погружения, который помещает пользователей в центр событий, делая ваш контент более реалистичным. Звук «пространственно» «пространственно» преобразуется для создания эффекта многоканального звучания, аналогичного системе объемного звучания, но через наушники.
Например, в фильме звук автомобиля может начинаться позади пользователя, распространяться вперед и затихать вдали. В видеочате голоса можно разделить и расположить вокруг пользователя, что облегчает идентификацию говорящих.
Если ваш контент использует поддерживаемый аудиоформат, вы можете добавить пространственное звучание в свое приложение, начиная с 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() .
This can be useful if you want to adjust your track selection during playback using the listener's callbacks. For example, when a user connects or disconnects their headset from the device, the onSpatializerAvailableChanged callback indicates whether the spatializer effect is available for the new audio output routing. At this point, you may consider updating your player's track selection logic to match the device's new capabilities. For details on ExoPlayer's track selection behavior, refer to the ExoPlayer and spatial audio section.
ExoPlayer и пространственное аудио
Recent releases of ExoPlayer make it easier to adopt spatial audio. If you use the standalone ExoPlayer library (package name com.google.android.exoplayer2 ), version 2.17 configures the platform to output spatialized audio, and version 2.18 introduces audio channel count constraints . If you use the ExoPlayer module from the Media3 library, (package name androidx.media3 ), versions 1.0.0-beta01 and newer include these same updates.
После обновления зависимости 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() );
With audio channel count constraints disabled, if content has multiple audio tracks, ExoPlayer initially selects the track that has the highest number of channels and is playable from the device. For example, if the content contains a multi-channel audio track and a stereo audio track, and the device supports playback of both, ExoPlayer selects the multi-channel track. See the Audio track selection for details on how to customize this behavior.
выбор аудиодорожки
When ExoPlayer's audio channel count constraints behavior is disabled, ExoPlayer does not automatically select an audio track that matches the properties of the device's spatializer. Instead, you can customize ExoPlayer's track selection logic by setting track selection parameters before or during playback. By default, ExoPlayer selects audio tracks that are the same as the initial track with regards to MIME type (encoding), channel count, and sample rate.
Изменение параметров выбора трассы
Чтобы изменить параметры выбора трека в 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)