Spatial Audio ist ein eindrucksvolles Audioerlebnis, das Nutzern das Gefühl vermittelt, mitten im Geschehen zu sein, und Inhalte besonders realistisch klingen lässt. Der entstehende Raumklang wirkt, als würde der Sound aus mehreren Lautsprechern kommen, ähnlich wie bei einem Surround-Soundsystem, aber über Kopfhörer.
In einem Film kann beispielsweise das Geräusch eines Autos hinter dem Nutzer beginnen, sich nach vorne bewegen und in der Ferne verhallen. In einem Videoanruf können Stimmen getrennt und um den Nutzer herum platziert werden, damit er die Sprecher leichter identifizieren kann.
Wenn deine Inhalte ein unterstütztes Audioformat verwenden, kannst du deiner App ab Android 13 (API-Level 33) Spatial Audio hinzufügen.
Funktionen abfragen
Verwende die Klasse Spatializer, um die Spatial Audio-Funktionen und das Verhalten des Geräts abzufragen. Rufen Sie zuerst eine Instanz von Spatializer aus dem AudioManager ab:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Nachdem du die Spatializer erhalten hast, prüfe, ob die vier Bedingungen erfüllt sind, die für die Ausgabe von Spatial Audio auf dem Gerät erfüllt sein müssen:
| Kriterien | Scheck |
|---|---|
| Unterstützt das Gerät die Spatialisierung? |
getImmersiveAudioLevel() ist nicht SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
| Ist die Verräumlichung verfügbar? Die Verfügbarkeit hängt von der Kompatibilität mit dem aktuellen Audioausgabe-Routing ab. |
isAvailable() ist true |
| Ist die räumliche Darstellung 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 Verräumlichung für den aktuellen Audiotrack nicht verfügbar oder auf dem Audioausgabegerät vollständig deaktiviert ist.
Erfassung von Kopfbewegungen
Bei unterstützten Headsets kann die Plattform die Räumlichkeit des Audiosignals an die Kopfposition des Nutzers anpassen. Mit isHeadTrackerAvailable() können Sie prüfen, ob für das aktuelle Audioausgabe-Routing eine Erfassung von Kopfbewegungen verfügbar ist.
Kompatible Inhalte
Spatializer.canBeSpatialized() gibt an, ob Audio mit den angegebenen Eigenschaften mit dem aktuellen Ausgabegeräte-Routing räumlich wiedergegeben werden kann. Diese Methode verwendet ein AudioAttributes und ein AudioFormat, die beide unten ausführlicher beschrieben werden.
AudioAttributes
Ein AudioAttributes-Objekt beschreibt die Nutzung eines Audiostreams (z. B. Spielaudio oder Standardmedien) sowie sein Wiedergabeverhalten und seinen Inhaltstyp.
Verwenden Sie beim Aufrufen von canBeSpatialized() dieselbe AudioAttributes-Instanz, die für Player festgelegt ist. Wenn Sie beispielsweise die Jetpack Media3-Bibliothek verwenden und die AudioAttributes nicht angepasst haben, verwenden Sie AudioAttributes.DEFAULT.
Spatial Audio deaktivieren
Wenn du angeben möchtest, dass deine Inhalte bereits räumlich wiedergegeben wurden, rufe setIsContentSpatialized(true) auf, damit die Audioinhalte nicht doppelt verarbeitet werden. Alternativ können Sie das Spatialization-Verhalten anpassen, um die Spatialization vollständig zu deaktivieren, indem Sie setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) aufrufen.
AudioFormat
Ein AudioFormat-Objekt beschreibt Details zum Format und zur Kanalkonfiguration eines Audiotracks.
Wenn Sie die AudioFormat instanziieren, die an canBeSpatialized() übergeben werden soll, legen Sie die Codierung auf das Ausgabeformat fest, das vom Decoder erwartet wird. Außerdem solltest du eine Kanalmaske festlegen, die der Kanalkonfiguration deiner Inhalte entspricht. Informationen zu den zu verwendenden Werten findest du im Abschnitt Standardverhalten für die Spatialization.
Änderungen am Spatializer überwachen
Wenn Sie auf Änderungen des Status von Spatializer reagieren möchten, können Sie mit Spatializer.addOnSpatializerStateChangedListener() einen Listener hinzufügen.
Wenn du auf Änderungen bei der Verfügbarkeit der Erfassung von Kopfbewegungen reagieren möchtest, rufe Spatializer.addOnHeadTrackerAvailableListener() auf.
Das kann nützlich sein, wenn Sie die Titelauswahl während der Wiedergabe mithilfe der Callbacks des Listeners anpassen möchten. Wenn ein Nutzer beispielsweise sein Headset mit dem Gerät verbindet oder die Verbindung trennt, gibt der Callback onSpatializerAvailableChanged an, ob der Spatializer-Effekt für das neue Audioausgabe-Routing verfügbar ist. An dieser Stelle kannst du die Logik für die Trackauswahl deines Players aktualisieren, um sie an die neuen Funktionen des Geräts anzupassen. Weitere Informationen zum Verhalten der Trackauswahl von ExoPlayer finden Sie im Abschnitt ExoPlayer und Spatial Audio.
ExoPlayer und Spatial Audio
In neueren Versionen von ExoPlayer ist es einfacher, Spatial Audio zu verwenden. Wenn Sie die eigenständige ExoPlayer-Bibliothek (Paketname com.google.android.exoplayer2) verwenden, wird die Plattform in Version 2.17 so konfiguriert, dass Spatial Audio ausgegeben wird. In Version 2.18 werden Einschränkungen für die Anzahl der Audiokanäle 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 du die ExoPlayer-Abhängigkeit auf die neueste Version aktualisiert hast, muss deine 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 Audiotrack mit mehreren Kanälen aus. Andernfalls wählt ExoPlayer stattdessen einen Stereotrack aus.
Wenn sich die Spatializer-Eigenschaften ändern, löst ExoPlayer eine neue Trackauswahl aus, um einen Audiotrack auszuwählen, der den aktuellen Eigenschaften entspricht. Beachten Sie, dass diese neue Trackauswahl zu einer kurzen Zwischenspeicherung führen kann.
Wenn Sie die Einschränkungen für die Anzahl der Audiokanäle deaktivieren möchten, legen Sie die Parameter für die Trackauswahl 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 auch die Parameter einer vorhandenen Spurauswahl aktualisieren, um die Einschränkungen für die Anzahl der Audiokanäle zu deaktivieren:
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 abgespielt 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 finden Sie unter Audiotracks auswählen.
Audiotrack-Auswahl
Wenn das Verhalten von ExoPlayer für Einschränkungen der Audiokanäle 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 Trackauswahl von ExoPlayer anpassen, indem Sie vor oder während der Wiedergabe Parameter für die Trackauswahl festlegen. Standardmäßig wählt ExoPlayer Audiotracks aus, die in Bezug auf MIME-Typ (Codierung), Kanalanzahl und Abtastrate mit dem ursprünglichen Track übereinstimmen.
Parameter für die Trackauswahl ändern
Verwenden Sie Player.setTrackSelectionParameters(), um die Parameter für die Titelauswahl des ExoPlayers 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() );
Beachte, dass das Ändern der Parameter für die Trackauswahl während der Wiedergabe zu einer Unterbrechung der Wiedergabe führen kann. Weitere Informationen zum Optimieren der Parameter für die Titelauswahl des Players finden Sie im Abschnitt Titelauswahl der ExoPlayer-Dokumentation.
Standardverhalten für die Verräumlichung
Das standardmäßige Spatial Audio-Verhalten in Android umfasst die folgenden Verhaltensweisen, die von OEMs angepasst werden können:
Nur Mehrkanal-Inhalte werden räumlich wiedergegeben, keine Stereo-Inhalte. Wenn du ExoPlayer nicht verwendest, musst du je nach Format deiner Mehrkanal-Audioinhalte möglicherweise die maximale Anzahl von Kanälen, die von einem Audiodecoder ausgegeben werden können, auf eine große Zahl festlegen. So wird sichergestellt, dass der Audiodecoder mehrkanaliges PCM ausgibt, das von der Plattform räumlich dargestellt werden 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 für die Verwendung finden Sie in der
MediaCodecAudioRenderer.javavon ExoPlayer. Wenn du die räumliche Darstellung unabhängig von der OEM-Anpassung selbst deaktivieren möchtest, findest du weitere Informationen unter Spatial Audio deaktivieren.AudioAttributes: Audio ist für Spatial Audio geeignet, wennusageentweder aufUSAGE_MEDIAoderUSAGE_GAMEfestgelegt ist.AudioFormat: Verwende 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_5POINT1für einen 5.1-Audiotrack. 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.Setze außerdem die Codierung auf
AudioFormat.ENCODING_PCM_16BIT, wenn du den Decoder so konfiguriert hast, dass er Mehrkanal-PCM 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: Systemeinstellungen > Ton & Vibration > Spatial Audio.
- Bei kabellosen Kopfhörern: Systemeinstellungen > Verbundene Geräte > Zahnradsymbol für dein kabelloses Gerät > Spatial Audio.
Führe den Befehl adb shell dumpsys audio auf deinem Gerät aus, um die Verfügbarkeit von Spatial Audio für das aktuelle Routing zu prüfen. Während der Wiedergabe sollten die folgenden Parameter in der Ausgabe angezeigt werden:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)