Основное демонстрационное приложение ExoPlayer выполняет две основные функции:
- Цель данного примера — продемонстрировать относительно простое, но полнофункциональное использование ExoPlayer. Демонстрационное приложение может служить удобной отправной точкой для разработки собственного приложения.
- Чтобы упростить тестирование ExoPlayer, в демо-версии приложения, помимо включенных в комплект примеров, можно проверить воспроизведение собственного контента.
На этой странице описано, как получить, скомпилировать и запустить демонстрационное приложение. Также описано, как использовать его для воспроизведения собственных медиафайлов.
Получение кода
Исходный код основного демонстрационного приложения можно найти в папке demos/main нашего проекта на GitHub . Если вы еще этого не сделали, клонируйте проект в локальную директорию:
git clone https://github.com/androidx/media.git
Далее откройте проект в Android Studio. В окне проекта Android вы должны увидеть следующее (соответствующие папки демонстрационного приложения развернуты):

Компиляция и запуск
Для компиляции и запуска демонстрационного приложения выберите и запустите конфигурацию demo в Android Studio. Демонстрационное приложение будет установлено и запущено на подключенном устройстве Android. Мы рекомендуем использовать физическое устройство, если это возможно. Если вы хотите использовать эмулятор, пожалуйста, ознакомьтесь с разделом «Поддерживаемые устройства» в разделе «Эмуляторы» и убедитесь, что ваше виртуальное устройство использует образ системы с уровнем API не ниже 23.

