Nowości dotyczące produktów

Media3 1.9.0 – co nowego

Czas czytania: 6 minut
Kristina Simakova
Menedżer ds. inżynierii

Wydaliśmy Media3 1.9.0. Oprócz zwykłych poprawek błędów i ulepszeń wydajności najnowsza wersja zawiera też 4 nowe lub w dużej mierze przepisane moduły:

  • media3-inspector – wyodrębnianie metadanych i klatek poza odtwarzaniem
  • media3-ui-compose-material3 – tworzenie podstawowego interfejsu multimedialnego Material3 Compose w kilku krokach
  • media3-cast – automatyczne przełączanie się między odtwarzaniem na urządzeniu a odtwarzaniem na urządzeniu Chromecast
  • media3-decoder-av1 – spójne odtwarzanie AV1 dzięki przepisanej wtyczce dekodera opartej na bibliotece dav1d

Dodaliśmy też ulepszenia dotyczące buforowania i zarządzania pamięcią w PreloadManager oraz wprowadziliśmy kilka nowych uproszczeń w ExoPlayer, Transformer i MediaSession

Ta wersja daje też pierwszy eksperymentalny dostęp do CompositionPlayer, który umożliwia wyświetlanie podglądu edycji multimediów.  


Aby dowiedzieć się więcej, przeczytaj ten artykuł. Jak zawsze, pełne informacje o zmianach w tej wersji znajdziesz w pełnych informacjach o wersji.

Wyodrębnianie metadanych i klatek poza odtwarzaniem

W wielu przypadkach możesz chcieć sprawdzić multimedia bez rozpoczynania odtwarzania. Możesz na przykład wykryć, jakie formaty zawiera plik, jaka jest jego długość lub pobrać miniatury.

Nowy moduł media3-inspector łączy w jednym miejscu wszystkie narzędzia do sprawdzania multimediów bez odtwarzania:

  • MetadataRetriever do odczytywania długości, formatu i statycznych metadanych z MediaItem.
  • FrameExtractor do pobierania klatek lub miniatur z elementu.
  • MediaExtractorCompat jako bezpośredni zamiennik klasy MediaExtractor platformy Android, który umożliwia uzyskiwanie szczegółowych informacji o próbkach w pliku.

MetadataRetriever i FrameExtractor korzystają z prostego wzorca AutoCloseable. Więcej informacji znajdziesz na naszych nowych stronach przewodnika.

suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Tworzenie podstawowego interfejsu multimedialnego Material3 Compose w kilku krokach

W poprzednich wersjach zaczęliśmy udostępniać kod łączący elementy interfejsu Compose z instancją odtwarzacza. W Media3 1.9.0 dodaliśmy nowy moduł media3-ui-compose-material3 z w pełni stylizowanymi przyciskami i elementami treści Material3. Umożliwiają one tworzenie interfejsu multimedialnego w kilku krokach, a jednocześnie zapewniają pełną elastyczność w zakresie dostosowywania stylu. Jeśli wolisz tworzyć własny styl interfejsu, możesz użyć bloków konstrukcyjnych, które zajmują się całą logiką aktualizacji i połączeń, dzięki czemu możesz skupić się tylko na projektowaniu elementu interfejsu. Więcej informacji znajdziesz na naszych rozszerzonych stronach przewodnika dotyczących modułów interfejsu Compose.

Cały czas pracujemy też nad kolejnymi komponentami Compose, takimi jak gotowy pasek przewijania, kompletny zamiennik PlayerView, a także integracja napisów i reklam.

@Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

Prosty interfejs odtwarzacza Compose z gotowymi elementami

Automatyczne przełączanie się między odtwarzaniem na urządzeniu a odtwarzaniem na urządzeniu Chromecast

Odtwarzacz CastPlayer w module media3-cast został przepisany, aby automatycznie przełączać się między odtwarzaniem na urządzeniu (np. za pomocą ExoPlayer) a odtwarzaniem na urządzeniu Chromecast.

Gdy skonfigurujesz MediaSession, po prostu utwórz CastPlayer wokół ExoPlayer i dodaj MediaRouteButton do interfejsu. To wszystko.

// MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Nowa integracja CastPlayer w aplikacji w wersji demonstracyjnej sesji Media3

