Spatial Audio ist ein eindrucksvolles Audioerlebnis, das Nutzern das Gefühl vermittelt, als wären sie mitten im Geschehen, und Inhalte viel realistischer klingen lässt. Der von Pixel Buds Pro erzeugte räumliche Klang scheint dabei aus mehreren Lautsprechern zu kommen, ähnlich wie bei einem Surround-Soundsystem, aber über Kopfhörer.
In einem Film könnte der Ton eines Autos beispielsweise hinter dem Nutzer beginnen, sich nach vorne bewegen und in der Ferne verstommen. In einem Videochat können Stimmen voneinander getrennt und um den Nutzer herum platziert werden, damit die Sprecher leichter zu erkennen sind.
Wenn Sie für Ihre Inhalte ein unterstütztes Audioformat verwenden, können Sie Ihrer App ab Android 13 (API-Level 33) räumlichen Audio hinzufügen.
Funktionen abfragen
Verwenden Sie die Klasse Spatializer
, um die Spatialisierungsfunktionen und das Verhalten des Geräts abzufragen. Rufen Sie zuerst eine Instanz der Spatializer
aus der AudioManager
ab:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Nachdem du die Spatializer
erhalten hast, prüfe, ob die vier folgenden Bedingungen erfüllt sind, damit das Gerät räumliches Audio ausgeben kann:
Kriterien | Prüfen |
---|---|
Unterstützt das Gerät die Spatial Audio-Funktion? |
getImmersiveAudioLevel() ist nicht SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
Ist die Spatialisierung verfügbar? Die Verfügbarkeit hängt von der Kompatibilität mit der aktuellen Audioausgabe ab. |
isAvailable() ist true |
Ist die räumliche Darstellung aktiviert? | isEnabled() ist true |
Kann ein Audiotrack mit den angegebenen Parametern räumlich lokalisiert werden? | canBeSpatialized() ist true |
Diese Bedingungen sind möglicherweise nicht erfüllt, wenn die Spatialisierung beispielsweise für den aktuellen Audiotrack nicht verfügbar ist oder auf dem Audioausgabegerät vollständig deaktiviert ist.
Erfassung von Kopfbewegungen
Bei unterstützten Headsets kann die Plattform die Raumklangwiedergabe anhand der Kopfposition des Nutzers anpassen. Wenn Sie prüfen möchten, ob für die aktuelle Audioausgabe ein Kopf-Tracker verfügbar ist, rufen Sie isHeadTrackerAvailable()
auf.
Kompatible Inhalte
Spatializer.canBeSpatialized()
gibt an, ob Audio mit den angegebenen Eigenschaften mit der aktuellen Routing-Ausgabe für das Gerät räumlich lokalisiert werden kann. Diese Methode nimmt ein AudioAttributes
und ein AudioFormat
entgegen, die unten genauer beschrieben werden.
AudioAttributes
Ein AudioAttributes
-Objekt beschreibt die Nutzung eines Audiostreams (z. B. Game Audio oder Standardmedien) sowie die Wiedergabeeigenschaften und den Inhaltstyp.
Verwende beim Aufrufen von canBeSpatialized()
dieselbe AudioAttributes
-Instanz wie für deine Player
festgelegt. Wenn du beispielsweise die Jetpack Media3-Bibliothek verwendest und die AudioAttributes
nicht angepasst hast, verwende AudioAttributes.DEFAULT
.
Spatial Audio deaktivieren
Wenn du angeben möchtest, dass deine Inhalte bereits räumlich lokalisiert wurden, rufe setIsContentSpatialized(true)
auf, damit das Audio nicht doppelt verarbeitet wird. Alternativ kannst du das Spatialisierungsverhalten anpassen, um die Spatialisierung vollständig zu deaktivieren. Rufe dazu setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
auf.
AudioFormat
Ein AudioFormat
-Objekt enthält Details zum Format und zur Kanalkonfiguration eines Audiotracks.
Wenn du AudioFormat
instanzierst, um sie an canBeSpatialized()
zu übergeben, muss die Codierung mit dem vom Decoder erwarteten Ausgabeformat übereinstimmen. Außerdem solltest du eine Kanalmaske festlegen, die der Kanalkonfiguration deiner Inhalte entspricht. Im Abschnitt Standardverhalten für die Spatialisierung findest du Informationen zu den zu verwendenden Werten.
Auf Änderungen an Spatializer
achten
Wenn Sie auf Änderungen des Status von Spatializer
reagieren möchten, können Sie einen Listener mit Spatializer.addOnSpatializerStateChangedListener()
hinzufügen.
Wenn Sie Änderungen an der Verfügbarkeit eines Kopf-Trackers beobachten möchten, rufen Sie Spatializer.addOnHeadTrackerAvailableListener()
auf.
Das kann nützlich sein, wenn du die Titelauswahl während der Wiedergabe mithilfe der Callbacks des Listeners anpassen möchtest. Wenn ein Nutzer beispielsweise sein Headset mit dem Gerät verbindet oder trennt, gibt der onSpatializerAvailableChanged
-Callback an, ob der Spatializer-Effekt für die neue Audioausgabe-Weiterleitung verfügbar ist. An dieser Stelle kannst du die Logik für die Titelauswahl deines Players an die neuen Funktionen des Geräts anpassen. Weitere Informationen zum Verhalten der Titelauswahl von ExoPlayer findest du im Abschnitt ExoPlayer und räumliches Audio.
ExoPlayer und Spatial Audio
Die neuesten Versionen von ExoPlayer erleichtern die Nutzung von Spatial Audio. Wenn du die eigenständige ExoPlayer-Bibliothek (Paketname com.google.android.exoplayer2
) verwendest, wird die Plattform in Version 2.17 für die Ausgabe von räumlichem Audio konfiguriert. In Version 2.18 werden Einschränkungen für die Anzahl der Audiokanäle eingeführt.
Wenn du das ExoPlayer-Modul aus der Media3-Bibliothek (Paketname androidx.media3
) verwendest, sind diese Updates in den Versionen 1.0.0-beta01
und höher enthalten.
Nachdem du die ExoPlayer-Abhängigkeit auf die neueste Version aktualisiert hast, muss deine App nur noch Inhalte enthalten, die lokalisiert werden können.
Einschränkungen bei der Anzahl der Audiokanäle
Wenn alle vier Bedingungen für Spatial Audio erfüllt sind, wählt ExoPlayer einen Audiotrack mit mehreren Kanälen aus. Andernfalls wählt ExoPlayer stattdessen einen Stereotrack aus.
Wenn sich die Spatializer
-Properties ändern, löst ExoPlayer eine neue Titelauswahl aus, um einen Audiotrack auszuwählen, der den aktuellen Properties entspricht. Beachte, dass es bei der neuen Titelauswahl zu einer kurzen Pufferung kommen kann.
Wenn du die Einschränkungen bei der Anzahl der Audiokanäle deaktivieren möchtest, musst du die Parameter für die Titelauswahl im Player wie unten gezeigt festlegen:
Kotlin
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Ebenso kannst du die Parameter einer vorhandenen Titelauswahl aktualisieren, um Einschränkungen bei der Anzahl der Audiokanäle zu deaktivieren. Gehe dazu so vor:
Kotlin
val trackSelector = DefaultTrackSelector(context) ... trackSelector.parameters = trackSelector.buildUponParameters() .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context); ... trackSelector.setParameters( trackSelector .buildUponParameters() .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Wenn die Einschränkungen für die Anzahl der Audiokanäle deaktiviert sind und Inhalte mehrere Audiotracks haben, wählt ExoPlayer zuerst den Track mit der höchsten Anzahl von Kanälen aus, der auf dem Gerät wiedergegeben werden kann. Wenn der Inhalt beispielsweise einen Mehrkanal-Audiotrack und einen Stereo-Audiotrack enthält und das Gerät die Wiedergabe beider unterstützt, wählt ExoPlayer den Mehrkanal-Track aus. Weitere Informationen zum Anpassen dieses Verhaltens findest du unter Audiotrackauswahl.
Auswahl des Audiotracks
Wenn das Verhalten der Einschränkungen für die Anzahl der Audiokanäle von ExoPlayer deaktiviert ist, wählt ExoPlayer nicht automatisch einen Audiotrack aus, der den Eigenschaften des Spatializers des Geräts entspricht. Stattdessen kannst du die Logik der Titelauswahl von ExoPlayer anpassen, indem du vor oder während der Wiedergabe Parameter für die Titelauswahl festlegst. Standardmäßig wählt ExoPlayer Audiotracks aus, die mit dem ursprünglichen Track hinsichtlich MIME-Typ (Codierung), Kanalanzahl und Abtastrate übereinstimmen.
Parameter für die Titelauswahl ändern
Mit Player.setTrackSelectionParameters()
kannst du die Parameter für die Titelauswahl von ExoPlayer ändern.
Ebenso kannst du die aktuellen Parameter von ExoPlayer mit Player.getTrackSelectionParameters()
abrufen.
So wählst du beispielsweise während der Wiedergabe einen Stereo-Audiotrack aus:
Kotlin
exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters .buildUpon() .setMaxAudioChannelCount(2) .build()
Java
exoPlayer.setTrackSelectionParameters( exoPlayer.getTrackSelectionParameters() .buildUpon() .setMaxAudioChannelCount(2) .build() );
Hinweis: Wenn Sie die Parameter für die Titelauswahl während der Wiedergabe ändern, kann es zu Unterbrechungen kommen. Weitere Informationen zum Optimieren der Parameter für die Titelauswahl des Players findest du im Abschnitt Titelauswahl der ExoPlayer-Dokumentation.
Standardverhalten bei der Spatialisierung
Das Standardverhalten der Spatialisierung unter Android umfasst die folgenden Funktionen, die von OEMs angepasst werden können:
Nur Mehrkanalinhalte werden räumlich dargestellt, keine Stereoinhalte. Wenn du ExoPlayer nicht verwendest, musst du je nach Format deiner mehrkanaligen Audioinhalte möglicherweise die maximale Anzahl von Kanälen konfigurieren, die von einem Audiodecoder ausgegeben werden können. So wird sichergestellt, dass der Audiodecoder PCM mit mehreren Kanälen für die Plattform ausgibt, um eine räumliche Audiowiedergabe zu ermöglichen.
Kotlin
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);
Ein Beispiel in der Praxis findest du in der
MediaCodecAudioRenderer.java
von ExoPlayer. Informationen zum Deaktivieren der Raumorientierung unabhängig von der OEM-Anpassung finden Sie unter Spatial Audio deaktivieren.AudioAttributes
: Audio kann für die Spatialisierung verwendet werden, wennusage
aufUSAGE_MEDIA
oderUSAGE_GAME
festgelegt ist.AudioFormat
: Verwenden Sie eine Kanalmaske, die mindestens dieAudioFormat.CHANNEL_OUT_QUAD
-Kanäle (vorne links, vorne rechts, hinten links und hinten rechts) enthält, damit das Audiomaterial für die Spatialisierung infrage kommt. Im folgenden Beispiel wirdAudioFormat.CHANNEL_OUT_5POINT1
für einen 5.1-Audiotrack verwendet. Verwenden Sie für einen Stereo-AudiotrackAudioFormat.CHANNEL_OUT_STEREO
.Wenn du Media3 verwendest, kannst du mit
Util.getAudioTrackChannelConfig(int channelCount)
eine Kanalanzahl in eine Kanalmaske umwandeln.Lege außerdem
AudioFormat.ENCODING_PCM_16BIT
als Codierung fest, wenn du den Decoder so konfiguriert hast, dass er PCM mit mehreren Kanälen ausgibt.Kotlin
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();
Spatial Audio testen
Achte darauf, dass Spatial Audio auf deinem Testgerät aktiviert ist:
- Bei kabelgebundenen Headsets rufen Sie Systemeinstellungen > Ton und Vibration > Raumaudio auf.
- Bei kabellosen Headsets rufen Sie Systemeinstellungen > Verbundene Geräte > Zahnradsymbol für Ihr kabelloses Gerät > Spatial Audio auf.
Wenn du prüfen möchtest, ob Spatial Audio für die aktuelle Weiterleitung verfügbar ist, führe den Befehl adb shell dumpsys audio
auf deinem Gerät aus. Während der Wiedergabe sollten in der Ausgabe die folgenden Parameter angezeigt werden:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)