Dźwięk przestrzenny to niezwykłe doznania dźwiękowe, które przenoszą użytkowników w sam środek akcji i sprawiają, że treści brzmią bardziej realistycznie. „Uprzestrzennienie” dźwięku pozwala uzyskać efekt wielu głośników, podobny do konfiguracji dźwięku przestrzennego, ale w słuchawkach.
Na przykład w filmie dźwięk samochodu może rozpoczynać się za plecami użytkownika, a potem przesuwać się do przodu i zanikać w oddali. Na czacie wideo głosy można rozdzielić i rozmieścić wokół użytkownika, co ułatwia rozpoznawanie osób mówiących.
Jeśli Twoje treści korzystają z obsługiwanego formatu dźwięku, dźwięk przestrzenny możesz dodawać do aplikacji już na Androidzie 13 (poziom API 33).
Zapytanie o możliwości
Użyj klasy Spatializer
, aby wysłać zapytanie dotyczące możliwości i działania urządzenia w zakresie przestrzennego działania urządzenia. Zacznij od pobrania instancji Spatializer
z AudioManager
:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Po uzyskaniu Spatializer
sprawdź 4 warunki, które muszą zostać spełnione, by urządzenie mogło odtwarzać dźwięk przestrzenny:
Kryteria | Sprawdź |
---|---|
Czy urządzenie obsługuje stosowanie przestrzeni przestrzennej? |
getImmersiveAudioLevel() nie jest SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
Czy jest dostępna analiza przestrzenna? Dostępność funkcji zależy od zgodności z bieżącym kierowaniem wyjścia audio. |
isAvailable() to true |
Czy przestrzennia 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 zostać spełnione, np. jeśli nie można zastosować przekształcenia przestrzennego w przypadku bieżącej ścieżki audio lub jest całkowicie wyłączone na urządzeniu wyjściowym audio.
Monitorowanie ruchów głowy
W przypadku obsługiwanych zestawów słuchawkowych platforma może dostosowywać przestrzenność dźwięku na podstawie pozycji głowy użytkownika. Aby sprawdzić, czy tracker jest dostępny przy bieżącym kierowaniu wyjścia audio, wywołaj isHeadTrackerAvailable()
.
Zgodne treści
Spatializer.canBeSpatialized()
wskazuje, czy dźwięk o podanych właściwościach może zostać przestrzenny z obecnym kierowaniem urządzenia wyjściowego. Ta metoda korzysta z obiektów AudioAttributes
i AudioFormat
. Oba te metody zostały szczegółowo opisane poniżej.
AudioAttributes
Obiekt AudioAttributes
opisuje użycie strumienia audio (na przykład dźwięk z gry lub standardowe multimedia), a także sposób jego odtwarzania i typ treści.
Wywołując metodę canBeSpatialized()
, użyj takiej samej instancji AudioAttributes
jak w przypadku instancji Player
. Jeśli na przykład używasz biblioteki Jetpack Media3 bez dostosowania AudioAttributes
, użyj AudioAttributes.DEFAULT
.
Wyłączanie dźwięku przestrzennego
Aby wskazać, że treści zostały już przekształcone w przestrzeni, wywołaj metodę setIsContentSpatialized(true)
, aby dźwięk nie był przetworzony podwójnie. Możesz też dostosować działanie przestrzenne, aby całkowicie wyłączyć przekształcanie przestrzenne, wywołując metodę setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
.
AudioFormat
Obiekt AudioFormat
opisuje szczegółowe informacje o formacie i konfiguracji kanału ścieżki audio.
Podczas tworzenia instancji AudioFormat
przekazywanej do canBeSpatialized()
ustaw kodowanie na taki sam format jak format wyjściowy oczekiwany od dekodera. Ustaw maskę kanału, która pasuje do konfiguracji Twojego kanału. Wskazówki dotyczące konkretnych wartości, których należy użyć, znajdziesz w sekcji Domyślne zachowanie przestrzenny.
Wykrywaj zmiany w: Spatializer
Aby nasłuchiwać zmian stanu obiektu Spatializer
, możesz dodać detektor za pomocą funkcji Spatializer.addOnSpatializerStateChangedListener()
.
Aby wykryć zmiany w dostępności trackera, wywołaj Spatializer.addOnHeadTrackerAvailableListener()
.
Jest to przydatne, gdy chcesz dostosować wybór ścieżki podczas odtwarzania za pomocą wywołań zwrotnych słuchacza. Na przykład, gdy użytkownik podłącza lub odłącza swój zestaw słuchawkowy od urządzenia, wywołanie zwrotne onSpatializerAvailableChanged
wskazuje, czy w przypadku nowego routingu wyjścia audio jest dostępny efekt przestrzenny. W tym momencie możesz zaktualizować logikę wyboru ścieżki w odtwarzaczu, aby dostosować ją do nowych możliwości urządzenia. Szczegółowe informacje o tym, jak ExoPlayer wybiera ścieżki, znajdziesz w sekcji ExoPlayer a dźwięk przestrzenny.
ExoPlayer i dźwięk przestrzenny
Najnowsze wersje ExoPlayer ułatwiają korzystanie z dźwięku przestrzennego. Jeśli używasz samodzielnej biblioteki ExoPlayer (nazwa pakietu com.google.android.exoplayer2
), wersja 2.17 konfiguruje platformę tak, aby wydawał dźwięk przestrzenny, a wersja 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 nowsze zawierają te same aktualizacje.
Po zaktualizowaniu zależności ExoPlayer do najnowszej wersji aplikacja musi tylko zawierać treści, które można umieścić w przestrzeni przestrzennej.
Ograniczenia liczby kanałów audio
Gdy zostaną spełnione wszystkie 4 warunki dotyczące dźwięku przestrzennego, ExoPlayer wybiera wielokanałową ścieżkę audio. W przeciwnym razie ExoPlayer wybiera ścieżkę stereo.
Jeśli właściwości Spatializer
ulegną zmianie, ExoPlayer wybierze nową ścieżkę audio, która pasuje do bieżących właściwości. Pamiętaj, że wybór nowej ścieżki audio może spowodować krótki okres ponownego buforowania.
Aby wyłączyć ograniczenia liczby kanałów audio, ustaw parametry wyboru ścieżki w odtwarzaczu w następujący sposób:
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ć istniejące parametry selektora ścieżki, aby wyłączyć ograniczenia liczby kanałów audio w ten sposób:
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() );
Gdy ograniczenie liczby kanałów audio jest wyłączone, to jeśli treści zawierają wiele ścieżek audio, ExoPlayer początkowo wybiera utwór z największą liczbą kanałów i można go odtworzyć na urządzeniu. Jeśli np. materiał zawiera wielokanałową i stereofoniczną ścieżkę audio, a urządzenie obsługuje odtwarzanie obu, ExoPlayer wybierze ścieżkę wielokanałową. Szczegółowe informacje o tym, jak dostosować ten sposób działania, znajdziesz w sekcji Wybór ścieżki dźwiękowej.
Wybór ścieżki audio
Gdy działanie ograniczeń liczby kanałów audio w oprogramowaniu ExoPlayer jest wyłączone, ExoPlayer nie wybiera automatycznie ścieżki audio, która pasuje do właściwości rozmieszczenia przestrzennego urządzenia. Zamiast tego możesz dostosować logikę wyboru ścieżki ExoPlayer przez ustawienie parametrów wyboru ścieżki przed odtwarzaniem lub w jego trakcie. Domyślnie ExoPlayer wybiera ścieżki audio takie same jak ścieżka początkowa, jeśli chodzi o typ MIME (kodowanie), liczbę kanałów i częstotliwość próbkowania.
Zmiana parametrów wyboru ścieżki
Aby zmienić parametry wyboru ścieżki w odtwarzaczu ExoPlayer, użyj polecenia Player.setTrackSelectionParameters()
.
Bieżące parametry ExoPlayer możesz też uzyskać za pomocą Player.getTrackSelectionParameters()
.
Aby na przykład wybrać stereofoniczną ścieżkę dźwiękową 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 utworu w trakcie odtwarzania może spowodować przerwanie odtwarzania. Więcej informacji o dostrajaniu parametrów wyboru ścieżki odtwarzacza znajdziesz w sekcji Wybór ścieżki w dokumentacji ExoPlayer.
Domyślne zachowanie przestrzeni
Domyślne zachowanie przestrzenne na Androidzie obejmuje te zachowania, które producenci OEM mogą dostosować:
Przestrzenne są tylko treści wielokanałowe, a nie materiały stereo. Jeśli nie używasz ExoPlayer, to w zależności od formatu wielokanałowych treści audio może być konieczne skonfigurowanie maksymalnej liczby kanałów, którą dekoder audio może wysłać na dużą liczbę. Dzięki temu dekoder dźwięku wysyła wielokanałowy PCM, aby platforma stała się przestrzenna.
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ć stosowanie dźwięku przestrzennego bez względu na dostosowanie OEM, przeczytaj artykuł Wyłączanie dźwięku przestrzennego.AudioAttributes
: dźwięk może być przestrzenny, jeśliusage
ma ustawienieUSAGE_MEDIA
lubUSAGE_GAME
.AudioFormat
: użyj maski kanału, która zawiera co najmniej kanałyAudioFormat.CHANNEL_OUT_QUAD
(przedni lewy, przedni, lewy i tylny prawy), aby dźwięk kwalifikował się do przekształcenia w przestrzeni. W przykładzie poniżej używamy słowaAudioFormat.CHANNEL_OUT_5POINT1
w przypadku ścieżki audio 5.1. W przypadku stereofonicznej ścieżki audio użyjAudioFormat.CHANNEL_OUT_STEREO
.Jeśli korzystasz z Media3, możesz użyć parametru
Util.getAudioTrackChannelConfig(int channelCount)
, aby przekonwertować liczbę kanałów na maskę kanału.Dodatkowo, jeśli dekoder został skonfigurowany tak, by wyjścić wielokanałowy PCM, ustaw kodowanie na
AudioFormat.ENCODING_PCM_16BIT
.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();
Przetestuj dźwięk przestrzenny
Sprawdź, czy na urządzeniu testowym włączony jest dźwięk przestrzenny:
- W przypadku przewodowych zestawów słuchawkowych kliknij Ustawienia systemu > Dźwięk i wibracje > Dźwięk przestrzenny.
- W przypadku bezprzewodowych zestawów słuchawkowych kliknij Ustawienia systemu > Połączone urządzenia > Ikona koła zębatego urządzenia bezprzewodowego > Dźwięk przestrzenny.
Aby sprawdzić dostępność dźwięku przestrzennego dla bieżącego routingu, uruchom na urządzeniu polecenie adb shell dumpsys audio
. Gdy odtwarzanie jest aktywne, w danych wyjściowych powinny być widoczne te parametry:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)