Rozwiązywanie problemów


Naprawianie ustawienia „Ruch HTTP niedozwolony” błędy

Ten błąd występuje, jeśli aplikacja żąda ruchu HTTP jako jawnego tekstu (czyli http://, a nie https://), jeśli ma konfigurację zabezpieczeń sieci nie pozwalają. Jeśli aplikacja jest kierowana na Androida 9 (poziom interfejsu API 28) lub nowszego, tekst nieszyfrowany Ruch HTTP jest wyłączony przez domyślną konfigurację.

Jeśli Twoja aplikacja musi obsługiwać ruch HTTP z tekstem nieszyfrowanym, użyj metody Konfiguracja zabezpieczeń sieci, która na to zezwala. Zobacz: dokumentacja dotycząca zabezpieczeń sieci . Aby włączyć cały ruch HTTP, możesz dodać android:usesCleartextTraffic="true" do elementu application w polu wyszukiwania AndroidManifest.xml

Aplikacja demonstracyjna ExoPlayer używa domyślnej konfiguracji zabezpieczeń sieci, nie zezwala na ruch HTTP nieszyfrowany. Aby ją włączyć, postępuj zgodnie z instrukcjami powyżej.

Naprawianie wyjątku „SSLHandshakeException” i „CertPathValidatorException” i „ERR_CERT_AUTHORITY_Nieprawidłowy” błędy

SSLHandshakeException, CertPathValidatorException i ERR_CERT_AUTHORITY_INVALID oznacza problem z protokołem SSL serwera certyfikat. Te błędy nie dotyczą konkretnego odtwarzacza ExoPlayer. Zobacz Dokumentacja SSL na Androida .

Dlaczego niektórych plików multimedialnych nie można przewijać?

Domyślnie ExoPlayer nie obsługuje przewijania w przypadku multimediów, w których jedyną metodą wykonywanie dokładnych operacji przewijania ma na celu to, aby odtwarzacz przeskanował i zindeksował cały plik. Program ExoPlayer uważa takie pliki za mało wyszukiwane. Najbardziej nowoczesne media zawiera metadane do przewijania (np. przykładowy indeks), mają dobrze zdefiniowany algorytm przewijania (np. interpolowane wyszukiwanie dwusekcji dla Ogg) lub wskazują, że ich treści mają stałą szybkość transmisji bitów. Efektywne przewijanie i obsługiwany przez ExoPlayer w takich przypadkach.

Jeśli zależy Ci na poszukiwaniach, ale masz mało dostępne media, zalecamy aby użyć bardziej odpowiedniego formatu kontenera. W przypadku plików MP3, ADTS i AMR możesz też włączyć przewijanie, zakładając, że pliki mają stałą zgodnie z opisem tutaj.

Dlaczego w przypadku niektórych plików MP3 wyszukiwanie jest niedokładne?

Pliki MP3 o zmiennej szybkości transmisji bitów (VBR) zasadniczo nie nadają się do stosowania wymagają dokładnego przewijania. Dzieje się tak z 2 powodów:

  1. Przy precyzyjnym wyszukiwaniu format kontenera powinien zapewniać dokładny w nagłówku. To mapowanie umożliwia graczowi mapowanie żądanego czasu przewijania do odpowiedniego przesunięcia bajtowego i rozpocznij żądanie, analizowanie i odtwarzanie multimediów od tego przesunięcia. Nagłówki dostępne dla określenie tego mapowania w formacie MP3 (np. nagłówków XING) jest niestety często są nieprecyzyjne.
  2. Na potrzeby formatów kontenerów, które nie zapewniają dokładnego mapowania czasu do bajtów (lub w jakimkolwiek mapowaniu czasu do bajtów), wciąż można dokładnie szukaj, czy kontener zawiera bezwzględne sygnatury czasowe próbki w strumieniu. W w tym przypadku gracz może przypisać czas przewijania do najbardziej trafnego bajtowe, zacznij żądać multimediów od tego przesunięcia, przeanalizuj pierwsze bezwzględna sygnatura czasowa próbki i skutecznie przeprowadzić wyszukiwanie binarne z przewodnikiem aż znajdzie właściwy fragment. Format MP3 nie działa uwzględnić w strumieniu bezwzględne sygnatury czasowe próbek, więc ta metoda nie jest jak to tylko możliwe.

Z tych powodów jedynym sposobem przeprowadzenia dokładnego wyszukiwania do pliku VBR MP3 jest skanować cały plik i ręcznie utworzyć mapowanie czasu do bajtów . Tę strategię można włączyć za pomocą: FLAG_ENABLE_INDEX_SEEKING, które można ustawić na DefaultExtractorsFactory za pomocą setMp3ExtractorFlags. Ta funkcja nie radzi sobie dobrze z dużymi plikami MP3, zwłaszcza jeśli użytkownik próbuje dotrzeć do końca transmisji po rozpoczęciu odtwarzania, co wymaga, aby odtwarzacz czekał, aż film zostanie pobrany. i zindeksował cały strumień przed rozpoczęciem wyszukiwania. W narzędziu ExoPlayer w tym przypadku optymalizacja pod kątem szybkości, niż dokładności, Dlatego usługa FLAG_ENABLE_INDEX_SEEKING jest domyślnie wyłączona.

Jeśli masz kontrolę nad odtwarzanymi multimediami, zdecydowanie zalecamy korzystanie odpowiedniego formatu kontenera, np. MP4. Nie znamy żadnych przypadków użycia gdzie MP3 to najlepszy format.

Dlaczego przewijanie w filmie trwa wolno?

Gdy odtwarzacz przewija film do nowej pozycji, musi wykonać dwie czynności

  1. Wczytaj do bufora dane odpowiadające nowej pozycji odtwarzania (może to nie być konieczne, jeśli dane są już buforowane).
  2. Opróżnić dekoder wideo i rozpocząć dekodowanie od klatki kluczowej (klatka kluczowa) przed ze względu na kodowanie wewnątrzklatkowe, które jest używane przez większość filmów formatów kompresji. Aby mieć pewność, że wyszukiwanie jest dokładne (czyli odtwarzanie rozpocznie się dokładnie w pozycji przewijania), wszystkie klatki między klawiszem poprzedzające klatkę I-Frame i pozycję przewijania muszą zostać zdekodowane i niezwłocznie odrzucone (nie pojawiają się na ekranie).

Czas oczekiwania związany z wynikiem (1) można zmniejszyć, zwiększając wartość danych buforowanych w pamięci przez odtwarzacz lub wstępnego buforowania danych na dysku.

Czas oczekiwania związany z wynikiem (2) można zmniejszyć, zmniejszając dokładność przewinięcia za pomocą narzędzia ExoPlayer.setSeekParameters lub ponowne kodowanie filmu aby mieć więcej ramek I-frame (co spowoduje większy plik wyjściowy).

Dlaczego niektóre pliki MPEG-TS nie odtwarzają się?

Niektóre pliki MPEG-TS nie zawierają ograniczników jednostek dostępu (AUD). Domyślnie ExoPlayer polega na tanim wykrywaniu granic klatek na podstawie danych w dolarach australijskich. Podobnie niektóre Pliki MPEG-TS nie zawierają klatek kluczowych IDR. Domyślnie są to jedyne typy klatek kluczowych branych pod uwagę przez ExoPlayer.

Odtwarzacz ExoPlayer zawiesił się w trybie buforowania po wyświetleniu prośby o odtworzenie Plik MPEG-TS bez AUD ani klatek kluczowych IDR. Jeśli chcesz odtworzyć takie pliki, możesz to zrobić za pomocą narzędzia FLAG_DETECT_ACCESS_UNITS oraz FLAG_ALLOW_NON_IDR_KEYFRAMES. Te flagi można ustawić DefaultExtractorsFactory za pomocą setTsExtractorFlags lub w DefaultHlsExtractorFactory za pomocą Konstruktor. Korzystanie z aplikacji FLAG_DETECT_ACCESS_UNITS nie ma żadnych skutków ubocznych poza koszt obliczeniowy w stosunku do wykrywania granic ramek na podstawie AUD. Zastosowanie FLAG_ALLOW_NON_IDR_KEYFRAMES może spowodować tymczasowe uszkodzenie wizualne rozpoczęcie odtwarzania i bezpośrednio po przewijaniu w przypadku niektórych plików MPEG-TS.

Dlaczego w niektórych plikach MPEG-TS nie ma napisów?

Niektóre pliki MPEG-TS zawierają ścieżki CEA-608, ale nie są deklarowane w metadanych kontenera, więc ExoPlayer nie może ich wykryć. Możesz ręcznie wskazać ścieżki napisów, podając listę oczekiwanych formaty napisów do filmu DefaultExtractorsFactory, w tym ułatwienia dostępu kanałów, za pomocą których można zidentyfikować je w strumieniu MPEG-TS:

Kotlin

val extractorsFactory =
  DefaultExtractorsFactory()
    .setTsSubtitleFormats(
      listOf(
        Format.Builder()
          .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
          .setAccessibilityChannel(accessibilityChannel)
          // Set other subtitle format info, such as language.
          .build()
      )
    )
val player: Player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory()
        .setTsSubtitleFormats(
            ImmutableList.of(
                new Format.Builder()
                    .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
                    .setAccessibilityChannel(accessibilityChannel)
                    // Set other subtitle format info, such as language.
                    .build()));
Player player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory))
        .build();