Spójne odtwarzanie AV1 dzięki przepisanej wtyczce opartej na dav1d

Wersja 1.9.0 zawiera całkowicie przepisany moduł wtyczki AV1 oparty na popularnej bibliotece dav1d

Podobnie jak w przypadku wszystkich modułów rozszerzeń dekoderów, pamiętaj, że aby prawidłowo powiązać odpowiedni kod natywny, musisz skompilować kod źródłowy.  Powiązanie dekodera zapewnia spójność i obsługę formatów na wszystkich urządzeniach, ale ponieważ dekodowanie odbywa się w Twoim procesie, najlepiej używać go w przypadku treści, którym ufasz. 

Integracja buforowania i zarządzania pamięcią z PreloadManager

Ulepszyliśmy też PreloadManager. Umożliwia on już wstępne wczytywanie multimediów do pamięci poza odtwarzaniem, a następnie płynne przekazywanie ich do odtwarzacza w razie potrzeby. Chociaż jest dość wydajny, nadal trzeba uważać, aby nie przekroczyć limitów pamięci przez przypadkowe wstępne wczytanie zbyt dużej ilości danych. Dlatego w Media3 1.9.0 dodaliśmy 2 funkcje, które znacznie ułatwiają i stabilizują ten proces:

  1. Obsługa buforowania – podczas określania, jak daleko wstępnie wczytywać, możesz teraz wybrać PreloadStatus.specifiedRangeCached(0, 5000) jako stan docelowy wstępnie wczytanych elementów. Spowoduje to dodanie określonego zakresu do pamięci podręcznej na dysku zamiast wczytywania danych do pamięci. Dzięki temu możesz udostępnić znacznie większy zakres elementów do wstępnego wczytywania, ponieważ elementy znajdujące się dalej od bieżącego elementu nie muszą już zajmować pamięci. Pamiętaj, że wymaga to ustawienia Cache w DefaultPreloadManager.Builder.
  2. Automatyczne zarządzanie pamięcią – zaktualizowaliśmy też interfejs LoadControl, aby lepiej obsługiwał wstępne wczytywanie. Możesz teraz ustawić wyraźny górny limit pamięci dla wszystkich wstępnie wczytanych elementów w pamięci. Domyślnie jest to 144 MB, ale możesz skonfigurować limit w DefaultLoadControl.Builder. DefaultPreloadManager automatycznie zatrzyma wstępne wczytywanie po osiągnięciu limitu i w razie potrzeby automatycznie zwolni pamięć elementów o niższym priorytecie.

Korzystanie z nowych uproszczonych domyślnych zachowań w ExoPlayer

Jak zawsze, dodaliśmy też wiele drobnych ulepszeń do ExoPlayer. Oto kilka przykładów:

  • Wyciszanie i wyłączanie wyciszenia – mieliśmy już metodę setVolume, ale dodaliśmy teraz wygodne metody mute i unmute, które umożliwiają łatwe przywrócenie poprzedniej głośności bez konieczności samodzielnego śledzenia jej.
  • Wykrywanie zablokowanego odtwarzacza – w rzadkich przypadkach odtwarzacz może się zablokować w stanie buforowania lub odtwarzania bez postępu, np. z powodu problemów z kodekiem lub błędnej konfiguracji. Użytkownicy będą zirytowani, ale Ty nigdy nie zobaczysz tych problemów w statystykach. Aby to było bardziej oczywiste, odtwarzacz zgłasza teraz StuckPlayerException, gdy wykryje stan zablokowania.
  • Wakelock domyślnie – zarządzanie blokadą uśpienia było wcześniej opcjonalne, co powodowało trudne do znalezienia przypadki brzegowe, w których postęp odtwarzania mógł być znacznie opóźniony podczas działania w tle. Teraz ta funkcja jest domyślnie wyłączona, więc nie musisz się o nią martwić i możesz też usunąć całą ręczną obsługę blokady uśpienia podczas odtwarzania.
  • Uproszczone ustawienie logiki przycisku napisów – zmiana TrackSelectionParameters na „włącz/wyłącz napisy” była zaskakująco trudna do prawidłowego wykonania, dlatego dodaliśmy prostą opcję logiczną selectTextByDefault dla tego przypadku użycia.

