- Исправление ошибок типа «Запрещен трафик HTTP в открытом виде».
- Исправление ошибок "SSLHandshakeException", "CertPathValidatorException" и "ERR_CERT_AUTHORITY_INVALID".
- Почему некоторые медиафайлы невозможно перемотать?
- Почему в некоторых MP3-файлах поиск по файлу происходит неточно?
- Почему перемотка видео происходит медленно?
- Почему некоторые файлы MPEG-TS не воспроизводятся?
- Почему в некоторых файлах MPEG-TS отсутствуют субтитлы?
- Почему некоторые файлы MP4/FMP4 воспроизводятся некорректно?
- Почему некоторые потоки завершаются с ошибкой HTTP-ответа с кодом 301 или 302?
- Почему при потоковой передаче данных возникает ошибка UnrecognizedInputFormatException?
- Почему функция setPlaybackParameters некорректно работает на некоторых устройствах?
- Что означают ошибки "Доступ к плееру осуществляется в неправильном потоке"?
- Как исправить ошибку "Неожиданная строка состояния: ICY 200 OK"?
- Как я могу проверить, является ли воспроизводимый поток прямой трансляцией?
- Как сделать так, чтобы звук продолжал воспроизводиться, когда приложение находится в фоновом режиме?
- Почему ExoPlayer поддерживает мой контент, а библиотека ExoPlayer Cast — нет?
- Почему контент не воспроизводится, но при этом не отображается никаких ошибок?
- Как мне загрузить библиотеку декодирования и использовать её для воспроизведения?
- Можно ли воспроизводить видео с YouTube напрямую с помощью ExoPlayer?
- Воспроизведение видео прерывается.
- Нестабильные ошибки проверки кода API
Исправление ошибок типа «Запрещен трафик HTTP в открытом виде».
Эта ошибка возникнет, если ваше приложение запрашивает HTTP-трафик в открытом виде (то есть http:// вместо https:// ), когда его конфигурация сетевой безопасности это не разрешает. Если ваше приложение ориентировано на Android 9 (уровень API 28) или выше, HTTP-трафик в открытом виде отключен по умолчанию.
Если вашему приложению необходимо работать с HTTP-трафиком в открытом виде, вам потребуется использовать конфигурацию сетевой безопасности, которая это разрешает. Подробности см. в документации Android по сетевой безопасности . Чтобы разрешить весь HTTP-трафик в открытом виде, просто добавьте android:usesCleartextTraffic="true" в элемент application ` AndroidManifest.xml вашего приложения.
Демонстрационное приложение ExoPlayer использует конфигурацию сетевой безопасности по умолчанию, поэтому оно не разрешает HTTP-трафик в открытом виде. Вы можете включить его, следуя инструкциям выше.
Исправление ошибок "SSLHandshakeException", "CertPathValidatorException" и "ERR_CERT_AUTHORITY_INVALID".
SSLHandshakeException , CertPathValidatorException и ERR_CERT_AUTHORITY_INVALID указывают на проблему с SSL-сертификатом сервера. Эти ошибки не являются специфичными для ExoPlayer. Дополнительную информацию см. в документации по SSL для Android .
Почему некоторые медиафайлы невозможно перемотать?
По умолчанию ExoPlayer не поддерживает поиск в медиафайлах, где единственным способом точного поиска является сканирование и индексирование всего файла. ExoPlayer считает такие файлы недоступными для поиска. Большинство современных форматов медиаконтейнеров содержат метаданные для поиска (например, индекс образцов), имеют четко определенный алгоритм поиска (например, интерполированный поиск по бисекции для файлов Ogg) или указывают, что их содержимое имеет постоянный битрейт. В таких случаях эффективные операции поиска возможны и поддерживаются ExoPlayer.
Если вам требуется перемотка, но у вас есть медиафайлы, которые нельзя перемотать, мы рекомендуем преобразовать ваш контент в более подходящий формат контейнера. Для файлов MP3, ADTS и AMR вы также можете включить перемотку, предполагая, что файлы имеют постоянный битрейт, как описано здесь .
Почему в некоторых MP3-файлах поиск по файлу происходит неточно?
MP3-файлы с переменным битрейтом (VBR) принципиально непригодны для случаев, требующих точного перемотки. Этому есть две причины:
- Для точного поиска формат контейнера в идеале должен обеспечивать точное соответствие времени и байта в заголовке. Это соответствие позволяет проигрывателю сопоставить запрошенное время поиска с соответствующим смещением в байтах и начать запрос, анализ и воспроизведение медиафайлов с этого смещения. К сожалению, заголовки, доступные для указания этого соответствия в MP3 (например, заголовки XING), часто неточны.
- Для форматов контейнеров, которые не предоставляют точного соответствия времени и байтов (или вообще какого-либо соответствия времени и байтов), всё ещё возможно выполнить точный поиск, если контейнер включает в поток абсолютные метки времени сэмплов. В этом случае проигрыватель может сопоставить время поиска с наиболее вероятным смещением соответствующего байта, начать запрашивать медиафайлы с этого смещения, проанализировать первую абсолютную метку времени сэмпла и фактически выполнить управляемый бинарный поиск в медиафайлах, пока не найдёт нужный сэмпл. К сожалению, MP3 не включает абсолютные метки времени сэмплов в поток, поэтому этот подход невозможен.
По этим причинам единственный способ выполнить точный поиск в файле MP3 с переменным битрейтом (VBR) — это просканировать весь файл и вручную создать в плеере соответствие времени и байтов. Эту стратегию можно включить с помощью FLAG_ENABLE_INDEX_SEEKING , который можно установить для DefaultExtractorsFactory с помощью setMp3ExtractorFlags . Следует отметить, что он плохо масштабируется для больших файлов MP3, особенно если пользователь пытается перейти к концу потока вскоре после начала воспроизведения, что требует от плеера ожидания загрузки и индексации всего потока перед выполнением поиска. В ExoPlayer мы решили оптимизировать скорость, а не точность, поэтому FLAG_ENABLE_INDEX_SEEKING по умолчанию отключен.
Если вы контролируете воспроизводимый контент, мы настоятельно рекомендуем использовать более подходящий формат контейнера, например MP4. Нам неизвестны случаи, когда MP3 был бы лучшим выбором формата мультимедиа.
Почему перемотка видео происходит медленно?
При перемотке видео на новую позицию воспроизведения проигрывателю необходимо выполнить две действия:
- Загрузите в буфер данные, соответствующие новой позиции воспроизведения (это может быть необязательно, если эти данные уже находятся в буфере).
- Необходимо очистить видеодекодер и начать декодирование с I-кадра (ключевого кадра), предшествующего новой позиции воспроизведения, из-за внутрикадрового кодирования, используемого большинством форматов сжатия видео. Для обеспечения точности перемотки (то есть, начала воспроизведения точно с позиции перемотки) все кадры между предыдущим I-кадром и позицией перемотки должны быть декодированы и немедленно отброшены (без отображения на экране).
Задержку, вносимую (1), можно уменьшить либо за счет увеличения объема данных, буферизуемых в памяти проигрывателем, либо за счет предварительного кэширования данных на диск .
Задержку, вносимую (2), можно уменьшить либо за счет снижения точности поиска с помощью ExoPlayer.setSeekParameters , либо за счет перекодирования видео с более частыми I-кадрами (что приведет к увеличению размера выходного файла).
Почему некоторые файлы MPEG-TS не воспроизводятся?
Некоторые файлы MPEG-TS не содержат разделителей единиц доступа (AUD). По умолчанию ExoPlayer использует AUD для быстрого определения границ кадров. Аналогично, некоторые файлы MPEG-TS не содержат ключевых кадров IDR. По умолчанию ExoPlayer рассматривает только этот тип ключевых кадров.
При попытке воспроизведения файла MPEG-TS, в котором отсутствуют ключевые кадры AUD или IDR, ExoPlayer будет казаться зависшим в состоянии буферизации. Если вам необходимо воспроизводить такие файлы, вы можете сделать это, используя FLAG_DETECT_ACCESS_UNITS и FLAG_ALLOW_NON_IDR_KEYFRAMES соответственно. Эти флаги можно установить в DefaultExtractorsFactory с помощью setTsExtractorFlags или в DefaultHlsExtractorFactory с помощью конструктора . Использование FLAG_DETECT_ACCESS_UNITS не имеет побочных эффектов, кроме того, что оно является вычислительно затратным по сравнению с обнаружением границ кадров на основе AUD. Использование FLAG_ALLOW_NON_IDR_KEYFRAMES может привести к временным визуальным искажениям в начале воспроизведения и сразу после перемотки при воспроизведении некоторых файлов MPEG-TS.
Почему в некоторых файлах MPEG-TS отсутствуют субтитлы?
Некоторые файлы MPEG-TS содержат дорожки CEA-608, но не указывают их в метаданных контейнера, поэтому ExoPlayer не может их обнаружить. Вы можете вручную указать любые дорожки субтитров, предоставив список ожидаемых форматов субтитров в DefaultExtractorsFactory , включая каналы доступности, которые можно использовать для их идентификации в потоке MPEG-TS:
Котлин
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();
Почему некоторые файлы MP4/FMP4 воспроизводятся некорректно?
Некоторые файлы MP4/FMP4 содержат списки правок, которые перезаписывают временную шкалу медиафайла, пропуская, перемещая или повторяя списки сэмплов. ExoPlayer частично поддерживает применение списков правок. Например, он может задерживать или повторять группы сэмплов, начиная с синхронизирующего сэмпла, но не обрезает аудиосэмплы и не выполняет предварительную прокрутку медиафайлов для правок, которые не начинаются с синхронизирующего сэмпла.
Если вы заметили, что часть медиафайла неожиданно отсутствует или повторяется, попробуйте установить Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS или FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS , что заставит экстрактор полностью игнорировать списки редактирования. Эти флаги можно установить в DefaultExtractorsFactory с помощью setMp4ExtractorFlags или setFragmentedMp4ExtractorFlags .
Почему некоторые потоки завершаются с ошибкой HTTP-ответа с кодом 301 или 302?
Коды HTTP-ответа 301 и 302 указывают на перенаправление. Краткое описание можно найти в Википедии . Когда ExoPlayer отправляет запрос и получает ответ со статусом 301 или 302, он обычно следует перенаправлению и начинает воспроизведение в обычном режиме. Единственный случай, когда это не происходит по умолчанию, — это межпротокольные перенаправления. Межпротокольное перенаправление — это перенаправление с HTTPS на HTTP или наоборот (или, реже, между другой парой протоколов). Вы можете проверить, вызывает ли URL-адрес межпротокольное перенаправление, используя инструмент командной строки wget следующим образом:
wget "https://yourserver.example.com/test.mp3" 2>&1 | grep Location
Результат должен выглядеть примерно так:
Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]
В этом примере есть два перенаправления. Первое перенаправление — с https://yourserver.example.com/test.mp3 на https://secondserver.example.net/test.mp3 . Оба используют HTTPS, поэтому это не кросс-протокольное перенаправление. Второе перенаправление — с https://secondserver.example.net/test.mp3 на http://thirdserver.example.org/test.mp3 . Это перенаправление с HTTPS на HTTP, поэтому это кросс-протокольное перенаправление. ExoPlayer не будет следовать этому перенаправлению в своей конфигурации по умолчанию, что означает, что воспроизведение не удастся.
При необходимости вы можете настроить ExoPlayer для отслеживания перенаправлений между протоколами при создании экземпляров DefaultHttpDataSource.Factory , используемых в вашем приложении. Подробнее о выборе и настройке сетевого стека можно узнать здесь .
Почему при потоковой передаче данных возникает ошибка UnrecognizedInputFormatException?
Этот вопрос касается сбоев воспроизведения следующего вида:
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
Возможны две причины этой ошибки. Наиболее распространенная причина заключается в том, что вы пытаетесь воспроизвести контент DASH (mpd), HLS (m3u8) или SmoothStreaming (ism, isml), но плеер пытается воспроизвести его как прогрессивный поток. Для воспроизведения таких потоков необходимо использовать соответствующий модуль ExoPlayer . В случаях, когда URI потока не заканчивается стандартным расширением файла, вы также можете передать MimeTypes.APPLICATION_MPD , MimeTypes.APPLICATION_M3U8 или MimeTypes.APPLICATION_SS в setMimeType объекта MediaItem.Builder , чтобы явно указать тип потока.
Вторая, менее распространённая причина, заключается в том, что ExoPlayer не поддерживает формат контейнера медиафайлов, которые вы пытаетесь воспроизвести. В этом случае ошибка является ожидаемым результатом, однако вы можете отправить запрос на добавление функции в наш трекер проблем , указав подробности о формате контейнера и тестовый поток. Пожалуйста, поищите уже существующий запрос на добавление функции, прежде чем отправлять новый.
Почему функция setPlaybackParameters некорректно работает на некоторых устройствах?
При запуске отладочной сборки вашего приложения на Android M и более ранних версиях вы можете столкнуться с нестабильной производительностью, звуковыми артефактами и высокой загрузкой ЦП при использовании API setPlaybackParameters . Это связано с тем, что важная для этого API оптимизация отключена для отладочных сборок, работающих на этих версиях Android.
Важно отметить, что эта проблема затрагивает только отладочные сборки. Она не влияет на релизные сборки, для которых оптимизация всегда включена. Следовательно, релизы, которые вы предоставляете конечным пользователям, не должны быть затронуты этой проблемой.
Что означают ошибки "Доступ к плееру осуществляется в неправильном потоке"?
См. примечание о нитях на странице "Начало работы".
Как исправить ошибку "Неожиданная строка состояния: ICY 200 OK"?
Эта проблема может возникнуть, если ответ сервера содержит строку состояния ICY, а не строку, соответствующую протоколу HTTP. Строки состояния ICY устарели и не должны использоваться, поэтому, если вы управляете сервером, вам следует обновить его, чтобы он предоставлял ответ, соответствующий протоколу HTTP. Если это невозможно, то использование библиотеки ExoPlayer OkHttp решит проблему, поскольку она корректно обрабатывает строки состояния ICY.
Как я могу проверить, является ли воспроизводимый поток прямой трансляцией?
Вы можете запросить метод isCurrentWindowLive проигрывателя. Кроме того, вы можете проверить isCurrentWindowDynamic чтобы узнать, является ли окно динамическим (то есть, продолжает ли оно обновляться со временем).
Как сделать так, чтобы звук продолжал воспроизводиться, когда приложение находится в фоновом режиме?
Выполните следующие действия, чтобы обеспечить непрерывное воспроизведение аудио, когда ваше приложение находится в фоновом режиме:
- Для корректной работы системы необходимо запустить службу переднего плана . Это предотвратит завершение процесса системой для освобождения ресурсов.
- Необходимо удерживать блокировки
WifiLockиWakeLock. Они гарантируют, что система будет поддерживать активность Wi-Fi-модуля и процессора. Это легко сделать при использованииExoPlayer, вызвавsetWakeMode, который автоматически получит и освободит необходимые блокировки в нужное время.
Важно снять блокировки (если не используется setWakeMode ) и остановить службу, как только воспроизведение звука прекратится.
Почему ExoPlayer поддерживает мой контент, а библиотека ExoPlayer Cast — нет?
Возможно, контент, который вы пытаетесь воспроизвести, не поддерживает CORS . Для воспроизведения контента в рамках платформы Cast требуется поддержка CORS.
Почему контент не воспроизводится, но при этом не отображается никаких ошибок?
Возможно, устройство, на котором вы воспроизводите контент, не поддерживает определенный формат медиафайлов. Это легко подтвердить, добавив EventLogger в качестве слушателя к вашему плееру и найдя в Logcat строку, похожую на эту:
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
NO_UNSUPPORTED_TYPE означает, что устройство не может декодировать формат медиафайлов, указанный в mimeType . Информацию о поддерживаемых форматах медиафайлов см. в документации Android . Как загрузить и использовать библиотеку декодирования для воспроизведения? Это также может быть полезно.
Как мне загрузить библиотеку декодирования и использовать её для воспроизведения?
- В большинстве библиотек декодеров требуется выполнить ручную проверку и сборку зависимостей, поэтому убедитесь, что вы выполнили все шаги, описанные в файле README для соответствующей библиотеки. Например, для библиотеки ExoPlayer FFmpeg необходимо следовать инструкциям в файле libraries/decoder_ffmpeg/README.md , включая передачу флагов конфигурации для включения декодеров для любых форматов, которые вы хотите воспроизводить.
- Для библиотек, содержащих нативный код, убедитесь, что вы используете правильную версию Android NDK, указанную в файле README, и следите за любыми ошибками, которые могут возникнуть во время настройки и сборки. После выполнения шагов, описанных в файле README, вы должны увидеть файлы
.soв подкаталогеlibsпути к библиотеке для каждой поддерживаемой архитектуры. - Чтобы протестировать воспроизведение с использованием библиотеки в демонстрационном приложении , см. раздел «Включение встроенных декодеров» . Инструкции по использованию библиотеки в вашем собственном приложении см. в файле README библиотеки.
- Если вы используете
DefaultRenderersFactory, в Logcat при загрузке декодера вы должны увидеть строку информационного уровня, например, "Loaded FfmpegAudioRenderer". Если она отсутствует, убедитесь, что приложение зависит от библиотеки декодирования. - Если в Logcat вы видите предупреждения от
LibraryLoader, это означает, что загрузка нативного компонента библиотеки завершилась неудачей. В этом случае убедитесь, что вы правильно выполнили шаги, описанные в файле README библиотеки, и что при выполнении инструкций не было обнаружено никаких ошибок.
Если у вас по-прежнему возникают проблемы с использованием библиотек декодирования, пожалуйста, проверьте систему отслеживания ошибок Media3 на наличие актуальных проблем. Если вам необходимо создать новую проблему, связанную со сборкой нативной части библиотеки, пожалуйста, приложите полный вывод командной строки из инструкций README, чтобы помочь нам диагностировать проблему.
Можно ли воспроизводить видео с YouTube напрямую с помощью ExoPlayer?
Нет, ExoPlayer не может воспроизводить видео с YouTube, например, URL-адреса вида https://www.youtube.com/watch?v=... . Вместо этого следует использовать API YouTube IFrame Player , который является официальным способом воспроизведения видео YouTube на Android.
Воспроизведение видео прерывается.
Устройство может оказаться неспособным декодировать контент достаточно быстро, если, например, битрейт или разрешение контента превышают его возможности. В этом случае для обеспечения хорошей производительности на таких устройствах может потребоваться использование контента более низкого качества.
Если вы сталкиваетесь с подтормаживанием видео на устройстве под управлением Android версии от 6.0 (уровень API 23) до Android 11 (уровень API 30) включительно, особенно при воспроизведении контента с DRM-защитой или высокой частотой кадров, вы можете попробовать включить асинхронную буферизацию .
Нестабильные ошибки проверки кода API
Media3 гарантирует бинарную совместимость для части API. Части, для которых бинарная совместимость не гарантируется, помечены аннотацией @UnstableApi . Чтобы это различие было очевидным, использование символов нестабильного API приводит к ошибке линтера, если они не помечены аннотацией @OptIn .
Аннотация @UnstableApi ничего не говорит о качестве или производительности API, а лишь о том, что он не "заморожен".
Для обработки нестабильных ошибок проверки API у вас есть два варианта:
- Переключитесь на использование стабильного API, который обеспечивает тот же результат.
- Продолжайте использовать нестабильный API и аннотируйте его использование с помощью
@OptIn, как показано далее.
Добавьте аннотацию @OptIn
В Android Studio вы можете добавить аннотацию:

Вы также можете вручную помечать конкретные сайты использования:
Котлин
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
Java
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }
Для включения в программу можно добавить файл package-info для целых пакетов:
Котлин
// In your package-info.kt
@OptIn(UnstableApi::class)
package name.of.your.package
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
Java
// In your package-info.java
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
Для включения этой функции можно отключить проверку кода для целых проектов, указав конкретную ошибку в их файле 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>
Существует также аннотация kotlin.OptIn , которую не следует использовать. Важно использовать аннотацию androidx.annotation.OptIn .