Dlaczego niektóre pliki MP4/FMP4 są nieprawidłowo odtwarzane?

Niektóre pliki MP4/FMP4 zawierają listy edycji, które zmieniają oś czasu multimediów przez pomijania, przenoszenia lub powtarzania list próbek. ExoPlayer ma częściową obsługę do zastosowania list edycji. Może na przykład opóźniać lub powtarzać grupy próbek. rozpoczyna się od próbki synchronizacji, ale nie powoduje obcięcia sampli audio ani multimedia przed filmem w przypadku zmian, które nie rozpoczynają się od próbki synchronizacji.

Jeśli zauważysz, że danego fragmentu multimediów nieoczekiwanie brakuje lub powtarza się, spróbuj ustawić Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS lub FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS, co spowoduje wyodrębniania, aby całkowicie zignorować listy edycyjne. Można je ustawić DefaultExtractorsFactory za pomocą setMp4ExtractorFlags lub setFragmentedMp4ExtractorFlags.

Dlaczego w przypadku niektórych strumieni występuje błąd, gdy pojawia się kod odpowiedzi HTTP 301 lub 302?

Kody odpowiedzi HTTP 301 i 302 wskazują na przekierowanie. Krótkie opisy znajdziesz w Wikipedii. Gdy ExoPlayer wysyła żądanie i otrzymuje odpowiedź z kodem stanu 301 lub 302, zwykle będzie podążać za przekierowaniem i rozpocznij odtwarzanie tak jak zwykle. Jedyny przypadek, w którym domyślnie jest przeznaczony do przekierowań międzyprotokołowych. Przekierowanie międzyprotokołowe to takie, które polega na przekierowaniu z HTTPS do HTTP lub odwrotnie (lub rzadziej – między inną parą adresów protokoły). To, czy adres URL powoduje przekierowanie między protokołami, możesz sprawdzić za pomocą użyj narzędzia wiersza poleceń wget w ten sposób:

