Spatial Audio ist ein immersives Audioerlebnis, bei dem die Nutzer in den Mittelpunkt der Handlung rücken und Inhalte so realistisch klingen. Der Klang wird räumlich verarbeitet, um einen Effekt mit mehreren Lautsprechern zu erzeugen, ähnlich wie bei einem Surround-Sound-Setup, jedoch über Kopfhörer.
In einem Film könnte beispielsweise das Geräusch eines Autos hinter dem Nutzer rauskommen, sich vorwärts bewegen und in die Ferne gehen. In einem Videochat können die Stimmen getrennt und um den Nutzer herum platziert werden, damit die Sprecher leichter identifiziert werden können.
Wenn für deine Inhalte ein unterstütztes Audioformat verwendet wird, kannst du deiner App ab Android 13 (API-Level 33) Spatial Audio hinzufügen.
Abfrage von Funktionen
Verwenden Sie die Klasse Spatializer
, um die Raumisierungsfunktionen 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 Spatializer
abgerufen hast, prüfe, ob die vier Bedingungen erfüllt sein müssen, damit das Gerät Spatial Audio ausgeben kann:
Kriterien | Prüfen |
---|---|
Unterstützt das Gerät die Verräumlichung? |
getImmersiveAudioLevel() ist nicht SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
Ist Verräumlichung verfügbar? Die Verfügbarkeit hängt von der Kompatibilität mit dem aktuellen Audioausgaberouting ab. |
isAvailable() ist true |
Ist die Raumisierung aktiviert? | isEnabled() ist true |
Kann eine Audiotracks mit den angegebenen Parametern räumlich erstellt werden? | canBeSpatialized() ist true |
Diese Bedingungen werden möglicherweise nicht erfüllt, z. B. wenn die Raumisierung für den aktuellen Audiotrack nicht verfügbar oder auf dem Audioausgabegerät vollständig deaktiviert ist.
Erfassung von Kopfbewegungen
Mit unterstützten Headsets kann die Plattform die Raumisierung der Audiodaten an die Kopfposition des Nutzers anpassen. Wenn Sie prüfen möchten, ob für das aktuelle Audioausgabe-Routing ein Kopf-Tracker verfügbar ist, rufen Sie isHeadTrackerAvailable()
auf.
Kompatible Inhalte
Spatializer.canBeSpatialized()
gibt an, ob Audio mit den angegebenen Attributen mit dem aktuellen Routing des Ausgabegeräts räumlich dargestellt 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.
Verwenden Sie beim Aufrufen von canBeSpatialized()
dieselbe AudioAttributes
-Instanz, die für Player
festgelegt ist. Wenn Sie beispielsweise die Jetpack Media3-Bibliothek verwenden und AudioAttributes
nicht angepasst haben, verwenden Sie AudioAttributes.DEFAULT
.
Spatial Audio deaktivieren
Wenn Sie angeben möchten, dass der Inhalt bereits verräumt wurde, rufen Sie setIsContentSpatialized(true)
auf, damit die Audiodaten nicht doppelt verarbeitet werden. 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 beschreibt Details zum Format und der Kanalkonfiguration eines Audiotracks.
Legen Sie bei der Instanziierung von AudioFormat
für die Übergabe an canBeSpatialized()
die Codierung auf dasselbe Ausgabeformat fest, das vom Decodierer erwartet wird. Du solltest außerdem eine Kanalmaske festlegen, die der Kanalkonfiguration deines Inhalts entspricht. Weitere Informationen zu bestimmten Werten, die Sie verwenden sollten, finden Sie im Abschnitt Standardmäßiges Raumisierungsverhalten.
Änderungen an Spatializer
überwachen
Wenn Sie auf Änderungen am Status des Spatializer
s warten möchten, können Sie mit Spatializer.addOnSpatializerStateChangedListener()
einen Listener hinzufügen.
Wenn Sie auf Änderungen an der Verfügbarkeit eines Kopf-Trackers warten möchten, rufen Sie Spatializer.addOnHeadTrackerAvailableListener()
auf.
Dies 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 onSpatializerAvailableChanged
-Callback an, ob der Spatializer-Effekt für das neue Audioausgabe-Routing 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
Mit den jüngsten Releases von ExoPlayer ist die Einführung von Spatial Audio noch einfacher. Wenn Sie die eigenständige ExoPlayer-Bibliothek (Paketname com.google.android.exoplayer2
) verwenden, wird die Plattform in Version 2.17 für die Ausgabe von Spatial Audio konfiguriert und 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, enthalten Versionen 1.0.0-beta01
und höher dieselben Updates.
Nachdem Sie die ExoPlayer-Abhängigkeit auf die neueste Version aktualisiert haben, muss Ihre App nur Inhalte enthalten, die verräumt 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-Audiotrack aus. Ist dies nicht der Fall, wählt ExoPlayer stattdessen eine Stereospur aus.
Wenn sich die Spatializer
-Eigenschaften ändern, löst ExoPlayer eine neue Trackauswahl aus, um einen Audiotrack auszuwählen, der den aktuellen Eigenschaften entspricht. Diese neue Titelauswahl kann zu einem kurzen Puffer führen.
Um Einschränkungen für die Anzahl der Audiokanäle zu deaktivieren, 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() );
Auf ähnliche Weise können Sie die Parameter einer vorhandenen Trackauswahl aktualisieren, um Einschränkungen für die Anzahl der Audiokanäle so 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 anfangs den Track mit den meisten Kanälen aus und kann auf dem Gerät wiedergegeben werden. 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 die Einschränkungen der Audiokanalzahl von ExoPlayer deaktiviert sind, wählt ExoPlayer nicht automatisch einen Audiotrack aus, der den Eigenschaften des Spatializers des Geräts entspricht. Stattdessen können Sie die Trackauswahllogik von ExoPlayer anpassen, indem Sie vor oder während der Wiedergabe Trackauswahlparameter festlegen. 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
Verwenden Sie Player.setTrackSelectionParameters()
, um die Trackauswahlparameter des ExoPlayers zu ändern.
Ebenso können Sie die aktuellen Parameter von ExoPlayer mit Player.getTrackSelectionParameters()
abrufen.
So kannst du beispielsweise einen Stereo-Audiotrack während der Wiedergabe auswählen:
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 für Verräumlichung
Das standardmäßige Verräumlichungsverhalten in Android umfasst die folgenden Verhaltensweisen, die von OEMs angepasst werden können:
Nur Multi-Channel-Inhalte werden räumlich dargestellt, keine Stereoinhalte. Wenn Sie ExoPlayer nicht verwenden, müssen Sie abhängig vom Format Ihres Mehrkanal-Audioinhalts möglicherweise die maximale Anzahl von Kanälen konfigurieren, die von einem Audiodecoder für eine große Anzahl ausgegeben werden können. Dadurch wird sichergestellt, dass der Audiodecoder mehrkanalige PCM für die Verräumlichkeit der Plattform ausgibt.
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
. Wie Sie die Spatialisierung unabhängig von der OEM-Anpassung selbst deaktivieren, erfahren Sie unter Spatial Audio deaktivieren.AudioAttributes
: Audioinhalte können für die Verräumlichung verwendet werden, wennusage
aufUSAGE_MEDIA
oderUSAGE_GAME
gesetzt ist.AudioFormat
: Verwende eine Kanalmaske, die mindestens dieAudioFormat.CHANNEL_OUT_QUAD
-Kanäle (vorne links, vorne rechts, hinten links und hinten rechts) enthält, damit die Audioinhalte für die Verräumlichung infrage kommen. Im folgenden Beispiel verwenden wirAudioFormat.CHANNEL_OUT_5POINT1
für einen 5.1-Audiospur. Für Stereo-Audiospuren verwendest duAudioFormat.CHANNEL_OUT_STEREO
.Wenn Sie Media3 verwenden, können Sie mit
Util.getAudioTrackChannelConfig(int channelCount)
eine Kanalanzahl in eine Kanalmaske umwandeln.Legen Sie außerdem die Codierung auf
AudioFormat.ENCODING_PCM_16BIT
fest, 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 rufen Sie Systemeinstellungen > Ton & Vibration > Spatial Audio auf.
- Rufe bei kabellosen Headsets Systemeinstellungen > Verbundene Geräte > Zahnradsymbol für 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 die Wiedergabe aktiv ist, sollten die folgenden Parameter in der Ausgabe zu sehen sein:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)