Playing different Videos with Exo-Player in Android TV
There are usually 3 types of videos while streaming in any Video Player. While working on Android TV we categorize these in
-
Dash Videos
-
HLS Videos (.m3u8 & .ts)
-
Others (.mp4,.mpeg etc)
We need different types of ExtractorRendererBuilder for playing different videos with Exo-Player. In this article I will be describing the difference between Other Videosand HLS Videos (.m3u8 & .ts).
For HLS Videos we need to create different ExtractorRenderBuilder for reference I will be taking them as HlsExtractorRendererBuilder and ExtractorRendererBuilder respectively.
In PlaybackFragment getRendererBuilder() method will be implemented somewhat like this
[java]private VideoPlayer.RendererBuilder getRendererBuilder() {
String userAgent = Util.getUserAgent(getContext(), "ExoVideoPlayer");
Uri contentUri = Uri.parse(mSelectedVideo.videoUrl);
int contentType = Util.inferContentType(contentUri.getLastPathSegment());
switch (contentType) {
case Util.TYPE_OTHER: {
return new ExtractorRendererBuilder(getContext(), userAgent, contentUri);
}
case Util.TYPE_HLS: {
return new HlsExtractorRendererBuilder(getContext(), userAgent, contentUri);
}
default: {
throw new IllegalStateException("Unsupported type: " + contentType);
}
}
}
[/java]
userAgent : Util.getUserAgent() gives ExoVideoPlayer which tells that what kind of VideoPlayer we are going to use. Internal implementation of getUserAgent() is
[java]
public static String getUserAgent(Context context, String applicationName) {
String versionName;
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
versionName = info.versionName;
} catch (NameNotFoundException e) {
versionName = "?";
}
return applicationName + "/" + versionName + " (Linux;Android " + Build.VERSION.RELEASE
+ ") " + "ExoPlayerLib/" + ExoPlayerLibraryInfo.VERSION;
}
[/java]
ContentUri : Video Url to be played
contentType : Util.inferContentType() extracts the video type. Internal implementation of inferContentType() is
[java]public static int inferContentType(String fileName) {
if (fileName == null) {
return TYPE_OTHER;
} else if (fileName.endsWith(".mpd")) {
return TYPE_DASH;
} else if (fileName.endsWith(".ism")) {
return TYPE_SS;
} else if (fileName.endsWith(".m3u8")) {
return TYPE_HLS;
} else {
return TYPE_OTHER;
}
}
[/java]
For playing different type of videos we create different rendererbuilders, Each RenderBuilder class implements RenderBuilder interface and we need to implement buildRenderers() and cancel() methods.
Playing TYPE_OTHER Videos in ExoPlayer
The buildRenderers() for TYPE_OTHER videos would be as following code.
[java]
@Override
public void buildRenderers(VideoPlayer player) {
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
Handler mainHandler = player.getMainHandler();
// Build the video and audio renderers.
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, null);
DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, mainHandler, player, 0);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
mainHandler, player, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
MediaCodecSelector.DEFAULT, null, true, mainHandler, player,
AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
mainHandler.getLooper());
// Invoke the callback.
TrackRenderer[] renderers = new TrackRenderer[VideoPlayer.RENDERER_COUNT];
renderers[VideoPlayer .TYPE_VIDEO] = videoRenderer;
renderers[VideoPlayer .TYPE_AUDIO] = audioRenderer;
renderers[VideoPlayer .TYPE_TEXT] = textRenderer;
player.onRenderers(renderers, bandwidthMeter);
}
[/java]
We include Video, Audio, Text types of renderer as per our need.
[java]
@Override
public void cancel() {
//Do Nothing
}
[/java]
Playing TYPE_HLS Videos in ExoPlayer
As we know that HLS stands for HTTP Live Streaming, So we need to implement AsyncRendererBuilder for streaming HLS type of Videos.
BuildRenderers() for HLS Videos :
[java]
@Override
public void buildRenderers(DemoPlayer player) {
currentAsyncBuilder = new AsyncRendererBuilder(context, userAgent, url, player);
currentAsyncBuilder.init();
}
[/java]
Cancel() fir HLS Videos:
[java]@Override
public void cancel() {
if (currentAsyncBuilder != null) {
currentAsyncBuilder.cancel();
currentAsyncBuilder = null;
}
}
[/java]
For reference of demo with exoplayer kindly fork from Github-HlsVideoSample