wget "https://yourserver.com/test.mp3" 2>&1  | grep Location

Dane wyjściowe powinny wyglądać mniej więcej tak:

Location: https://second.com/test.mp3 [following]
Location: http://third.com/test.mp3 [following]

W tym przykładzie mamy 2 przekierowania. Pierwsze przekierowanie pochodzi z https://yourserver.com/test.mp3 do https://second.com/test.mp3. Oba HTTPS, więc nie jest to przekierowanie między protokołami. Drugie przekierowanie pochodzi z https://second.com/test.mp3 do http://third.com/test.mp3. To przekierowanie z HTTPS do HTTP, co oznacza przekierowanie między protokołami. ExoPlayer nie będzie dla tego przekierowania w konfiguracji domyślnej, co oznacza, że odtwarzanie się nie powiedzie.

W razie potrzeby możesz skonfigurować ExoPlayer tak, aby śledził przekierowania między protokołami podczas tworzenia instancji DefaultHttpDataSource.Factory używanych aplikacji. Więcej informacji o wybieraniu i konfigurowaniu stosu sieciowego tutaj.

Dlaczego w przypadku niektórych strumieni występują błędy z błędem UnrecognizedInputFormatException?

To pytanie dotyczy błędów odtwarzania w następującym formacie:

UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.

Ten błąd może mieć dwie przyczyny. Najczęstszą przyczyną jest próbujesz odtworzyć DASH (mpd), HLS (m3u8) lub SmoothStreaming (ism, isml); treści, ale odtwarzacz próbuje je odtworzyć jako strumień progresywny. Aby odtworzyć taki strumieniowania, musisz skorzystać z odpowiedniego modułu ExoPlayer. W przypadku, gdy: identyfikator URI strumienia nie kończy się standardowym rozszerzeniem pliku, możesz też MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 lub Od MimeTypes.APPLICATION_SS do setMimeType z MediaItem.Builder do określ typ strumienia.

Drugą, rzadziej występującą przyczyną jest to, że ExoPlayer nie obsługuje kontenera formatu nośnika, który próbujesz odtworzyć. W tym przypadku chodzi o niepowodzenie. działa zgodnie z oczekiwaniami, ale możesz przesłać prośbę o dodanie funkcji do naszego narzędzie do rejestrowania problemów, w tym szczegóły formatu kontenera i strumień testowy. Zanim prześlesz nową prośbę o dodanie funkcji, wyszukaj istniejącą.