Uproszczenie ustawień przycisków multimedialnych w MediaSession

Do tej pory określanie preferencji dotyczących tego, które przyciski mają się wyświetlać w panelu powiadomień multimedialnych w Androidzie Auto lub WearOS, wymagało definiowania niestandardowych poleceń i przycisków, nawet jeśli po prostu chciałeś wywołać standardową metodę odtwarzacza.

Media3 1.9.0 ma nową funkcję, która znacznie upraszcza ten proces – możesz teraz określać preferencje dotyczące przycisków multimedialnych za pomocą standardowego polecenia odtwarzacza, co nie wymaga żadnej obsługi poleceń niestandardowych.

session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Ustawienia przycisków multimedialnych z przyciskiem szybkiego przewijania do przodu

CompositionPlayer do podglądu w czasie rzeczywistym

Wersja 1.9.0 wprowadza CompositionPlayer pod nową adnotacją @ExperimentalApi. Wskazuje ona, że jest on dostępny do eksperymentowania, ale nadal jest w fazie rozwoju. 

CompositionPlayer to nowy komponent w interfejsach Media3 API do edycji, który umożliwia wyświetlanie podglądu edycji multimediów w czasie rzeczywistym. CompositionPlayer jest oparty na znanym interfejsie Media3 Player i umożliwia użytkownikom zobaczenie zmian przed rozpoczęciem procesu eksportu. Używa tego samego obiektu Composition, który przekazujesz do Transformer na potrzeby eksportu, co usprawnia proces edycji przez ujednolicenie modelu danych na potrzeby podglądu i eksportu.

Zachęcamy do rozpoczęcia korzystania z CompositionPlayer i dzielenia się opiniami. Więcej informacji znajdziesz w nadchodzących postach i aktualizacjach dokumentacji.

InAppMuxer jako domyślny multiplekser w Transformer

Transformer używa teraz InAppMp4Muxer jako domyślnego multipleksera do zapisywania plików kontenerów multimedialnych. Wewnętrznie, InAppMp4Muxer zależy od modułu Media3 Muxer, co zapewnia spójne działanie we wszystkich wersjach interfejsu API. 

Pamiętaj, że chociaż Transformer nie używa już domyślnie MediaMuxer platformy Android, możesz nadal przekazywać FrameworkMuxer.Factory za pomocą setMuxerFactory, jeśli wymaga tego Twój przypadek użycia.

Nowe interfejsy API do regulacji prędkości

Wersja 1.9.0 upraszcza interfejsy API do regulacji prędkości na potrzeby edycji multimediów. Wprowadziliśmy nowe metody bezpośrednio w EditedMediaItem.Builder, aby kontrolować prędkość, co sprawia, że interfejs API jest bardziej intuicyjny. Możesz teraz zmienić prędkość klipu, wywołując setSpeed(SpeedProvider provider) w EditedMediaItem.Builder:

val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

To nowe podejście zastępuje poprzednią metodę korzystania z Effects#createExperimentalSpeedChangingEffects(), która została wycofana i zostanie usunięta w przyszłej wersji.

Wprowadzenie typów ścieżek dla EditedMediaItemSequence

W wersji 1.9.0 EditedMediaItemSequence wymaga określenia żądanych typów ścieżek wyjściowych podczas tworzenia sekwencji. Ta zmiana zapewnia bardziej wyraźną i niezawodną obsługę ścieżek w całej kompozycji. 

Odbywa się to za pomocą nowego EditedMediaItemSequence.Builder konstruktora, który akceptuje zestaw typów ścieżek (np. C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

Aby uprościć tworzenie, dodaliśmy nowe statyczne metody pomocnicze:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Zachęcamy do przejścia na nowy konstruktor lub metody pomocnicze, aby uzyskać bardziej przejrzyste i niezawodne definicje sekwencji.

Przykład tworzenia sekwencji tylko z wideo:

EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Jeśli napotkasz błędy lub masz pytania albo prośby o dodanie funkcji, skontaktuj się z nami za pomocą narzędzia do śledzenia problemów Media3. Czekamy na wiadomość od Ciebie!

Autor:

Czytaj dalej