Демонстрационное приложение отображает список сэмплов ( SampleChooserActivity ). Выбор сэмпла откроет второе окно ( PlayerActivity ) для воспроизведения. Демонстрационное приложение включает элементы управления воспроизведением и функцию выбора треков. Оно также использует вспомогательный класс EventLogger из ExoPlayer для вывода полезной отладочной информации в системный журнал. Этот журнал (а также журнал ошибок для других тегов) можно просмотреть с помощью команды:
adb logcat EventLogger:V *:E
Включение встроенных декодеров
ExoPlayer имеет ряд расширений, позволяющих использовать встроенные программные декодеры, включая AV1, VP9, Opus, FLAC и FFmpeg (только аудио). Демонстрационное приложение можно собрать с учетом этих расширений следующим образом:
- Соберите каждое из расширений, которые вы хотите включить. Обратите внимание, что это ручной процесс. Инструкции см. в файле
README.mdкаждого расширения. В окне «Варианты сборки» в Android Studio установите вариант сборки для демонстрационного модуля на
withDecoderExtensionsDebugилиwithDecoderExtensionsReleaseкак показано на следующем изображении.
Скомпилируйте, установите и запустите
demoконфигурацию в обычном режиме.
По умолчанию расширенный декодер будет использоваться только в том случае, если подходящий декодер для платформы отсутствует. Можно указать, что предпочтение следует отдавать расширенным декодерам, как описано в следующих разделах.
Воспроизведение собственного контента
В демо-версии приложения есть несколько способов воспроизведения собственного контента.
1. Редактирование файла assets/media.exolist.json
Примеры, перечисленные в демонстрационном приложении, загружаются из assets/media.exolist.json . Редактируя этот JSON-файл, можно добавлять и удалять примеры из демонстрационного приложения. Схема выглядит следующим образом, где [O] обозначает необязательный атрибут.
[
{
"name": "Name of heading",
"samples": [
{
"name": "Name of sample",
"uri": "The URI of the sample",
"extension": "[O] Sample type hint. Cannot be combined with mime_type. Values: mpd, ism, m3u8",
"clip_start_position_ms": "[O] A start point to which the sample should be clipped, in milliseconds"
"clip_end_position_ms": "[O] An end point from which the sample should be clipped, in milliseconds"
"drm_scheme": "[O] Drm scheme if protected. Values: widevine, playready, clearkey",
"drm_license_uri": "[O] URI of the license server if protected",
"drm_force_default_license_uri": "[O] Whether to force use of "drm_license_uri" for key requests that include their own license URI",
"drm_key_request_properties": "[O] Key request headers if protected",
"drm_session_for_clear_content": "[O] Whether to attach a DRM session to clear video and audio tracks"
"drm_multi_session": "[O] Enables key rotation if protected",
"mime_type": "[O] The MIME type of the sample. Cannot be combined with extension.",
"subtitle_uri": "[O] The URI of a subtitle sidecar file",
"subtitle_mime_type": "[O] The MIME type of subtitle_uri (required if subtitle_uri is set)",
"subtitle_language": "[O] The BCP47 language code of the subtitle file (ignored if subtitle_uri is not set)",
"ad_tag_uri": "[O] The URI of an ad tag to load via the IMA extension"
},
...etc
]
},
...etc
]
Списки сэмплов можно задать с помощью схемы:
[
{
"name": "Name of heading",
"samples": [
{
"name": "Name of playlist sample",
"playlist": [
{
"uri": "The URI of the first sample in the playlist",
"extension": "[O] Sample type hint. Cannot be combined with mime_type. Values: mpd, ism, m3u8"
"clip_start_position_ms": "[O] A start point to which the sample should be clipped, in milliseconds"
"clip_end_position_ms": "[O] An end point from which the sample should be clipped, in milliseconds"
"drm_scheme": "[O] Drm scheme if protected. Values: widevine, playready, clearkey",
"drm_license_uri": "[O] URI of the license server if protected",
"drm_force_default_license_uri": "[O] Whether to force use of "drm_license_uri" for key requests that include their own license URI",
"drm_key_request_properties": "[O] Key request headers if protected",
"drm_session_for_clear_content": "[O] Whether to attach a DRM session to clear video and audio tracks",
"drm_multi_session": "[O] Enables key rotation if protected",
"mime_type": "[O] The MIME type of the sample. Cannot be combined with extension.",
"subtitle_uri": "[O] The URI of a subtitle sidecar file",
"subtitle_mime_type": "[O] The MIME type of subtitle_uri (required if subtitle_uri is set)",
"subtitle_language": "[O] The BCP47 language code of the subtitle file (ignored if subtitle_uri is not set)"
},
{
"uri": "The URI of the second sample in the playlist",
...etc
},
...etc
]
},
...etc
]
},
...etc
]
При необходимости ключевые заголовки запроса указываются в виде объекта, содержащего строковый атрибут для каждого заголовка:
"drm_key_request_properties": {
"name1": "value1",
"name2": "value2",
...etc
}
В окне выбора примера в дополнительном меню можно указать, следует ли отдавать предпочтение декодерам расширений.
URI локальных файлов и ограничения на область хранения.
При указании локальных URI файлов демонстрационное приложение запрашивает необходимые разрешения на доступ к хранилищу для чтения этих файлов. Однако, начиная с Android 13, невозможно загружать произвольные файлы, не имеющие типичного расширения медиафайла (например, .mp4 ). Если вам необходимо загрузить такой файл, вы можете поместить его в специальный каталог хранилища демонстрационного приложения, не имеющий ограничений доступа. Обычно он находится по адресу /sdcard/Android/data/androidx.media3.demo.main/files .
2. Загрузка внешнего файла exolist.json
Демонстрационное приложение может загружать внешние JSON-файлы, используя указанную выше схему и именуя их в соответствии с соглашением *.exolist.json . Например, если вы разместили такой файл по адресу https://yourdomain.com/samples.exolist.json , вы можете открыть его в демонстрационном приложении, используя:
adb shell am start -a android.intent.action.VIEW \
-d https://yourdomain.com/samples.exolist.json
Нажатие на ссылку *.exolist.json (например, в браузере или почтовом клиенте) на устройстве с установленным демонстрационным приложением также откроет её в демонстрационном приложении. Таким образом, размещение JSON-файла *.exolist.json предоставляет простой способ распространения контента, чтобы другие могли попробовать его в демонстрационном приложении.
3. Выстрел с намерением
Интенты можно использовать для обхода списка сэмплов и запуска воспроизведения напрямую. Чтобы воспроизвести один сэмпл, установите действие интента на androidx.media3.demo.main.action.VIEW , а его URI данных — на URI воспроизводимого сэмпла. Такой интент можно запустить из терминала, используя:
adb shell am start -a androidx.media3.demo.main.action.VIEW \
-d https://yourdomain.com/sample.mp4
Для одного примера намерения поддерживаются следующие дополнительные параметры:
- Пример дополнительных параметров конфигурации:
-
mime_type[String] Пример подсказки типа MIME. Например,application/dash+xmlдля содержимого DASH. -
clip_start_position_ms[Long] Начальная точка, до которой следует обрезать сэмпл, в миллисекундах. -
clip_end_position_ms[Long] Конечная точка, от которой следует обрезать сэмпл, в миллисекундах. -
drm_scheme[String] Схема DRM, если она защищена. Допустимые значения:widevine,playreadyиclearkey. Также принимаются UUID схем DRM. -
drm_license_uri[String] URI сервера лицензий, если лицензия защищена. -
drm_force_default_license_uri[Логическое значение] Указывает, следует ли принудительно использоватьdrm_license_uriдля запросов ключей, содержащих собственный URI лицензии. -
drm_key_request_properties[Строковый массив] Заголовки запроса ключа, упакованные как name1, value1, name2, value2 и т. д., если они защищены. -
drm_session_for_clear_content[Логическое значение] Следует ли прикреплять сессию DRM к видео- и аудиодорожкам с защитой DRM. -
drm_multi_session[Логическое значение] Включает ротацию клавиш, если она защищена. -
subtitle_uri[String] URI файла-дополнения к субтитрам. -
subtitle_mime_type[String] MIME-тип subtitle_uri (обязательно, если subtitle_uri задан). -
subtitle_language[String] Языковой код BCP47 файла субтитров (игнорируется, если subtitle_uri не задан). -
ad_tag_uri[Строка] URI рекламного тега для загрузки с использованием [расширения IMA][]. -
prefer_extension_decoders[Boolean] Указывает, какие декодеры расширений предпочтительнее, чем декодеры платформы.
-
При использовании adb shell am start для запуска интента можно задать необязательный строковый параметр с помощью --es (например, --es extension mpd ). Необязательный логический параметр можно задать с помощью --ez (например, --ez prefer_extension_decoders TRUE ). Необязательный параметр типа long можно задать с помощью --el (например, --el clip_start_position_ms 5000 ). Необязательный параметр типа string array можно задать с помощью --esa (например, --esa drm_key_request_properties name1,value1 ).
Чтобы воспроизвести плейлист с сэмплами, установите действие интента на androidx.media3.demo.main.action.VIEW_LIST . Дополнительные параметры конфигурации сэмплов остаются такими же, как и для androidx.media3.demo.main.action.VIEW , за исключением двух отличий:
- Ключи дополнительных параметров должны иметь символ подчеркивания и суффикс, указывающий на индекс образца (начиная с 0). Например,
extension_0укажет тип образца для первого образца.drm_scheme_1установит схему DRM для второго образца. - URI образца передается в качестве дополнительного параметра с ключом
uri_<sample-index>.
Другие дополнительные параметры, не зависящие от сэмпла, остаются неизменными. Например, вы можете выполнить следующую команду в терминале, чтобы воспроизвести плейлист с двумя элементами, заменив расширение второго элемента:
adb shell am start -a androidx.media3.demo.main.action.VIEW_LIST \
--es uri_0 https://a.com/sample1.mp4 \
--es uri_1 https://b.com/sample2.fake_mpd \
--es extension_1 mpd
Основное демонстрационное приложение ExoPlayer выполняет две основные функции:
- Цель данного примера — продемонстрировать относительно простое, но полнофункциональное использование ExoPlayer. Демонстрационное приложение может служить удобной отправной точкой для разработки собственного приложения.
- Чтобы упростить тестирование ExoPlayer, в демо-версии приложения, помимо включенных в комплект примеров, можно проверить воспроизведение собственного контента.
На этой странице описано, как получить, скомпилировать и запустить демонстрационное приложение. Также описано, как использовать его для воспроизведения собственных медиафайлов.
Получение кода
Исходный код основного демонстрационного приложения можно найти в папке demos/main нашего проекта на GitHub . Если вы еще этого не сделали, клонируйте проект в локальную директорию:
git clone https://github.com/androidx/media.git
Далее откройте проект в Android Studio. В окне проекта Android вы должны увидеть следующее (соответствующие папки демонстрационного приложения развернуты):