Dlaczego na niektórych urządzeniach parametr setPlaybackParameters nie działa prawidłowo?

Podczas wykonywania kompilacji do debugowania aplikacji na Androidzie M lub starszym możesz: niestabilną wydajność, słyszalne zakłócenia i wysokie wykorzystanie procesora za pomocą interfejsu API setPlaybackParameters. To dlatego, że optymalizacja ważne dla tego interfejsu API jest wyłączone w kompilacjach do debugowania działających w tych wersji Androida.

Pamiętaj, że ten problem dotyczy tylko kompilacji do debugowania. Nie wpływa na kompilacje wersji, w których optymalizacja jest zawsze włączona. Dlatego wersji udostępnianych użytkownikom nie powinien dotyczyć tego problemu.

Co się dzieje „Do gracza uzyskano dostęp w niewłaściwym wątku” co oznaczają błędy?

Na stronie z wprowadzeniem znajdziesz notatkę o wątkach.

Jak rozwiązać problem z komunikatem „Nieoczekiwany wiersz stanu: ICY 200 OK”?

Ten problem może wystąpić, jeśli odpowiedź serwera zawiera wiersz stanu ICY, a nie zgodne z protokołem HTTP. Wiersze stanu ICY zostały wycofane i nie powinien być używany, więc jeśli masz kontrolę nad serwerem, zaktualizuj go, aby odpowiedź zgodną z protokołem HTTP. Jeśli nie możesz tego zrobić, skorzystaj z Biblioteka ExoPlayer OkHttp rozwiąże problem, ponieważ jest w stanie obsłużyć ICY. prawidłowe wiersze stanu.

Jak sprawdzić, czy odtwarzana transmisja jest transmisją na żywo?

Możesz wysłać zapytanie dotyczące metody isCurrentWindowLive odtwarzacza. Dodatkowo może sprawdzić pole isCurrentWindowDynamic, by określić, czy okno jest dynamiczne (czyli cały czas go aktualizujemy).

Jak mogę odtwarzać dźwięk, gdy moja aplikacja działa w tle?

Wykonaj te czynności, aby dalej odtwarzać dźwięk, gdy aplikacja jest włączona tło:

  1. Musisz mieć uruchomioną usługę na pierwszym planie. Zapobiega to od przerywania procesów do uwolnienia zasobów.
  2. Musisz mieć WifiLock i WakeLock. Dzięki temu powoduje, że radio i procesor Wi-Fi są aktywne. Możesz to łatwo zrobić, jeśli używasz ExoPlayer, łącząc się z setWakeMode, który zostanie automatycznie nakładania i usuwania wymaganych blokad we właściwym czasie.

Pamiętaj, aby zwolnić blokady (jeśli nie używasz setWakeMode) i zatrzymać z usługi w chwili zaprzestania odtwarzania dźwięku.

Dlaczego ExoPlayer obsługuje moje treści, a biblioteka Cast ExoPlayer nie?

Możliwe, że treści, które próbujesz odtworzyć, nie są Włączono CORS. Platforma przesyłania wymaga włączenia CORS w treści aby odtworzyć.

Dlaczego treści się nie odtwarzają, ale nie pojawiają się żadne błędy?

Możliwe, że urządzenie, na którym odtwarzasz treści, obsługują konkretny format przykładowych multimediów. Można to łatwo potwierdzić, dodając ciąg EventLogger jako słuchawka odtwarzacza i szuka wiersza podobny do tego w Logcat:

