Spatial Audio ist ein eindrucksvolles Audioerlebnis, das Ihren Nutzern das Gefühl vermittelt, mitten im Geschehen zu sein, und Ihre Inhalte besonders realistisch 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.
In einem Film kann der Ton eines Autos beispielsweise hinter dem Nutzer beginnen, sich nach vorn bewegen und in der Ferne ausklingen. In einem Videochat können Stimmen getrennt und um den Nutzer herum platziert werden, sodass es einfacher ist, die Sprecher zu identifizieren.
Wenn für Ihre Inhalte ein unterstütztes Audioformat verwendet wird, können Sie ab Android 13 (API‑Level 33) räumliches Audio in Ihre App einfügen.
Funktionen abfragen
Verwenden Sie die Klasse Spatializer
, um die Spatialization-Funktionen und das Verhalten des Geräts abzufragen. Rufen Sie zuerst eine Instanz von Spatializer
aus AudioManager
ab:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Nachdem Sie die Spatializer
erhalten haben, prüfen Sie, ob die vier Bedingungen erfüllt sind, die für die Ausgabe von räumlichem Audio auf dem Gerät gelten:
Kriterien | Prüfen |
---|---|
Unterstützt das Gerät die Räumlichkeit? |
getImmersiveAudioLevel() ist nicht SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
Ist die Räumlichkeit verfügbar? Die Verfügbarkeit von hängt von der Kompatibilität mit dem aktuellen Audioausgaberouting ab. |
isAvailable() ist true |
Ist die Verräumlichung aktiviert? | isEnabled() ist true |
Kann ein Audiotrack mit den angegebenen Parametern räumlich wiedergegeben werden? | canBeSpatialized() ist true |
Diese Bedingungen sind möglicherweise nicht erfüllt, wenn die Räumlichkeit für den aktuellen Audiotrack nicht verfügbar oder auf dem Audioausgabegerät deaktiviert ist.
Erfassung von Kopfbewegungen
Bei unterstützten Headsets kann die Plattform die Räumlichkeit des Audiosignals an die Kopfposition des Nutzers anpassen. Rufen Sie isHeadTrackerAvailable()
auf, um zu prüfen, ob ein Head-Tracker für das aktuelle Audioausgaberouting verfügbar ist.
Kompatible Inhalte
Spatializer.canBeSpatialized()
gibt an, ob Audio mit den angegebenen Eigenschaften mit dem aktuellen Routing des Ausgabegeräts räumlich wiedergegeben werden kann. Diese Methode verwendet ein AudioAttributes
und ein AudioFormat
, die beide unten genauer beschrieben werden.
AudioAttributes
Ein AudioAttributes
-Objekt beschreibt die Verwendung eines Audiostreams (z. B. Spielaudio oder Standardmedien) sowie sein Wiedergabeverhalten und seinen Inhaltstyp.
Verwenden Sie beim Aufrufen von canBeSpatialized()
dieselbe AudioAttributes
-Instanz wie für Ihre Player
. Wenn Sie beispielsweise die Jetpack Media3-Bibliothek verwenden und die AudioAttributes
nicht angepasst haben, verwenden Sie AudioAttributes.DEFAULT
.
Spatial Audio deaktivieren
Wenn Sie angeben möchten, dass Ihre Inhalte bereits räumlich bearbeitet wurden, rufen Sie setIsContentSpatialized(true)
auf, damit der Audioinhalt nicht doppelt verarbeitet wird. Alternativ können Sie das Verhalten der Räumlichkeit anpassen, um die Räumlichkeit vollständig zu deaktivieren, indem Sie setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
aufrufen.
AudioFormat
Ein AudioFormat
-Objekt enthält Details zum Format und zur Channelkonfiguration eines Audiotracks.
Wenn Sie AudioFormat
instanziieren, um es an canBeSpatialized()
zu übergeben, legen Sie die Codierung auf dieselbe Codierung fest, die vom Decoder als Ausgabeformat erwartet wird. Außerdem sollten Sie eine Channel-Maske festlegen, die der Channel-Konfiguration Ihrer Inhalte entspricht. Im Abschnitt Standardverhalten bei der Räumlichkeit finden Sie Informationen zu den zu verwendenden Werten.
Auf Änderungen am Spatializer
reagieren
Wenn Sie Änderungen am Status von Spatializer
erfassen möchten, können Sie mit Spatializer.addOnSpatializerStateChangedListener()
einen Listener hinzufügen.
Wenn Sie Änderungen an der Verfügbarkeit eines Head-Trackers erfassen möchten, rufen Sie Spatializer.addOnHeadTrackerAvailableListener()
auf.
Das kann nützlich sein, wenn Sie die Auswahl der Tracks während der Wiedergabe mithilfe der Listener-Callbacks anpassen möchten. 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 Audioausgabe-Routing verfügbar ist. An dieser Stelle sollten Sie die Logik für die Auswahl der Tracks für Ihren Player an die neuen Funktionen des Geräts anpassen. Weitere Informationen zum Verhalten von ExoPlayer bei der Auswahl von Tracks finden Sie im Abschnitt ExoPlayer und räumliches Audio.
ExoPlayer und Spatial Audio
In den letzten Versionen von ExoPlayer wurde die Einführung von Spatial Audio vereinfacht. Wenn Sie die eigenständige ExoPlayer-Bibliothek (Paketname com.google.android.exoplayer2
) verwenden, wird mit Version 2.17 die Plattform für die Ausgabe von räumlichem Audio konfiguriert und mit Version 2.18 werden Einschränkungen für die Anzahl der Audiochannels eingeführt.
Wenn Sie das ExoPlayer-Modul aus der Media3-Bibliothek (Paketname androidx.media3
) verwenden, sind diese Updates in den Versionen 1.0.0-beta01
und höher enthalten.
Nachdem Sie Ihre ExoPlayer-Abhängigkeit auf die aktuelle Version aktualisiert haben, muss Ihre App nur noch Inhalte enthalten, die räumlich wiedergegeben werden können.
Einschränkungen für die Anzahl der Audiokanäle
Wenn alle vier Bedingungen für Spatial Audio erfüllt sind, wählt ExoPlayer einen Mehrkanal-Audio-Track aus. Andernfalls wählt ExoPlayer einen Stereotrack aus.
Wenn sich die Spatializer
-Eigenschaften ändern, löst ExoPlayer eine neue Titelauswahl aus, um einen Audiotrack auszuwählen, der den aktuellen Eigenschaften entspricht. Hinweis: Durch die neue Auswahl des Tracks kann es zu einer kurzen Unterbrechung der Wiedergabe kommen.
Wenn Sie die Einschränkungen für die Anzahl der Audiochannels deaktivieren möchten, legen Sie die Parameter für die Titelauswahl im Player wie unten gezeigt fest:
Kotlin
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Sie können die Parameter eines vorhandenen Track-Selektors auch so aktualisieren, dass die Einschränkungen für die Anzahl der Audio-Channels deaktiviert werden:
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 Audio-Channels deaktiviert sind und Inhalte mehrere Audio-Tracks haben, wählt ExoPlayer zuerst den Track aus, der die höchste Anzahl von Channels hat und auf dem Gerät wiedergegeben werden kann. Wenn der Inhalt beispielsweise einen Mehrkanal-Audio-Track und einen Stereo-Audio-Track enthält und das Gerät die Wiedergabe beider unterstützt, wählt ExoPlayer den Mehrkanal-Track aus. Weitere Informationen zum Anpassen dieses Verhaltens finden Sie unter Auswahl von Audio-Tracks.
Auswahl des Audiotracks
Wenn das Verhalten von ExoPlayer in Bezug auf Einschränkungen bei der Anzahl der Audio-Channels deaktiviert ist, wählt ExoPlayer nicht automatisch einen Audiotrack aus, der den Eigenschaften des Spatializers des Geräts entspricht. Stattdessen können Sie die Logik für die Auswahl von ExoPlayer-Tracks anpassen, indem Sie vor oder während der Wiedergabe Parameter für die Auswahl von Tracks festlegen. Standardmäßig wählt ExoPlayer Audiotracks aus, die in Bezug auf MIME-Typ (Codierung), Anzahl der Kanäle und Samplerate mit dem ursprünglichen Track übereinstimmen.
Parameter für die Auswahl von Tracks ändern
Verwenden Sie Player.setTrackSelectionParameters()
, um die Parameter für die Auswahl von ExoPlayer-Tracks zu ändern.
Ebenso können Sie die aktuellen Parameter von ExoPlayer mit Player.getTrackSelectionParameters()
abrufen.
So wählen Sie 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 Auswahl des Tracks während der Wiedergabe ändern, kann es zu einer Unterbrechung der Wiedergabe kommen. Weitere Informationen zum Optimieren der Parameter für die Auswahl von Tracks im Player finden Sie in der ExoPlayer-Dokumentation im Abschnitt Track selection (Trackauswahl).
Standardverhalten bei der Räumlichkeit
Das standardmäßige Räumlichkeitsverhalten in Android umfasst die folgenden Verhaltensweisen, die von OEMs angepasst werden können:
Nur Mehrkanal-Inhalte werden räumlich wiedergegeben, nicht Stereo-Inhalte. Wenn Sie ExoPlayer nicht verwenden, müssen Sie je nach Format Ihrer Mehrkanal-Audioinhalte möglicherweise die maximale Anzahl von Kanälen, die von einem Audio-Decoder ausgegeben werden können, auf einen hohen Wert festlegen. So wird sichergestellt, dass der Audio-Decoder Mehrkanal-PCM für die Plattform ausgibt, damit diese den Sound räumlich wiedergeben kann.
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 finden Sie in der
MediaCodecAudioRenderer.java
von ExoPlayer. Informationen zum manuellen Deaktivieren der Räumlichkeit unabhängig von der OEM-Anpassung finden Sie unter Spatial Audio deaktivieren.AudioAttributes
: Audio kann räumlich wiedergegeben werden, wennusage
entweder aufUSAGE_MEDIA
oderUSAGE_GAME
festgelegt ist.AudioFormat
: Verwenden Sie eine Kanalmaske, die mindestens die KanäleAudioFormat.CHANNEL_OUT_QUAD
(vorne links, vorne rechts, hinten links und hinten rechts) enthält, damit die Audiodaten für die Räumlichkeit infrage kommen. Im folgenden Beispiel verwenden wirAudioFormat.CHANNEL_OUT_5POINT1
für einen 5.1-Audiotrack. Verwenden Sie für einen Stereo-Audio-TrackAudioFormat.CHANNEL_OUT_STEREO
.Wenn Sie Media3 verwenden, können Sie mit
Util.getAudioTrackChannelConfig(int channelCount)
eine Kanalanzahl in eine Kanalmaske umwandeln.Stellen Sie außerdem die Codierung auf
AudioFormat.ENCODING_PCM_16BIT
ein, wenn Sie den Decoder für die Ausgabe von Mehrkanal-PCM konfiguriert haben.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 gehen Sie zu Systemeinstellungen > Töne & Vibration > 3D-Audio.
- Bei kabellosen Headsets rufe Systemeinstellungen > Verbundene Geräte > Zahnradsymbol für dein kabelloses Gerät > Spatial Audio auf.
Führe den Befehl adb shell dumpsys audio
auf deinem Gerät aus, um zu prüfen, ob Spatial Audio für das aktuelle Routing verfügbar ist. Während der Wiedergabe sollten in der Ausgabe die folgenden Parameter angezeigt werden:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)