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 das Geräusch eines Autos beispielsweise hinter dem Nutzer stecken, sich vorwärts bewegen und in die Ferne steigen. In einem Videochat können Stimmen voneinander getrennt und um den Nutzer herum platziert werden, damit die Sprecher leichter zu identifizieren 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.
Abfrage von Funktionen
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, musst du prüfen, ob die folgenden vier 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 dem aktuellen Audioausgaberouting 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 verwendet ein AudioAttributes
und ein AudioFormat
, die beide weiter unten ausführlicher beschrieben werden.
AudioAttributes
Ein AudioAttributes
-Objekt beschreibt die Nutzung eines Audiostreams (z. B. Audio eines Spiels oder Standardmedien) zusammen mit seinem Wiedergabeverhalten und seinem Inhaltstyp.
Verwende beim Aufrufen von canBeSpatialized()
dieselbe AudioAttributes
-Instanz wie für deine Player
festgelegt. Wenn Sie beispielsweise die Jetpack Media3-Bibliothek verwenden und AudioAttributes
nicht angepasst haben, verwenden Sie AudioAttributes.DEFAULT
.
Spatial Audio deaktivieren
Wenn du angeben möchtest, dass deine Inhalte bereits räumlich ausgerichtet wurden, rufe setIsContentSpatialized(true)
auf, damit das Audio nicht doppelt verarbeitet wird. Alternativ können Sie das Raumisierungsverhalten so anpassen, dass die Verräumlichung vollständig deaktiviert wird. Dazu rufen Sie 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. Weitere Informationen zu bestimmten Werten, die Sie verwenden sollten, finden Sie im Abschnitt Standardmäßiges Raumisierungsverhalten.
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 wissen möchten, ob ein Kopf-Tracker verfügbar ist, 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 die Verbindung trennt, gibt der onSpatializerAvailableChanged
-Callback an, ob der Spatializer-Effekt für das neue Audioausgaberouting verfügbar ist. An dieser Stelle können Sie die Titelauswahllogik Ihres Spielers aktualisieren, damit sie den neuen Funktionen des Geräts entspricht. Weitere Informationen zur Trackauswahl von ExoPlayer finden Sie im Abschnitt ExoPlayer und Spatial 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 eine Mehrkanal-Audiospur und eine Stereospur enthält und das Gerät die Wiedergabe beider Elemente unterstützt, wählt ExoPlayer den Mehrkanalspur-Track aus. Weitere Informationen dazu, wie Sie dieses Verhalten anpassen können, finden Sie unter Auswahl von Audiospuren.
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. ExoPlayer wählt standardmäßig Audiotracks aus, die in Bezug auf MIME-Typ (Codierung), Kanalanzahl und Abtastrate mit dem ursprünglichen Track identisch sind.
Parameter für die Titelauswahl ändern
Mit Player.setTrackSelectionParameters()
kannst du die Parameter für die Titelauswahl von ExoPlayer ändern.
Ebenso können Sie 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() );
Wenn Sie die Parameter für die Titelauswahl während der Wiedergabe ändern, kann dies zu einer Unterbrechung der Wiedergabe führen. Weitere Informationen zur Feinabstimmung der Titelauswahlparameter des Players sind im Abschnitt zur Titelauswahl der ExoPlayer-Dokumentation verfügbar.
Standardverhalten bei der Spatialisierung
Das Standardverhalten der Verräumlichung in Android umfasst die folgenden Verhaltensweisen, 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 Praxisbeispiel findest du im ExoPlayer-
MediaCodecAudioRenderer.java
. 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 Sie Media3 verwenden, können Sie 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 Sie prüfen möchten, ob Spatial Audio für das aktuelle Routing verfügbar ist, führen Sie auf Ihrem Gerät den Befehl adb shell dumpsys audio
aus. Während der Wiedergabe sollten in der Ausgabe die folgenden Parameter angezeigt werden:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)