[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE

NO_UNSUPPORTED_TYPE oznacza, że urządzenie nie może zdekodować multimediów. przykładowy format określony przez mimeType. Zobacz formaty multimediów na Androida dokumentacji. Jak uzyskać biblioteki dekodującej do wczytania i odtwarzania?.

Jak pobrać bibliotekę dekodowania do wczytania i odtwarzania?

  • Większość bibliotek dekodera wymaga ręcznego sprawdzania i tworzenia zależności, wykonaj czynności opisane w pliku README w odniesieniu do odpowiedniej biblioteki. Na przykład w przypadku biblioteki ExoPlayer FFmpeg trzeba przestrzegać instrukcji instrukcji w pliku libraries/decoder_ffmpeg/README.md, w tym flag konfiguracji, aby włączyć dekodery dla każdego formatu, który chcesz odtwarzać.
  • W przypadku bibliotek zawierających kod natywny sprawdź, czy używasz poprawnej wersji NDK Androida wskazanej w pliku README i poszukaj ewentualnych które pojawiają się podczas konfigurowania i kompilowania. Zobaczysz: .so są widoczne w podkatalogu libs ścieżki biblioteki dla każdego z nich obsługiwanej architektury po wykonaniu czynności w pliku README.
  • Aby wypróbować odtwarzanie przy użyciu biblioteki w aplikacji demonstracyjnej, zobacz włączenie pakietów dekoderów. Wyświetl plik README dla biblioteki: jak korzystać z biblioteki w swojej aplikacji.
  • Jeśli używasz DefaultRenderersFactory, powinien wyświetlić się poziom informacyjny. wiersz dziennika, taki jak „Loaded FfmpegAudioRenderer”. w Logcat. Jeśli go brakuje, upewnij się, że aplikacja jest zależna od z biblioteki dekodowania.
  • Jeśli w logcat wyświetlają się logi na poziomie ostrzeżenia z LibraryLoader, wskazuje, że nie udało się wczytać natywnego komponentu biblioteki. Jeśli sprawdź, czy wykonałeś poprawnie czynności w pliku README biblioteki. i że podczas wykonywania instrukcji nie pojawiły się żadne błędy.

Jeśli nadal masz problemy z bibliotekami dekodowania, zapoznaj się z Narzędzie do śledzenia problemów Media3 dotyczące bieżących problemów. Jeśli chcesz złożyć wniosek nowego problemu i dotyczą tworzenia natywnej części biblioteki, dołącz pełne dane wyjściowe z wiersza poleceń po uruchomieniu instrukcji README, aby ułatwić nam zdiagnozować problem.

Czy za pomocą ExoPlayer mogę odtwarzać filmy z YouTube bezpośrednio?

Nie, ExoPlayer nie może odtwarzać filmów z YouTube, takich jak URL-e formularza https://www.youtube.com/watch?v=... Zamiast tego używaj narzędzia YouTube IFrame Player API, To oficjalny sposób odtwarzania filmów z YouTube na urządzeniach z Androidem.

Odtwarzanie filmu się zacina

Urządzenie może nie być w stanie zdekodować treści wystarczająco szybko, jeśli na przykład: że szybkość lub rozdzielczość treści przekraczają możliwości urządzenia. Może być konieczne treści o niższej jakości i dobrze działać na takich urządzeniach.

Zacinanie się obrazu na urządzeniu z Androidem od Androida 6.0 (poziom interfejsu API 23) po Androida 11 (poziom API 30) włącznie zwłaszcza przy odtwarzaniu treści chronionych przez DRM lub treści o wysokiej liczbie klatek na sekundę. włączenie asynchronicznego kolejkowania w buforze.

Błędy lintowania niestabilnego interfejsu API

Media3 gwarantuje zgodność plików binarnych dla podzbioru powierzchni interfejsu API. części, które nie gwarantują zgodności binarnej, są oznaczone znakiem @UnstableApi. Aby wyraźnie podkreślić to rozróżnienie, zastosowania niestabilnych wersji Symbole interfejsu API generują błąd lint, chyba że mają adnotację @OptIn.

Adnotacja @UnstableApi nie sugeruje jakości ani działania interfejsu API, a jedynie fakt, że nie jest on „zablokowany przez API”.

Masz 2 możliwości postępowania z niestabilnymi błędami lintowania interfejsu API:

  • Przejdź na stabilny interfejs API, który pozwala osiągnąć ten sam efekt.
  • Nadal korzystaj z niestabilnego interfejsu API i dodaj do niego adnotacje dotyczące użycia za pomocą atrybutu @OptIn, zgodnie z wyświetli się później.
Dodawanie adnotacji @OptIn

Android Studio może pomóc Ci dodać adnotację:

Zrzut ekranu: jak dodać adnotację dotyczącą zgody
Rysunek 2. Dodawanie adnotacji @androidx.annotations.OptIn w Android Studio.

W Kotlin możesz też ręcznie dodawać adnotacje do konkretnych miejsc użytkowania:

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi

@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }

A także w języku Java:

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }

Aby zezwolić na używanie całych pakietów, wystarczy dodać plik package-info.java:

@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

Akceptację można włączyć dla całych projektów, eliminując konkretny błąd lintowania w Plik lint.xml:

 <?xml version="1.0" encoding="utf-8"?>
 <lint>
   <issue id="UnsafeOptInUsageError">
     <option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
   </issue>
 </lint>

Istnieje też adnotacja kotlin.OptIn, której nie należy używać. Jest Ważne jest, aby korzystać z adnotacji androidx.annotation.OptIn.