157 lines
5.4 KiB
Markdown
157 lines
5.4 KiB
Markdown
|
---
|
||
|
title: Media items
|
||
|
---
|
||
|
|
||
|
The [playlist API][] is based on `MediaItem`s, which can be conveniently built
|
||
|
using `MediaItem.Builder`. Inside the player, media items are converted into
|
||
|
playable `MediaSource`s by a `MediaSource.Factory`. Without
|
||
|
[custom configuration]({{ site.baseurl }}/media-sources.html#customizing-media-source-creation),
|
||
|
this conversion is carried out by a `DefaultMediaSourceFactory`, which is
|
||
|
capable of building complex media sources corresponding to the properties of the
|
||
|
media item. Some of the properties that can be set on media items are outlined
|
||
|
below.
|
||
|
|
||
|
## Simple media items ##
|
||
|
|
||
|
A media item consisting only of the stream URI can be built with the `fromUri`
|
||
|
convenience method:
|
||
|
|
||
|
~~~
|
||
|
MediaItem mediaItem = MediaItem.fromUri(videoUri);
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
For all other cases a `MediaItem.Builder` can be used. In the example below, a
|
||
|
media item is built with an ID and some attached metadata:
|
||
|
|
||
|
~~~
|
||
|
MediaItem mediaItem = new MediaItem.Builder()
|
||
|
.setUri(videoUri)
|
||
|
.setMediaId(mediaId)
|
||
|
.setTag(metadata)
|
||
|
.build();
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
Attaching metadata can be useful for
|
||
|
[updating your app's UI]({{ site.baseurl }}/playlists.html#detecting-when-playback-transitions-to-another-media-item)
|
||
|
when playlist transitions occur.
|
||
|
|
||
|
## Handling non-standard file extensions
|
||
|
|
||
|
The ExoPlayer library provides adaptive media sources for DASH, HLS and
|
||
|
SmoothStreaming. If the URI of such an adaptive media item ends with a standard
|
||
|
file extension, the corresponding media source is automatically created. If the
|
||
|
URI has a non-standard extension or no extension at all, then the MIME type can
|
||
|
be set explicitly to indicate the type of the media item:
|
||
|
|
||
|
~~~
|
||
|
// Use the explicit MIME type to build an HLS media item.
|
||
|
MediaItem mediaItem = new MediaItem.Builder()
|
||
|
.setUri(hlsUri)
|
||
|
.setMimeType(MimeTypes.APPLICATION_M3U8)
|
||
|
.build();
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
For progressive media streams a MIME type is not required.
|
||
|
|
||
|
## Protected content ##
|
||
|
|
||
|
For protected content, the media item's DRM properties should be set:
|
||
|
|
||
|
~~~
|
||
|
MediaItem mediaItem = new MediaItem.Builder()
|
||
|
.setUri(videoUri)
|
||
|
.setDrmConfiguration(
|
||
|
new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
|
||
|
.setLicenseUri(licenseUri)
|
||
|
.setMultiSession(true)
|
||
|
.setLicenseRequestHeaders(httpRequestHeaders)
|
||
|
.build())
|
||
|
.build();
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
This example builds a media item for Widevine protected content. Inside the
|
||
|
player, `DefaultMediaSourceFactory` will pass these properties to a
|
||
|
`DrmSessionManagerProvider` to obtain a `DrmSessionManager`, which is then
|
||
|
injected into the created `MediaSource`. DRM behaviour can be
|
||
|
[further customized]({{ site.baseurl }}/drm.html#using-a-custom-drmsessionmanager)
|
||
|
to your needs.
|
||
|
|
||
|
## Sideloading subtitle tracks ##
|
||
|
|
||
|
To sideload subtitle tracks, `MediaItem.Subtitle` instances can be added when
|
||
|
when building a media item:
|
||
|
|
||
|
~~~
|
||
|
MediaItem.SubtitleConfiguration subtitle =
|
||
|
new MediaItem.SubtitleConfiguration.Builder(subtitleUri)
|
||
|
.setMimeType(MimeTypes.APPLICATION_SUBRIP) // The correct MIME type (required).
|
||
|
.setLanguage(language) // The subtitle language (optional).
|
||
|
.setSelectionFlags(selectionFlags) // Selection flags for the track (optional).
|
||
|
.build();
|
||
|
MediaItem mediaItem =
|
||
|
new MediaItem.Builder()
|
||
|
.setUri(videoUri)
|
||
|
.setSubtitleConfigurations(ImmutableList.of(subtitle))
|
||
|
.build();
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
Internally, `DefaultMediaSourceFactory` will use a `MergingMediaSource` to
|
||
|
combine the content media source with a `SingleSampleMediaSource` for each
|
||
|
subtitle track.
|
||
|
|
||
|
## Clipping a media stream ##
|
||
|
|
||
|
It's possible to clip the content referred to by a media item by setting custom
|
||
|
start and end positions:
|
||
|
|
||
|
~~~
|
||
|
MediaItem mediaItem =
|
||
|
new MediaItem.Builder()
|
||
|
.setUri(videoUri)
|
||
|
.setClippingConfiguration(
|
||
|
new ClippingConfiguration.Builder()
|
||
|
.setStartPositionMs(startPositionMs)
|
||
|
.setEndPositionMs(endPositionMs)
|
||
|
.build())
|
||
|
.build();
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
Internally, `DefaultMediaSourceFactory` will use a `ClippingMediaSource` to wrap
|
||
|
the content media source. There are additional clipping properties. See the
|
||
|
[`MediaItem.Builder` Javadoc][] for more details.
|
||
|
|
||
|
When clipping the start of a video file, try to align the start position with a
|
||
|
keyframe if possible. If the start position is not aligned with a keyframe then
|
||
|
the player will need to decode and discard data from the previous keyframe up to
|
||
|
the start position before playback can begin. This will introduce a short delay
|
||
|
at the start of playback, including when the player transitions to playing a
|
||
|
clipped media source as part of a playlist or due to looping.
|
||
|
{:.info}
|
||
|
|
||
|
## Ad insertion ##
|
||
|
|
||
|
To insert ads, a media item's ad tag URI property should be set:
|
||
|
|
||
|
~~~
|
||
|
MediaItem mediaItem = new MediaItem.Builder()
|
||
|
.setUri(videoUri)
|
||
|
.setAdsConfiguration(
|
||
|
new MediaItem.AdsConfiguration.Builder(adTagUri).build())
|
||
|
.build();
|
||
|
~~~
|
||
|
{: .language-java}
|
||
|
|
||
|
Internally, `DefaultMediaSourceFactory` will wrap the content media source in an
|
||
|
`AdsMediaSource` to insert ads as defined by the ad tag. For this to work, the
|
||
|
the player also needs to have its `DefaultMediaSourceFactory`
|
||
|
[configured accordingly]({{ site.baseurl }}/ad-insertion.html#declarative-ad-support).
|
||
|
|
||
|
[playlist API]: {{ site.baseurl }}/playlists.html
|
||
|
[`MediaItem.Builder` Javadoc]: {{ site.baseurl }}/doc/reference/com/google/android/exoplayer2/MediaItem.Builder.html
|