Компиляция и запуск
Для компиляции и запуска демонстрационного приложения выберите и запустите конфигурацию demo в Android Studio. Демонстрационное приложение будет установлено и запущено на подключенном устройстве Android. Мы рекомендуем использовать физическое устройство, если это возможно. Если вы хотите использовать эмулятор, пожалуйста, ознакомьтесь с разделом «Поддерживаемые устройства» в разделе «Эмуляторы» и убедитесь, что ваше виртуальное устройство использует образ системы с уровнем API не ниже 23.

Демонстрационное приложение отображает список сэмплов ( SampleChooserActivity ). Выбор сэмпла откроет второе окно ( PlayerActivity ) для воспроизведения. Демонстрационное приложение включает элементы управления воспроизведением и функцию выбора треков. Оно также использует вспомогательный класс EventLogger из ExoPlayer для вывода полезной отладочной информации в системный журнал. Этот журнал (а также журнал ошибок для других тегов) можно просмотреть с помощью команды:
adb logcat EventLogger:V *:E
Включение встроенных декодеров
ExoPlayer имеет ряд расширений, позволяющих использовать встроенные программные декодеры, включая AV1, VP9, Opus, FLAC и FFmpeg (только аудио). Демонстрационное приложение можно собрать с учетом этих расширений следующим образом:
- Соберите каждое из расширений, которые вы хотите включить. Обратите внимание, что это ручной процесс. Инструкции см. в файле
README.mdкаждого расширения. В окне «Варианты сборки» в Android Studio установите вариант сборки для демонстрационного модуля на
withDecoderExtensionsDebugилиwithDecoderExtensionsReleaseкак показано на следующем изображении.
Скомпилируйте, установите и запустите
demoконфигурацию в обычном режиме.
По умолчанию расширенный декодер будет использоваться только в том случае, если подходящий декодер для платформы отсутствует. Можно указать, что предпочтение следует отдавать расширенным декодерам, как описано в следующих разделах.
Воспроизведение собственного контента
В демо-версии приложения есть несколько способов воспроизведения собственного контента.
1. Редактирование файла assets/media.exolist.json
Примеры, перечисленные в демонстрационном приложении, загружаются из assets/media.exolist.json . Редактируя этот JSON-файл, можно добавлять и удалять примеры из демонстрационного приложения. Схема выглядит следующим образом, где [O] обозначает необязательный атрибут.
[
{
"name": "Name of heading",
"samples": [
{
"name": "Name of sample",
"uri": "The URI of the sample",
"extension": "[O] Sample type hint. Cannot be combined with mime_type. Values: mpd, ism, m3u8",
"clip_start_position_ms": "[O] A start point to which the sample should be clipped, in milliseconds"
"clip_end_position_ms": "[O] An end point from which the sample should be clipped, in milliseconds"
"drm_scheme": "[O] Drm scheme if protected. Values: widevine, playready, clearkey",
"drm_license_uri": "[O] URI of the license server if protected",
"drm_force_default_license_uri": "[O] Whether to force use of "drm_license_uri" for key requests that include their own license URI",
"drm_key_request_properties": "[O] Key request headers if protected",
"drm_session_for_clear_content": "[O] Whether to attach a DRM session to clear video and audio tracks"
"drm_multi_session": "[O] Enables key rotation if protected",
"mime_type": "[O] The MIME type of the sample. Cannot be combined with extension.",
"subtitle_uri": "[O] The URI of a subtitle sidecar file",
"subtitle_mime_type": "[O] The MIME type of subtitle_uri (required if subtitle_uri is set)",
"subtitle_language": "[O] The BCP47 language code of the subtitle file (ignored if subtitle_uri is not set)",
"ad_tag_uri": "[O] The URI of an ad tag to load via the IMA extension"
},
...etc
]
},
...etc
]
Списки сэмплов можно задать с помощью схемы:
[
{
"name": "Name of heading",
"samples": [
{
"name": "Name of playlist sample",
"playlist": [
{
"uri": "The URI of the first sample in the playlist",
"extension": "[O] Sample type hint. Cannot be combined with mime_type. Values: mpd, ism, m3u8"
"clip_start_position_ms": "[O] A start point to which the sample should be clipped, in milliseconds"
"clip_end_position_ms": "[O] An end point from which the sample should be clipped, in milliseconds"
"drm_scheme": "[O] Drm scheme if protected. Values: widevine, playready, clearkey",
"drm_license_uri": "[O] URI of the license server if protected",
"drm_force_default_license_uri": "[O] Whether to force use of "drm_license_uri" for key requests that include their own license URI",
"drm_key_request_properties": "[O] Key request headers if protected",
"drm_session_for_clear_content": "[O] Whether to attach a DRM session to clear video and audio tracks",
"drm_multi_session": "[O] Enables key rotation if protected",
"mime_type": "[O] The MIME type of the sample. Cannot be combined with extension.",
"subtitle_uri": "[O] The URI of a subtitle sidecar file",
"subtitle_mime_type": "[O] The MIME type of subtitle_uri (required if subtitle_uri is set)",
"subtitle_language": "[O] The BCP47 language code of the subtitle file (ignored if subtitle_uri is not set)"
},
{
"uri": "The URI of the second sample in the playlist",
...etc
},
...etc
]
},
...etc
]
},
...etc
]
При необходимости ключевые заголовки запроса указываются в виде объекта, содержащего строковый атрибут для каждого заголовка:
"drm_key_request_properties": {
"name1": "value1",
"name2": "value2",
...etc
}
В окне выбора примера в дополнительном меню можно указать, следует ли отдавать предпочтение декодерам расширений.
URI локальных файлов и ограничения на область хранения.
При указании локальных URI файлов демонстрационное приложение запрашивает необходимые разрешения на доступ к хранилищу для чтения этих файлов. Однако, начиная с Android 13, невозможно загружать произвольные файлы, не имеющие типичного расширения медиафайла (например, .mp4 ). Если вам необходимо загрузить такой файл, вы можете поместить его в специальный каталог хранилища демонстрационного приложения, не имеющий ограничений доступа. Обычно он находится по адресу /sdcard/Android/data/androidx.media3.demo.main/files .
2. Загрузка внешнего файла exolist.json
Демонстрационное приложение может загружать внешние JSON-файлы, используя указанную выше схему и именуя их в соответствии с соглашением *.exolist.json . Например, если вы разместили такой файл по адресу https://yourdomain.com/samples.exolist.json , вы можете открыть его в демонстрационном приложении, используя:
adb shell am start -a android.intent.action.VIEW \
-d https://yourdomain.com/samples.exolist.json
Нажатие на ссылку *.exolist.json (например, в браузере или почтовом клиенте) на устройстве с установленным демонстрационным приложением также откроет её в демонстрационном приложении. Таким образом, размещение JSON-файла *.exolist.json предоставляет простой способ распространения контента, чтобы другие могли попробовать его в демонстрационном приложении.
3. Выстрел с намерением
Интенты можно использовать для обхода списка сэмплов и запуска воспроизведения напрямую. Чтобы воспроизвести один сэмпл, установите действие интента на androidx.media3.demo.main.action.VIEW , а его URI данных — на URI воспроизводимого сэмпла. Такой интент можно запустить из терминала, используя:
adb shell am start -a androidx.media3.demo.main.action.VIEW \
-d https://yourdomain.com/sample.mp4
Для одного примера намерения поддерживаются следующие дополнительные параметры:
- Пример дополнительных параметров конфигурации:
-
mime_type[String] Пример подсказки типа MIME. Например,application/dash+xmlдля содержимого DASH. -
clip_start_position_ms[Long] Начальная точка, до которой следует обрезать сэмпл, в миллисекундах. -
clip_end_position_ms[Long] Конечная точка, от которой следует обрезать сэмпл, в миллисекундах. -
drm_scheme[String] Схема DRM, если она защищена. Допустимые значения:widevine,playreadyиclearkey. Также принимаются UUID схем DRM. -
drm_license_uri[String] URI сервера лицензий, если лицензия защищена. -
drm_force_default_license_uri[Логическое значение] Указывает, следует ли принудительно использоватьdrm_license_uriдля запросов ключей, содержащих собственный URI лицензии. -
drm_key_request_properties[Строковый массив] Заголовки запроса ключа, упакованные как name1, value1, name2, value2 и т. д., если они защищены. -
drm_session_for_clear_content[Логическое значение] Следует ли прикреплять сессию DRM к видео- и аудиодорожкам с защитой DRM. -
drm_multi_session[Логическое значение] Включает ротацию клавиш, если она защищена. -
subtitle_uri[String] URI файла-дополнения к субтитрам. -
subtitle_mime_type[String] MIME-тип subtitle_uri (обязательно, если subtitle_uri задан). -
subtitle_language[String] Языковой код BCP47 файла субтитров (игнорируется, если subtitle_uri не задан). -
ad_tag_uri[Строка] URI рекламного тега для загрузки с использованием [расширения IMA][]. -
prefer_extension_decoders[Boolean] Указывает, какие декодеры расширений предпочтительнее, чем декодеры платформы.
-
При использовании adb shell am start для запуска интента можно задать необязательный строковый параметр с помощью --es (например, --es extension mpd ). Необязательный логический параметр можно задать с помощью --ez (например, --ez prefer_extension_decoders TRUE ). Необязательный параметр типа long можно задать с помощью --el (например, --el clip_start_position_ms 5000 ). Необязательный параметр типа string array можно задать с помощью --esa (например, --esa drm_key_request_properties name1,value1 ).
Чтобы воспроизвести плейлист с сэмплами, установите действие интента на androidx.media3.demo.main.action.VIEW_LIST . Дополнительные параметры конфигурации сэмплов остаются такими же, как и для androidx.media3.demo.main.action.VIEW , за исключением двух отличий:
- Ключи дополнительных параметров должны иметь символ подчеркивания и суффикс, указывающий на индекс образца (начиная с 0). Например,
extension_0укажет тип образца для первого образца.drm_scheme_1установит схему DRM для второго образца. - URI образца передается в качестве дополнительного параметра с ключом
uri_<sample-index>.
Другие дополнительные параметры, не зависящие от сэмпла, остаются неизменными. Например, вы можете выполнить следующую команду в терминале, чтобы воспроизвести плейлист с двумя элементами, заменив расширение второго элемента:
adb shell am start -a androidx.media3.demo.main.action.VIEW_LIST \
--es uri_0 https://a.com/sample1.mp4 \
--es uri_1 https://b.com/sample2.fake_mpd \
--es extension_1 mpd