5.4 KiB
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