Aplicación de demostración de ExoPlayer

La app de demostración principal de ExoPlayer tiene dos propósitos principales:

  1. Proporcionar un ejemplo relativamente simple, pero con todas las funciones, del uso de ExoPlayer La app de demostración se puede usar como un punto de partida conveniente para desarrollar tu propia app.
  2. Facilitar la prueba de ExoPlayer La app de demostración se puede usar para probar la reproducción de tu propio contenido, además de las muestras incluidas.

En esta página, se describe cómo obtener, compilar y ejecutar la app de demostración, y cómo usarla para reproducir tu propio contenido multimedia.

Cómo obtener el código

El código fuente de la app de demostración principal se puede encontrar en la carpeta demos/main de nuestro proyecto de GitHub. Si aún no lo hiciste, clona el proyecto en un directorio local:

git clone https://github.com/androidx/media.git

A continuación, abre el proyecto en Android Studio. Deberías ver lo siguiente en la vista Android Project (se expandieron las carpetas pertinentes de la app de demostración):

El proyecto en Android Studio

Compilación y ejecución

Para compilar y ejecutar la app de demostración, selecciona y ejecuta la configuración demo en Android Studio. La app de demostración se instalará y ejecutará en un dispositivo Android conectado. Si es posible, te recomendamos que uses un dispositivo físico. Si deseas usar un emulador, lee la sección de emuladores en Dispositivos compatibles y asegúrate de que tu dispositivo virtual use una imagen del sistema con un nivel de API de al menos 23.

SampleChooserActivity y PlayerActivity

La app de demostración presenta una lista de muestras (SampleChooserActivity). Si se selecciona una muestra, se abrirá una segunda actividad (PlayerActivity) para la reproducción. La demostración incluye controles de reproducción y la función de selección de pistas. También usa la clase de utilidad EventLogger de ExoPlayer para generar información de depuración útil en el registro del sistema. Este registro se puede ver (junto con el registro de nivel de error para otras etiquetas) con el siguiente comando:

adb logcat EventLogger:V *:E

Cómo habilitar los decodificadores agrupados

ExoPlayer tiene varias extensiones que permiten usar decodificadores de software incluidos, como AV1, VP9, Opus, FLAC y FFmpeg (solo audio). La app de demostración se puede compilar para incluir y usar estas extensiones de la siguiente manera:

  1. Compila cada una de las extensiones que quieras incluir. Ten en cuenta que este es un proceso manual. Consulta el archivo README.md en cada extensión para obtener instrucciones.
  2. En la vista Build Variants de Android Studio, establece la variante de compilación del módulo de demostración en withDecoderExtensionsDebug o withDecoderExtensionsRelease, como se muestra en la siguiente imagen.

    Selección de la variante de compilación de demostración `withDecoderExtensionsDebug`

  3. Compila, instala y ejecuta la configuración de demo de forma habitual.

De forma predeterminada, solo se usará un decodificador de extensión si no existe un decodificador de plataforma adecuado. Es posible especificar que se prefieran los decodificadores de extensión, como se describe en las siguientes secciones.

Cómo reproducir tu propio contenido

Hay varias formas de reproducir tu propio contenido en la app de demostración.

1. Cómo editar assets/media.exolist.json

Las muestras que se enumeran en la app de demostración se cargan desde assets/media.exolist.json. Si editas este archivo JSON, puedes agregar y quitar muestras de la app de demostración. El esquema es el siguiente, donde [O] indica un atributo opcional.

