Dźwięk przestrzenny to niezwykłe doznania dźwiękowe, które zapierają dech w piersiach jest w centrum akcji, dzięki czemu filmy brzmią bardziej realistycznie. Dźwięk jest „przestrzenny” aby uzyskać efekt wielu głośników, podobny do dźwięku przestrzennego konfiguracji, ale przez słuchawki.
Na przykład w filmie dźwięk samochodu może zaczynać się za użytkownikiem, przesuwać do przodu i zanikać w oddali. Na czacie wideo głosy mogą być są rozdzielone i rozmieszczone wokół użytkownika, co ułatwia rozpoznanie osób mówiących.
Jeśli Twoje treści są w obsługiwanym formacie audio, możesz dodać dźwięk przestrzenny do aplikacji od Androida w wersji 13 (poziom API 33).
Zapytanie o możliwości
Użyj klasy Spatializer
, aby zapytać o możliwości i zachowanie lokalizacji przestrzennej urządzenia. Najpierw pobierz instancję Spatializer
z poziomu bazy danych AudioManager
:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Po otrzymaniu Spatializer
sprawdź, czy spełnione są 4 warunki
true (prawda) dla urządzenia do odtwarzania dźwięku przestrzennego:
Kryteria | Sprawdź |
---|---|
Czy urządzenie obsługuje lokalizację przestrzenną? |
getImmersiveAudioLevel() nie jest SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
Czy dostępna jest lokalizacja przestrzenna? Dostępność zależy od zgodności z bieżącym kierowaniem wyjścia audio. |
isAvailable() to true |
Czy przestrzenność jest włączona? | isEnabled() to true |
Czy ścieżkę audio z podanymi parametrami można zastosować w przestrzeni przestrzennej? | canBeSpatialized() to true |
Te warunki mogą nie być spełnione, na przykład jeśli przestrzenność jest niedostępna dla bieżącej ścieżki audio lub jest całkowicie wyłączona na urządzeniu wyjściowym.
Monitorowanie ruchów głowy
W przypadku obsługiwanych słuchawek platforma może dostosować przestrzenność dźwięku na podstawie pozycji głowy użytkownika. Aby sprawdzić, czy tracker jest
dla bieżącego kierowania wyjścia audio, wywołanie
isHeadTrackerAvailable()
Zgodne treści
Spatializer.canBeSpatialized()
wskazuje, czy dźwięk z danymi właściwościami może być przestrzenny przy użyciu bieżącego przekierowywania urządzenia wyjściowego. Ta metoda przyjmuje argumenty AudioAttributes
i AudioFormat
, które są opisane bardziej szczegółowo poniżej.
AudioAttributes
Obiekt AudioAttributes
opisuje użytkowanie strumienia audio (np. dźwięk z gry lub standardowe media), a także jego zachowanie podczas odtwarzania i typ treści.
Podczas wywoływania canBeSpatialized()
użyj tej samej instancji AudioAttributes
, która jest skonfigurowana dla Player
. Na przykład, jeśli
używasz biblioteki Jetpack Media3 i nie dostosowano
AudioAttributes
, użyj AudioAttributes.DEFAULT
.
Wyłączanie dźwięku przestrzennego
Aby wskazać, że treść została już przestrzenna, użyj wywołania
setIsContentSpatialized(true)
aby dźwięk nie został
przetworzony podwójnie. Możesz też zmienić zachowanie funkcji dźwięku przestrzennego, aby całkowicie ją wyłączyć, wywołując funkcję setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
.
AudioFormat
Obiekt AudioFormat
opisuje
dane dotyczące formatu i konfiguracji kanału ścieżki audio.
Podczas tworzenia instancji AudioFormat
, którą chcesz przekazać do canBeSpatialized()
, ustaw kodowanie na takie samo jak format wyjściowy oczekiwany od dekodera. Musisz też ustawić maskę kanału, która odpowiada konfiguracji kanału Twoich treści. Zapoznaj się z
W sekcji Domyślne zachowanie przestrzenne znajdziesz wskazówki na temat
konkretne wartości.
Wykrywaj zmiany w: Spatializer
Aby nasłuchiwać zmian w stanie Spatializer
, możesz dodać słuchacza za pomocą Spatializer.addOnSpatializerStateChangedListener()
.
Aby nasłuchiwać zmian w dostępności lokalizatora głowy, zadzwoń pod numer Spatializer.addOnHeadTrackerAvailableListener()
.
Może to być przydatne, jeśli chcesz dostosować wybór utworu podczas odtwarzania za pomocą wywołań zwrotnych listenera. Na przykład, gdy użytkownik łączy lub rozłącza swoje
zestawu słuchawkowego z urządzenia onSpatializerAvailableChanged
wywołanie zwrotne wskazuje, czy efekt przestrzenny jest dostępny dla nowych
kierowania wyjścia audio. W tym momencie możesz rozważyć zaktualizowanie
śledzić logikę wyboru pod kątem nowych możliwości urządzenia. Więcej informacji:
Sposób wyboru ścieżek przez ExoPlayer znajdziesz w sekcji ExoPlayer i dźwięk przestrzenny.
.
ExoPlayer i dźwięk przestrzenny
Najnowsze wersje ExoPlayer ułatwiają stosowanie dźwięku przestrzennego. Jeśli używasz
samodzielna biblioteka ExoPlayer (nazwa pakietu com.google.android.exoplayer2
),
wersja 2.17 konfiguruje platformę tak, aby wydawała dźwięk przestrzenny,
2.18 wprowadza ograniczenia liczby kanałów audio.
Jeśli używasz modułu ExoPlayer z biblioteki Media3 (nazwa pakietu
androidx.media3
), wersje 1.0.0-beta01
i nowszych zawierają te same aktualizacje.
Po zaktualizowaniu zależności ExoPlayer do najnowszej wersji aplikacja musi zawierać treści, które można przestrzennie zlokalizować.
Ograniczenia dotyczące liczby kanałów audio
Gdy spełnione są wszystkie 4 warunki dotyczące dźwięku przestrzennego, ExoPlayer wybiera ścieżkę audio wielokanałową. W przeciwnym razie ExoPlayer wybiera ścieżkę stereo.
Jeśli właściwości Spatializer
ulegną zmianie, ExoPlayer
uruchamia wybór nowej ścieżki audio, która pasuje do
obecne właściwości. Pamiętaj, że wybór nowego utworu może spowodować krótką
przez okres ponownego buforowania.
Aby wyłączyć ograniczenia liczby kanałów audio, ustaw parametry wyboru ścieżki w odtwarzaczu, jak pokazano poniżej:
Kotlin
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Podobnie możesz zaktualizować parametry dotychczasowego selektora utworów, aby wyłączyć ograniczenia dotyczące liczby kanałów audio:
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() );
Jeśli ograniczenie liczby kanałów audio jest wyłączone, a treści zawierają wiele ścieżek audio, ExoPlayer początkowo wybiera ścieżkę, która ma największą liczbę kanałów i można ją odtworzyć na urządzeniu. Jeśli na przykład treści zawierają wielokanałową i stereofoniczną ścieżkę audio, a urządzenie obsługuje jednocześnie, ExoPlayer wybierze ścieżkę wielokanałową. Zobacz Wybór ścieżki dźwiękowej – szczegółowe informacje o tym, jak dostosować to działanie.
Wybór ścieżki audio
Gdy zachowanie ograniczeń liczby kanałów audio w ExoPlayerze jest wyłączone, ExoPlayer nie wybiera automatycznie ścieżki audio, która pasuje do właściwości procesora dźwięku przestrzennego urządzenia. Zamiast tego możesz dostosować logikę wyboru ścieżki ExoPlayera, ustawiając parametry wyboru ścieżki przed odtwarzaniem lub podczas odtwarzania. Domyślnie ExoPlayer wybiera dźwięk ścieżki, które są takie same jak ścieżka początkowa pod względem typu MIME. (kodowanie), liczbę kanałów i częstotliwość próbkowania.
Zmiana parametrów wyboru utworu
Aby zmienić parametry wyboru ścieżki w odtwarzaczu ExoPlayer, użyj funkcji
Player.setTrackSelectionParameters()
Bieżące parametry ExoPlayer można też uzyskać za pomocą parametru
Player.getTrackSelectionParameters()
Aby na przykład wybrać ścieżkę audio stereo w trakcie odtwarzania:
Kotlin
exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters .buildUpon() .setMaxAudioChannelCount(2) .build()
Java
exoPlayer.setTrackSelectionParameters( exoPlayer.getTrackSelectionParameters() .buildUpon() .setMaxAudioChannelCount(2) .build() );
Pamiętaj, że zmiana parametrów wyboru ścieżki w trakcie odtwarzania może spowodować przerwanie odtwarzania. Więcej informacji o dostosowywaniu parametrów wyboru utworów przez odtwarzacz znajdziesz w sekcji wyboru utworów w dokumentach ExoPlayer.
Domyślne zachowanie przestrzeni
Domyślne zachowanie przestrzenne w Androidzie obejmuje te zachowania, które mogą być dostosowywane przez producentów OEM:
Stereofonicznie są kodowane tylko treści wielokanałowe, a nie stereo. Jeśli nie używasz ExoPlayer, w zależności od formatu Twojego wielokanałowego treści audio, może być konieczne skonfigurowanie maksymalnej liczby kanałów które mogą być wysyłane przez dekoder audio na dużą liczbę. Dzięki temu dekoder audio może wygenerować PCM wielokanałowy, który platforma przetworzy na dźwięk przestrzenny.
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);
Przykład działania znajdziesz w przewodniku firmy ExoPlayer
MediaCodecAudioRenderer.java
. Aby samodzielnie wyłączyć przestrzennie, niezależnie od producenta OEM Więcej informacji znajdziesz w sekcji o wyłączaniu dźwięku przestrzennego.AudioAttributes
: dźwięk kwalifikuje się do przekształcenia przestrzennego jeśliusage
jest ustawiona naUSAGE_MEDIA
lubUSAGE_GAME
.AudioFormat
: użyj maski kanału, która zawiera co najmniejAudioFormat.CHANNEL_OUT_QUAD
(przedni lewy, przedni prawy, tylny lewy i tylny prawy) i nie mogą być wykorzystywane w przestrzeni. W poniższym przykładzie używamy wyrażeniaAudioFormat.CHANNEL_OUT_5POINT1
w przypadku ścieżki audio 5.1. W przypadku stereofonicznej ścieżki audio użyjAudioFormat.CHANNEL_OUT_STEREO
.Jeśli używasz Media3, możesz użyć funkcji
Util.getAudioTrackChannelConfig(int channelCount)
, aby przekształcić liczbę kanałów w maskę kanału.Dodatkowo ustaw kodowanie na
AudioFormat.ENCODING_PCM_16BIT
jeśli dekoder jest skonfigurowany tak, by wysyłał wielokanałowy PCM.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();
Testowanie dźwięku przestrzennego
Sprawdź, czy dźwięk przestrzenny jest włączony na urządzeniu testowym:
- W przypadku zestawów słuchawkowych przewodowych wybierz Ustawienia systemowe > Dźwięk i wibracje > Dźwięk przestrzenny.
- W przypadku słuchawek bezprzewodowych kliknij Ustawienia systemowe > Połączone urządzenia > Ikona koła zębatego (dla urządzenia bezprzewodowego) > Dźwięk przestrzenny.
Aby sprawdzić dostępność dźwięku przestrzennego dla bieżącego routingu, uruchom
adb shell dumpsys audio
na urządzeniu. Strona powinna wyglądać tak:
parametry w danych wyjściowych, gdy odtwarzanie jest aktywne:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)