Spatial Audio ist ein eindrucksvolles Audioerlebnis, bei dem der Nutzer in den Mittelpunkt des Geschehens rückt und Inhalte realistischer klingen. Der Klang wird dabei „räumlich“ erzeugt, um einen Effekt mit mehreren Lautsprechern zu erzeugen, ähnlich wie bei einem Surround-Sound-System, allerdings über Kopfhörer.
In einem Film könnte der Ton eines Autos beispielsweise hinter dem Nutzer beginnen, sich vorwärts bewegen und in die Ferne abschweifen. In Videoanrufen können Stimmen getrennt und um den Nutzer herum platziert werden, um die Identifizierung der Sprecher zu erleichtern.
Wenn deine Inhalte ein unterstütztes Audioformat verwenden, kannst du deiner App ab Android 13 (API-Level 33) Spatial Audio hinzufügen.
Funktionen abfragen
Verwenden Sie die Klasse Spatializer
, um die Räumlichkeitsfunktionen 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();
Prüfen Sie nach Erhalt von Spatializer
die vier Bedingungen, die erfüllt sein müssen, damit das Gerät Spatial Audio ausgibt:
Kriterien | Ansehen |
---|---|
Unterstützt das Gerät die Verräumung? |
getImmersiveAudioLevel() ist nicht SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
Ist Räumlichkeit verfügbar? Die Verfügbarkeit hängt von der Kompatibilität mit dem aktuellen Audioausgaberouting ab. |
isAvailable() ist true |
Ist die räumliche Umgebung aktiviert? | isEnabled() ist true |
Kann ein Audiotrack mit den angegebenen Parametern räumlich ermittelt werden? | canBeSpatialized() ist true |
Diese Bedingungen sind möglicherweise nicht erfüllt, z. B. wenn die Räumlichkeit 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 des Audios 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 Audiodaten mit den angegebenen Eigenschaften mit dem aktuellen Routing des Ausgabegeräts räumlich dargestellt werden können. Diese Methode verwendet ein AudioAttributes
- und ein AudioFormat
-Element, die beide unten ausführlicher beschrieben werden.
AudioAttributes
Ein AudioAttributes
-Objekt beschreibt die Nutzung eines Audiostreams (z. B. Spiele-Audio oder Standardmedien) sowie sein Wiedergabeverhalten und Inhaltstyp.
Verwenden Sie beim Aufrufen von canBeSpatialized()
dieselbe AudioAttributes
-Instanz wie für Player
festgelegt. Wenn Sie beispielsweise die Jetpack Media3-Bibliothek verwenden und AudioAttributes
nicht angepasst haben, verwenden Sie AudioAttributes.DEFAULT
.
Spatial Audio wird deaktiviert
Wenn Sie angeben möchten, dass Ihr Inhalt bereits räumlich aufgeteilt wurde, rufen Sie setIsContentSpatialized(true)
auf, damit die Audiodaten nicht doppelt verarbeitet werden. Alternativ können Sie das Räumlichkeitsverhalten anpassen und setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
aufrufen, um die Räumlichkeit zu deaktivieren.
AudioFormat
Ein AudioFormat
-Objekt beschreibt Details zum Format und zur Kanalkonfiguration eines Audiotracks.
Wenn Sie AudioFormat
instanziieren, um es an canBeSpatialized()
zu übergeben, legen Sie für die Codierung dasselbe Ausgabeformat fest, das vom Decodierer erwartet wird. Außerdem solltest du eine Kanalmaske festlegen, die der Kanalkonfiguration deiner Inhalte entspricht. Informationen zu den verwendeten Werten finden Sie im Abschnitt Standardverhalten für die Räumlichkeit.
Änderungen an Spatializer
beobachten
Sie können mit Spatializer.addOnSpatializerStateChangedListener()
einen Listener hinzufügen, um auf Änderungen am Status der Spatializer
zu warten.
In ähnlicher Weise können Sie Spatializer.addOnHeadTrackerAvailableListener()
aufrufen, um auf Änderungen in der Verfügbarkeit eines Head-Trackers zu warten.
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 trennt, gibt der Callback onSpatializerAvailableChanged
an, ob der Spatializer-Effekt für das neue Audioausgaberouting verfügbar ist. An dieser Stelle können Sie die Logik zur Titelauswahl Ihres Players so aktualisieren, dass 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 Releases von ExoPlayer erleichtern die Einführung von Spatial Audio. 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 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, enthalten die 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 noch Inhalte enthalten, die räumlich dargestellt werden können.
Beschränkungen bei der 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 einen Stereotitel aus.
Wenn sich die Spatializer
-Eigenschaften ändern, löst ExoPlayer eine neue Trackauswahl aus, um einen Audiotrack auszuwählen, der mit den aktuellen Eigenschaften übereinstimmt. Durch diese neue Track-Auswahl kann es zu einer kurzen Pufferzeit kommen.
Um die Beschränkungen für die Anzahl der Audiokanäle zu deaktivieren, lege die Parameter für die Trackauswahl im Player wie unten dargestellt fest:
Kotlin
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Ebenso können Sie die Parameter eines vorhandenen Track-Selektors aktualisieren, um die Einschränkungen der 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 von Audiokanälen deaktiviert sind, wählt ExoPlayer anfangs den Titel mit der höchsten Anzahl von Kanälen aus und kann auf dem Gerät wiedergegeben werden, wenn Inhalte mehrere Audiospuren haben. Wenn der Inhalt beispielsweise eine Mehrkanal-Audiospur und eine Stereo-Audiospur enthält und das Gerät die Wiedergabe beider Audiotracks unterstützt, wählt ExoPlayer die Mehrkanalspur aus. Weitere Informationen zum Anpassen dieses Verhaltens finden Sie unter Audiotrack-Auswahl.
Audiotrackauswahl
Wenn das ExoPlayer-Verhalten der Einschränkungen für die Anzahl der Audiokanäle deaktiviert ist, wählt ExoPlayer nicht automatisch einen Audiotrack aus, der mit den Eigenschaften des Spatializers des Geräts übereinstimmt. Stattdessen können Sie die Logik für die Titelauswahl von ExoPlayer anpassen, indem Sie vor oder während der Wiedergabe Parameter zur Titelauswahl festlegen. ExoPlayer wählt in Bezug auf MIME-Typ (Codierung), Kanalanzahl und Abtastrate standardmäßig Audiotracks aus, die mit dem ursprünglichen Track identisch sind.
Parameter für die Titelauswahl ändern
Verwenden Sie Player.setTrackSelectionParameters()
, um die Parameter für die Trackauswahl des ExoPlayers zu ändern.
Analog können Sie die aktuellen ExoPlayer-Parameter mit Player.getTrackSelectionParameters()
abrufen.
So wählen Sie beispielsweise bei der Wiedergabe einen Stereo-Audiotrack aus:
Kotlin
exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters .buildUpon() .setMaxAudioChannelCount(2) .build()
Java
exoPlayer.setTrackSelectionParameters( exoPlayer.getTrackSelectionParameters() .buildUpon() .setMaxAudioChannelCount(2) .build() );
Das Ändern der Titelauswahlparameter mitten in der Wiedergabe kann zu einer Unterbrechung der Wiedergabe führen. Weitere Informationen zur Feinabstimmung der Titelauswahlparameter des Players finden Sie in der ExoPlayer-Dokumentation im Abschnitt zur Titelauswahl.
Standardverhalten für die Räumlichkeit
Das Standardverhalten der Räumlichkeit in Android umfasst die folgenden Verhaltensweisen, die von OEMs angepasst werden können:
Nur Multikanal-Inhalte sind räumlich dargestellt, keine Stereoinhalte. Wenn Sie ExoPlayer nicht verwenden, müssen Sie abhängig vom Format Ihrer Mehrkanal-Audioinhalte möglicherweise die maximale Anzahl an Kanälen konfigurieren, die von einem Audiodecoder an eine große Anzahl ausgegeben werden können. Dadurch wird sichergestellt, dass der Audiodecoder Mehrkanal-PCM für die Rä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 finden Sie unter
MediaCodecAudioRenderer.java
von ExoPlayer. Wie Sie die Raumisierung unabhängig von der OEM-Anpassung selbst deaktivieren, erfahren Sie unter Spatial Audio deaktivieren.AudioAttributes
: Audio ist für die Räumlichkeit zulässig, wennusage
entweder aufUSAGE_MEDIA
oderUSAGE_GAME
eingestellt ist.AudioFormat
: Verwenden Sie eine Kanalmaske, die mindestens die KanäleAudioFormat.CHANNEL_OUT_QUAD
(vorn links, vorne rechts, hinten links und hinten rechts) enthält, damit das Audio für die Räumlichkeit geeignet ist. Im folgenden Beispiel verwenden wirAudioFormat.CHANNEL_OUT_5POINT1
fü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.Setzen Sie außerdem die Codierung auf
AudioFormat.ENCODING_PCM_16BIT
, 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
Vergewissere dich, dass Spatial Audio auf deinem Testgerät aktiviert ist:
- Rufen Sie bei kabelgebundenen Headsets Systemeinstellungen > Ton und Vibration > Spatial Audio auf.
- Rufen Sie bei kabellosen Headsets Systemeinstellungen > Verbundene Geräte > Zahnradsymbol für Ihr Mobilgerät > Spatial Audio auf.
Führen Sie den Befehl adb shell dumpsys audio
auf Ihrem Gerät aus, um zu prüfen, ob Spatial Audio für das aktuelle Routing verfügbar ist. Während der Wiedergabe sollten die folgenden Parameter in der Ausgabe zu sehen sein:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)