[
  {
    "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
]

Las playlists de muestras se pueden especificar con el siguiente esquema:

[
  {
    "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
]

Si es necesario, los encabezados de solicitud clave se especifican como un objeto que contiene un atributo de cadena para cada encabezado:

"drm_key_request_properties": {
  "name1": "value1",
  "name2": "value2",
  ...etc
}

En la actividad del selector de muestras, el menú ampliado contiene opciones para especificar si se deben preferir los decodificadores de extensión.

URIs de archivos locales y restricciones de almacenamiento con alcance

Cuando se especifican URIs de archivos locales, la app de demostración solicita los permisos de acceso al almacenamiento necesarios para leer estos archivos. Sin embargo, a partir de Android 13, no es posible cargar archivos arbitrarios que no terminen en una extensión de archivo multimedia típica (como .mp4). Si necesitas cargar un archivo de este tipo, puedes colocarlo en el directorio de almacenamiento específico de la app de demostración que no tiene restricciones de acceso. Por lo general, se encuentra en /sdcard/Android/data/androidx.media3.demo.main/files.

2. Cómo cargar un archivo exolist.json externo

La app de demostración puede cargar archivos JSON externos con el esquema anterior y con el nombre según la convención de *.exolist.json. Por ejemplo, si alojas un archivo de este tipo en https://yourdomain.com/samples.exolist.json, puedes abrirlo en la app de demostración con el siguiente comando:

adb shell am start -a android.intent.action.VIEW \
    -d https://yourdomain.com/samples.exolist.json

Si haces clic en un vínculo *.exolist.json (por ejemplo, en el navegador o en un cliente de correo electrónico) en un dispositivo con la app de demostración instalada, también se abrirá en ella. Por lo tanto, alojar un archivo JSON de *.exolist.json proporciona una forma sencilla de distribuir contenido para que otros lo prueben en la app de demostración.

3. Cómo activar un intent

Las intents se pueden usar para omitir la lista de muestras y comenzar la reproducción directamente. Para reproducir una sola muestra, establece la acción del intent en androidx.media3.demo.main.action.VIEW y su URI de datos en el de la muestra que se reproducirá. Este intent se puede activar desde la terminal con el siguiente comando:

adb shell am start -a androidx.media3.demo.main.action.VIEW \
    -d https://yourdomain.com/sample.mp4

Los objetos adicionales opcionales admitidos para un solo intent de muestra son los siguientes:

  • Ejemplo de configuración adicional:
    • mime_type [String] Sugerencia de tipo de MIME de muestra. Por ejemplo, application/dash+xml para contenido de DASH.
    • clip_start_position_ms [Long] Es un punto de inicio en el que se debe cortar la muestra, en milisegundos.
    • clip_end_position_ms [Long] Es un punto final desde el que se debe cortar la muestra, en milisegundos.
    • drm_scheme [String] Esquema de DRM si está protegido. Los valores válidos son widevine, playready y clearkey. También se aceptan los UUID del esquema de DRM.
    • drm_license_uri [cadena] URI del servidor de licencias si está protegido.
    • drm_force_default_license_uri [booleano] Indica si se debe forzar el uso de drm_license_uri para las solicitudes de claves que incluyen su propio URI de licencia.
    • drm_key_request_properties [Matriz de cadenas] Encabezados de solicitud clave empaquetados como name1, value1, name2, value2, etc. si están protegidos.
    • drm_session_for_clear_content [Booleano] Indica si se debe adjuntar una sesión de DRM a las pistas de audio y video claras.
    • drm_multi_session [Booleano] Habilita la rotación de claves si está protegida.
    • subtitle_uri [String] Es el URI de un archivo de subtítulos complementario.
    • subtitle_mime_type [cadena]: Tipo de MIME de subtitle_uri (obligatorio si se establece subtitle_uri).
    • subtitle_language [String] Código de idioma BCP47 del archivo de subtítulos (se ignora si no se configura subtitle_uri).
    • ad_tag_uri [String] Es el URI de una etiqueta de anuncio que se cargará con la [extensión de IMA][].
    • prefer_extension_decoders [Booleano] Indica si se prefieren los decodificadores de extensión a los de la plataforma.

Cuando se usa adb shell am start para activar una intención, se puede establecer un extra de cadena opcional con --es (p.ej., --es extension mpd). Se puede establecer un extra booleano opcional con --ez (p.ej., --ez prefer_extension_decoders TRUE). Se puede establecer un extra largo opcional con --el (p.ej., --el clip_start_position_ms 5000). Se puede establecer un extra de array de cadenas opcional con --esa (p.ej., --esa drm_key_request_properties name1,value1).

Para reproducir una playlist de muestras, configura la acción de la intención en androidx.media3.demo.main.action.VIEW_LIST. Los elementos adicionales de configuración de muestra siguen siendo los mismos que para androidx.media3.demo.main.action.VIEW, excepto por dos diferencias:

  • Las claves de los elementos adicionales deben tener un guion bajo y el índice basado en 0 de la muestra como sufijo. Por ejemplo, extension_0 sugeriría el tipo de muestra para la primera muestra. drm_scheme_1 establecería el esquema de DRM para la segunda muestra.
  • El URI de la muestra se pasa como un valor adicional con la clave uri_<sample-index>.

Los otros extras, que no dependen de la muestra, no cambian. Por ejemplo, puedes ejecutar el siguiente comando en la terminal para reproducir una playlist con dos elementos y anular la extensión del segundo elemento:

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