Streaming media with ExoPlayer – Google I/O 2016

Streaming media with ExoPlayer – Google I/O 2016

hello, everyone. My name is Marc Bachinger. I’m a developer
advocate here at Google. I’m a member of the media
team, so I’m usually working with large media
partners, audio and video partners, to improve
the streaming experience of their app. So, usually this boils down
to integrate ExoPlayer, or to help them
migrate to ExoPlayer. So, let me start with one of
those mandatory instant surveys just to cool down the
speaker a little bit. Who of you have watched
a video on YouTube in the last week on Android? Yeah, not surprisingly,
very good numbers. All of you who raised your hand,
you already are ExoPlayer users because ExoPlayer
is the default video player in the YouTube app. So, let me start
with the first slide with a website I found some
years ago, or some months ago, on the internet. It’s obviously not
the Google website. It’s a website some
YouTube users did. It’s the YouTube
ExoPlayer guide, and there were some
users that found that YouTube started using
ExoPlayer within the YouTube app. And they found the
experience so exciting that they found ways
to kind of hack YouTube to force YouTube to use
ExoPlayer all the time and on all devices. So, there is a very nice
quote on this website. This quote says, “ExoPlayer
is an experimental video player hidden inside
Google’s YouTube app– it loads videos much,
much faster– but made unavailable to the
average person.” So, let me be clear, most
of this quote is not true. So, ExoPlayer is not
at all experimental. ExoPlayer is not hidden
inside the YouTube app, and it’s not unavailable
to the average person. I may agree to the thing
in the parentheses. It loads video much
faster, so that’s the improved video experience
we want to have from ExoPlayer. So, again, let me be
clear, that’s not true. It’s available on GitHub. You can download it on GitHub. So, what is ExoPlayer, then? ExoPlayer is a so-called
application level media player library. Application level
media player library means you can include the
library within your APK, within your app, and ship it
to your user with your APK. Regarding the living room,
ExoPlayer is a perfect choice. All Android TV devices
support ExoPlayer. Android TV devices run
on Lollipop and greater, so all those devices
support ExoPlayer. But ExoPlayer is not only
a good choice for TV, it’s also an excellent
choice for mobile. All devices which have API 16
and greater support ExoPlayer. So, I have this
number here– 95.7%. This is the share
of Android devices running API 16 and later. So, that’s a quite good number
for all devices out there. ExoPlayer is built on
some public APIs provided by the media framework. So, to say this
clearly, ExoPlayer does not use some
kind of hidden APIs or private APIs only
available for Google tech. ExoPlayer really
uses public APIs. It’s the Android Media
API on the one hand, and the Android Media DRM
API on the other hand. So, at least in theory,
you can write such a player for yourself. But that’s, of course,
not a really easy task. That’s why I released
ExoPlayer some years ago as an open-source
product on GitHub. So, you can include it
into your apps as well. So, what is an application
level media player? I already mentioned
you can include this library in your APK
and ship it to your users as part of your APK. We see here this
white box at the top. This white box is the APK, which
contains an application level media player, or in this
case, ExoPlayer itself. And now, this application level
media player, or ExoPlayer, uses those APIs available. This diagram here is
ExoPlayer in an early version. Today, [INAUDIBLE] we will
have a look at this later. We see those arrows. ExoPlayer is using the
MediaExtractor API. It’s using the
MediaCodecs API, and it’s using the AudioTrack API. All of those are public
APIs available on Android. When you have a little
look at the gray boxes, we have this MediaExtractor
with those green boxes in it. So this is what a streaming
video player has to do. First, it would have to
download container data from the internet. Then we have to buffer this
data until we really need it. And once we need
the data, we need to extract audio and video
samples out of the container. When we have those
samples, those audio and those video samples,
they are still encoded, so we can’t really render those. So, we need the MediaCodecs
API to decode those samples, and once we have those
samples in a decoded way, we can render
those with Android. In the case of
video, we only have to pass a surface to the
codec’s API, and the codec’s API itself then does the
rendering on this surface. In the case of audio files,
the result of passing these encoded frames, or PCM
frames, which we then can play by using the audio track. So that’s what is involved
in both, in audio streaming and in video streaming. And there’s still a little bit
of a problem with this diagram. So all those tasks are kind
of buried in the APIs– in the APIs of the framework. So, if you want to
customize, or we want to change the behavior
regarding those tasks, there is nothing we can
do because everything is done by the framework, which
we can’t really customize. Early versions of ExoPlayer
used this FrameworkSampleSource class. This FrameworkSampleSource class
used the MediaExtractor API to do these
networking, buffering, and extracting tasks. And that’s what we also
see in the next slide, a little bit more focused. But still, the
FrameworkSampleSource can’t really influence
what MediaExtractor is doing in detail, and
that’s exactly what we want. So the ExoPlayer
team, in the end, decided to deprecate this
FrameworkSampleSource, and to do all these tasks
in ExoPlayer itself. So, the diagram, which
we have seen before, now looks like this. So, all those green tasks
are moved into ExoPlayer, or moved into the
APK, and that’s why we now can customize
the behavior of those tasks. So, if you want, for example,
to use another network stack, you can use another
network stack by using a custom data source. You can influence
buffering, and you can even support other containers–
other video or audio containers which are not
supported by the framework. So by moving those tasks
into ExoPlayer itself, we win some customizations. That’s exactly what we want. Regarding the other
two media APIs, there’s not much we can
win by replacing them. Usually, the MediaCodecs uses
hardware-backed functionality to decode those frames to
do really an efficient job. And that’s something we
never want to do in software. So, this still is done by those
media APIs provided by Android. The same is true
for the AudioTrack. There’s not much sense to
play audio in another way than with an AudioTrack. So, why should you, as a
developer, use ExoPlayer? What are the advantages
of using ExoPlayer? First of all, there are
those streaming formats like DASH and SmoothStreaming. Those two are not supported
by the MediaFramework itself. So if you want to use
DASH or SmoothStreaming, you need to use something
else than the media player– the player of the framework. And, of course, what we
recommend is using ExoPlayer. HLS is also supported
by ExoPlayer, and it’s also supported
by Media Player. In this case, if you already
use HLS with the Media Player, and you are OK
with that, there is nothing against using Media
Player, but for some reasons we also support
HLS with ExoPlayer. Another advantage is,
as I already said, you can include ExoPlayer
as a Gradle dependency within your app. And you can ship ExoPlayer or
this library, with your APK, to your users. The biggest advantage
of this is that you are really sure that every user
is using the very same version of your player. That’s one very
interesting feature because if you are using
the MediaFramework, and one user has
an older device, he will use another
player version than a user with a newer device. And if you have to
debug problems or so, you always have to
make sure that you are testing the very same version. With ExoPlayer,
that’s kind of easy because you can say which
version you ship with your APK. Besides this ability of
using the very same version, you also can take advantage
of the faster release cycle of ExoPlayer. ExoPlayer sometimes
releases newer versions within months, and with Android
devices, that’s something a little bit different. Some devices are
updated very rarely, so if you have to wait for
a bug fix for a framework component for some devices, you
will never get these updates. So with ExoPlayer,
you can just include the new version of the
library in your APK and ship it to your users. And in the end, the most
interesting features for some developers is the
ability to customize ExoPlayer. That’s exactly what we
have seen in the diagram before, by moving those
tasks of networking, buffering, and extracting
data from the containers, we gain some means to
customization in those tasks, and that’s exactly
what we want, if we have some specific requirements
to meet within your apps. For Android TV, of
course, ExoPlayer is a very good choice. If you want to support 4K,
ExoPlayer is ready for 4K. So if you have 4K content which
you want to bring to users, ExoPlayer is a very good choice. ExoPlayer also is ready for
some very modern audio codecs, like Dolby Digital, for example. If you have connected your
Nexus player, for example, to a TV which supports
Dolby Digital, ExoPlayer can recognize this
if the TV advertises supports for those codecs by HDMI. And then ExoPlayer
will just pass through the encoded
audio data to the TV, and the TV will do the
decoding and the playback of those modern audio codecs. One of the customizations,
which we see very often on Android TV, is
that you can customize the bitrate algorithm, the
bitrate adaption algorithm. You know, the Android
framework is still made for and optimized for mobile. So if the media player starts
doing adaptive playback, it starts with the
lowest video quality. If you’re on a mobile network,
that makes perfect sense, because you want to start
playback as soon as possible. So the media player starts
with the lowest quality. On Android TV, that’s
a little bit different. All Android TVs usually
are connected by WiFi to the internet, or
even by ethernet. So you have good bandwidth. And you may want to start
not with the lowest, but maybe with
medium video quality to have very good quality
for your users very quickly. So if you want to customize
this bitrate adaption algorithm, ExoPlayer is a good choice. And in the end, then,
ExoPlayer is also ready for content protection. Android TV does not
only support Widevine, it also supports PlayReady. And with ExoPlayer you can
use Widevine or PlayReady for both DASH and
SmoothStreaming. In fact, ExoPlayer
supports common encryption, which includes support
for those products available on Android TV. A question which comes
up very quickly when I talk to my partners–
which media formats are supported by ExoPlayer? That’s not really
an easy question, so let’s start with the
first row of this table. Let’s start with the
streaming formats. I already said, it’s DASH
and SmoothStreaming and HLS. These are the
streaming formats which are supported by ExoPlayer,
while HLS is also supported by the media framework. Only ExoPlayer supports
DASH and SmoothStreaming. Container formats are the
very strength of ExoPlayer. We have seen that we
moved those green boxes into the application space. So ExoPlayer does
extracting data out of these containers itself. This means ExoPlayer can
support arbitrary containers, and it can support
more containers than the framework does. So we have here a couple of
common container formats. So there’s MP4,
of course; there’s WebM; Matroska, which is
supported by ExoPlayer; there are a couple
of audio containers, like MP3, Ogg, and
WAV; and then there are the HLS container formats,
MPEG-TS, MPEG-PS, and ADTS. When it comes to video
and audio formats, ExoPlayer can do this itself. The decoding of those video
formats and audio formats is just delegated to
the media framework. So ExoPlayer supports
all those formats, which are supported by
the media framework. There is a web page on which you can consult to
see what video and audio formats are supported. Another important
[? high ?] performance are closed captions
and subtitles. For professional
media companies, this is a very important feature
they have to provide sometimes, for legal reasons– closed
captions and subtitles. So that’s very important. ExoPlayer supports
TTML and WebVTT for DASH and SmoothStreaming. These are the most
common formats for DASH and SmoothStreaming,
and it supports 608 for HLS, the format which
usually is used with HLS. Another question which
comes up very quickly– so if I have to put this player
library into my APK, my APK will get bigger. And some developers
are afraid of, maybe, hitting the DEX limit. There’s a certain
amount of methods which you can include
in your DEX file, so that’s a very
important question. How many methods are included
with the ExoPlayer library? The numbers which I have here
is the Kitchen-sink library, so it’s the very highest
number you can get if you ProGuard your app APK. Usually ProGuard is able to
remove a lot of those methods, because usually you don’t use
HLS, DASH, and SmoothStreaming in one APK. You would only one of
those streaming formats, and so, ProGuard is able to
remove many of those methods. I did a little
audio application, and then ProGuard removed
about 2,000 of those methods. I ended up with having about 900
methods for an audio playback application. Who is using ExoPlayer already? Also a very important question. You don’t want to
beta-test Google software with your users, of course. You want to have well-tested
software in your APK. So Google itself uses
ExoPlayer in their most famous application. YouTube, I already mentioned,
is using ExoPlayer. There’s also Google
Play Movies, which is using ExoPlayer on mobile
and on Android devices. And the next and last
Google application is Google Fiber, which
also relies on ExoPlayer for doing video playback. I already mentioned I’m working
with large media partners, and there are a couple
of large media partners which also use
ExoPlayer internally. We usually do not
expose these partners, but I can assure you there are
really large companies using ExoPlayer like Google does. Yeah, and hopefully soon
you will use ExoPlayer, too. If I’m a little bit
convincing today, you will download ExoPlayer. And once you’ve
downloaded ExoPlayer, I’m pretty sure
you will like it, and soon, you will include
it in your APK as well. So, let’s have a look
at some basic use cases. And for a media
player, of course, basic use cases is playing
audio and video files. So what do you have to do
to play audio or video files with ExoPlayer? The first thing is,
of course, including ExoPlayer in your APK. The easiest thing
to do this is just add another Gradle dependency
to your Gradle files, and then ExoPlayer
will be included and you can use all those
classes of [INAUDIBLE]. When you’re using
ExoPlayer, ExoPlayer has the concept
of TrackRenderers. You need a TrackRenderer
for every type of data you want to render. Usually, you have
audio data, video data, and text data– namely,
subtitles or closed captions. So, in a full-fledged
video application, you have three TrackRenderers. For this use case of
doing audio playback, there’s only one
TrackRenderer needed, and that’s exactly what we
see in this highlighted code snippet here. We require such a TrackRenderer. In this case, it’s a
MediaCodecAudioTrackRenderer. So, the interface
is a TrackRenderer, and the concrete class
implementing this interface is a
MediaCodecAudioTrackRenderer. This
MediaCodecAudioTrackRenderer now takes a couple of
arguments in its constructor, and the most important
one is the first. Or the most interesting
one is the first argument, the SampleSource. The SampleSource is a
collaborating component. So the
MediaCodecAudioTrackRenderer requires a SampleSource to
get audio samples from it. That’s exactly what we see now
in the next line of code here. We are creating an
instance of a SampleSource. Again, we have the SampleSource,
which is only a Java interface. The concrete
implementation, then, is an ExtractorSampleSource,
and the ExtractorSampleSource is provided by the
ExoPlayer library. Here again, a couple of
arguments in the constructor. The second constructor is of
interest, here, the DataSource. The DataSource is, again,
another collaborator, which then is created
in the line above. Again, we have a DataSource
interface– a Java interface DataSource, which
is then provided as a DefaultUriDataSource. And now, with the very
same pattern again, the DefaultUriDataSource
needs a BandwidthMeter. And, again, a concrete
implementation of BandwidthMeter is provided
by the ExoPlayer library. So, we kind of wire up
a chain of components, each depending on
another component. And it’s kind of obvious
that it’s quite easy to create your own
implementation of one of those interfaces. If you have such a
custom implementation of such an interface,
you can just instantiate it and inject
it into the constructor of the other components. Those arrays highlight
this path a little bit, so we create one
component and inject it into the other component to get
a chain of those components. So, once we have
this AudioRenderer, or this TrackRenderer
for audio, we need to register those renderers
in the ExoPlayer itself. So, we create an array
of TrackRenderers, assign the AudioRenderers to one
of the positions of this array, and then we pass it to
their own renderers method. So this was what we need to
do for doing audio playback. For video playback,
as I already said, we have some other type of data. There is not only audio,
there is also video data, and eventually you
want to render text, subtitles, or closed
captions as well. So again, we need three of those
chains of dependent components. So we need a TrackRenderer. The TrackRenderer then
needs a SampleSource. Each SampleSource, again,
needs a DataSource, which, in the end, needs
a BandwidthMeter if you want to do adaptive playback. So let me be clear again. You don’t have to provide
your own implementation. Each component has a default
implementation provided by the ExoPlayer library. You can wire up your
renderers as you want. So there’s no need
to really implement these things if you don’t
have specific requirements. You can just use it as the demo
application just demonstrated. Besides these
TrackRenderer components, there are a couple of UI
components available as well. So, these components are
not really mandatory, but they are very
convenient to use. There is, for example, this
AspectRatioFrameLayout. It’s a layout which makes
sure that the SurfaceView on which the video is rendered
is always resized nicely. So if a user, for example,
changes the orientation of a mobile device, you have to
resize the SurfaceView to match the size of the viewport. Another component is
at the very bottom. It’s the SubtitleLayout. Again, this SubtitleLayout is,
in the end, optional to use. But if you want to
render text or closed captions or subtitles, it’s
very convenient to use. It’s the same size
as the entire layout, or the SurfaceView
has, and it’s kind of a layer above the
video on which ExoPlayer can render those subtitles. So there’s a lot going on. We have seen that you
have to download data, we have to buffer data, we
have to extract data out of the containers,
and in the end, we have to render
these data to a surface or to the audio track. So a lot is going on
in this video player, and if you want to be
aware of what is going on, you can implement
some listeners, and then register
those listeners. So on a high level, there
is the ExoPlayer.Listener. This is a listener
which notifies you about the high level
state of the player. So when you start, the
player is in an idle state, and then it transitions
to a buffering state. So we have to start
downloading data. And as soon as there is enough
data, we can start playback. If you want to give some
signals to your user– now the player is buffering,
there’s not enough data available– you can just
implement such a listener and listen to those
state transitions. Besides these
high-level events, there are a couple of
low-level events. So there are many of
those components which you have to wire up, and
each of those components has an event listener. This snippet, again, is
out of the ExoPlayer Pro. Check this out. It’s from the DemoPlayer
application of ExoPlayer. It implements an event listener
for each of those components. So whatever’s going on in
one of those components, your application is aware
of what is going on, and you can act upon
these state transitions. So, let’s have a look at
the architecture, or design. We now have seen there are
many such components which are dependent on each other. So let’s have a
look at the diagram. This is a diagram of the
component model, or object model, which is required to
do traditional media playback. Traditional media playback
is so-called non-adaptive playback. So there is one
single container file sitting on a server on
the internet somewhere, and we need to download
this container. And then we need to extract
data out of this container. That’s exactly what we need
for such– traditional media playback is, again, we need
two [? TrackRenderers. ?] We have these blue
boxes on the right. This is
MediaCodecVideoTrackRenderer and the
MediaCodecAudioTrackRenderer. Those two are responsible to
render audio and video data by using the public media APIs. Each of those
TrackRenderers is now dependent on an
ExtractorSampleSource. This ExtractorSampleSource
uses an extractor. In this case, it’s an
MP4 extractor, which knows how to extract audio
and video data out of this MP4 container, then
passes the sample to the ExtractorSampleSource,
which again, passes it to the TrackRenderers
for rendering. So if you want to support
some kind of custom container format– maybe you invented
a super-efficient container format for video– you can
just create your own extractor, register the extractor with
the ExtractorSamplesource, and then you can support
this new kind of container. Maybe you have some kind
of content protection built into the container. If you have invented
such a container you can also plug in
these container formats with ExoPlayer. And in the end,
at the very left, we see the DefaultUriDataSource. Again this, is an implementation
of the data source. The ExtractorSampleSource
it relies on. And if you want to, for example,
support proprietary network protocol, you can implement
your own data source here to support those protocols. MARC BACHINGER: So
the next diagram shows the same object model
for adaptive media playback. The difference here is
that the video player has to pick the quality
of the video chunks. So again, on the very right,
we have those blue boxes it’s
MediaContactMediaTrackRenderer and the AudioTrackRenderer which
does the rendering and the end. Those two now are dependent
on a ChunkSampleSource. And DashChunkSource itself
depends on a DashChunkSource. The DashChunkSource is
now the component which knows the manifest of Dash. So in the manifest, there are
references to video chunks of different quality. And as soon as we
know that we have good bandwidth– good
network bandwidth, ExoPlayer should pick a better
quality over a lower quality. The DashChunkSource then
again, relies on a DataSource to actually do the downloading. Again, you can replace these
components if you want. The most important thing here
now is the AdaptiveElevator. The AdaptiveElevator does some
metering off the network speed. So as soon as we– usually,
we start with a low quality, or in the case of
AndroidTV, we start with maybe a medium
quality of those chunks. And the AdaptiveElevator
does meter the bandwidth of
the network as soon as we start downloading data. I already mentioned that this
bitrate adaptation algorithm might be when a candidate
you want to customize. And if you want to, you can only
replace these tiny components of the AdaptiveElevator to not
start with the lowest quality but maybe with a medium
quality, and then replace these components when
you wire up this object model. So you really have
just to replace this tiny piece of
this object model, provide your custom
implementation, and then in the end they
worked together nicely with the default components
delivered by the ExoPlayer library. So yeah. You might say, yeah, but
that’s really a complex thing to wire up all these components. But if I use MediaPlayer or
just have two lines of code, and it starts playback–
and yet that’s true. This flexibility or this
ability to customize things comes with price of
this added complexity. But the good news
is that ExoPlayer provides some templates to
wire up these objects together. There are templates for
DASH, SmoothStreaming and HLS for example. We have, for example,
the DashRendererBuilder, which does wire up the component
model for doing DASH streaming. Usually, you don’t have
to change these templates. You can just use it as is
provided by the ExoPlayer library. If you have some
specific requirements, you have some specific
features withing your DASH manifest–
for example, maybe you have to adapt what the
DashRendererBuilder is doing. But again, It’s
a very good start to look into these
RenderBuilders. These RendererBuilders,
again, are part of the demo application. So if you download
the project and you have to look at the
demo application, you will find these
RendererBuilders and can start from there. The last RendererBuilder
which is available is the non-adapt for
non-adaptive playback. It’s again, for
traditional media playback. And it’s pretty much the same. It’s not that complicated. We have seen the diagram. There are less components
which brought together. But if you want to do
traditional playback, again, you can start with
this ExtractorRendererBuilder. So yeah. Now, call to action. So of course, we have some
call to actions for you. So clone the ExoPlayer project. It’s available on GitHub. Easiest thing is just to search
for GitHub and ExoPlayer, and you will file repository. Clone the repository,
build the APK, and deployed the APK,
the demo application, to your Android device,
and then start testing. The demo application includes
a list of sample streams. There are samples streams for
DASH, SmoothStreaming, and HLS. There are sample streams
for the different content protection technologies, there
like WideVine and PlayReady. Check it out. And if you find your
streams you want to support, it’s quite easy to start
from the demo applicaiton. And in the end of course,
integrate ExoPlayer as a library into your own app. Take the demo application
as a template, and then use ExoPlayer
by integrating it with a Gradle dependency. There other ways to do that. You can copy the source
code into you APK, or you can build a
library and then put the library in your IDE. But the easiest way is just
to use a Gradle depdency. So that’s basically what I have. So there are again, those
links to the ExoPlayer project itself. And there is also a reference
to the Developer Guide. The Developer Guide gives
you in-depth information about customizing
ExoPlayer for your needs. All those diagrams
we’ve seen in this talk are taken from the
Developer Guide. So it’s a pretty
good read for you if you want to meet your
requirements to check out ExoPlayer, the ExoPlayer
Developer Guide. Yeah that’s all I have. So if you have some questions,
please go to the microphone, and ask questions so
everybody can hear it. And I’m happy to
answer these questions. AUDIENCE: Hey, does the player
support 360 video as well? MARC BACHINGER: Excuse me? AUDIENCE: 360 videos. MARC BACHINGER: No. ExoPlayer currently
does not support. I think that YouTube has a
kind of modified version, but currently no
support for 360. Excuse me? AUDIENCE: [INAUDIBLE] MARC BACHINGER: I don’t, sorry. AUDIENCE: It’s a custom model. MARC BACHINGER: Yeah. There’s currently no support
from ExoPlayer’s project. AUDIENCE: Whoa. That came on all of a sudden. Is there a roadmap
for the ExoPlayer? And is there any
kind of reliable way we can influence what’s
coming up in the project? MARC BACHINGER: There
is not a public roadmap. On GitHub, there are
different branches. We have the productive
branch, and then there is the development branch. If you’re looking into
the developer branch, you look a little
bit into the future. There’s also currently
an experimental branch. We are working currently
on version 2 of ExoPlayer, which brings in some
more flexibility, especially at runtime. So all those components
will be about the same. But at runtime,
we have more ways to replace components
at runtime. But there is not something like
a public roadmap available. If you are interested
in the future, I can just say, go to the
Issue Tracker of GitHub, and the team is there,
and we’ll answer about the plans of the team. AUDIENCE: Thank you. MARC BACHINGER: You’re welcome. AUDIENCE: Why HLS is
supported both for MediaPlayer and ExoPlayer? HLS is supported both for
MediaPlayer and ExoPlayer. What is the reasons for that? MARC BACHINGER: Yeah. I don’t know, actually. HLS is a very popular
format, and then it was included into
the framework itself. MediaPlayer supports HLS. And then as soon as we
started with ExoPlayer, it makes sense to support
all those most commonly used adaptive formats. AUDIENCE: How you choose that? Which one is better,
ExoPlayer or MediaPlayer? MARC BACHINGER:
Which one is better? AUDIENCE: Yeah. MARC BACHINGER: It depends. So you can try to use streams
if you are OK with what MediaPlayer can do, it’s OK. If you want to
customize the behavior, that’s in the end the thing. If you want to adjust the
player to your requirements in the app, I would
recommend to use ExoPlayer. But if one of those works
for you, both are OK. So there’s no reason to
use one over the other. AUDIENCE: We can try it. MARC BACHINGER: Yeah, exactly. AUDIENCE: One more question. Which protocol is used for
in the YouTube application? MARC BACHINGER:
Oh, I don’t know. I don’t know about the internals
of the YouTube application, sorry. AUDIENCE: Oh, OK. Yeah. Thank you. MARC BACHINGER: You’re welcome. AUDIENCE: Hi, Marc. Thanks for your presentation. So from our experience,
when we use ExoPlayer, some of the lower-end
phones, our experience is that sometimes
the video stutters. Sometimes the video
doesn’t play at all. Do you have any
recommendations how we can figure out if a phone
supports ExoPlayer or not? MARC BACHINGER: It’s hard
to say what the reason is, because– especially when
it comes to decoding, ExoPlayer is using the framework
classes or the framework API as well. So if there– and
those APIs usually are provided by the
vendor, by the OEM, which provides the device. So they are there are
different implementation on each of those devices. And if there is a problem
on certain device, it may be that it’s
just on this device. And it’s very hard to say, in
general, what the problem is on these devices. I would recommend to create a
bug report after you experience this problem. And put this bug report
into an issue on GitHub, and ask the ExoPlayer
team if that they know about a common
issue with these devices. AUDIENCE: Can I ask a follow-up? From my understanding
earlier, you were saying that the YouTube
app is using ExoPlayer by default. Do you know
how they handle it? MARC BACHINGER: No, sorry. I don’t know about the
internals of YouTube app. AUDIENCE: OK, cool. Thank you. MARC BACHINGER: You’re welcome. AUDIENCE: Hi, Marc. One quick question on the video
and audio on the [INAUDIBLE] implementation. Do you have plans to support
[INAUDIBLE] and tunneling? MARC BACHINGER: Support what? AUDIENCE: [INAUDIBLE] you know
in [INAUDIBLE] and tunneling? MARC BACHINGER: No, I
don’t know about it, but maybe we can talk
offline about it. And then I can ask the team. AUDIENCE: Yeah. Thank you. MARC BACHINGER: Welcome. AUDIENCE: Yes one
question on the ExoPlayer. Does the ExoPlayer
have the capability to extract metadata
from the video and display it, overlay
it on the video? MARC BACHINGER:
From what format? AUDIENCE: Let’s say if
your video source has some metadata built into
it, like MPEG-4 part 10, you have on the packer headers,
you can put metadata on that. Does the ExoPlayer
have the framework to extract that metadata
and overlay it on the video? MARC BACHINGER: Good question. I don’t know for MP4. I know, for example for HLS,
we are extracting the ID3 tags. And then you are able to get
the information from these tags. AUDIENCE: That’s different
from the closed caption, that particular slot on the
packer header is different. MARC BACHINGER: Yeah. AUDIENCE: Does this– I mean, we
looked at the Developer Guide. I didn’t see any
references to the metadata. MARC BACHINGER:
Yeah, I’m not sure. Maybe also let us check offline,
and then I can help you maybe. AUDIENCE: Hi, Marc. Does ExoPlayer
rights management. MARC BACHINGER: Yeah. It depends on what adaptive
technology you’re using. If you’re using HLS
AES-128, is supported. And for DASH and
for SmoothStreaming, we support common encryption. So for example, WideVine
and PlayReady on AndroidTV or WideVine on mobile devices. AUDIENCE: How about OMA? MARC BACHINGER: Sorry? AUDIENCE: OMA. MARC BACHINGER: OMA, I
don’t– so in general, if you really want to
have very good security, you have to use one of those
DRM technologies which are available on the devices,
because they need the keys to be in the hardware. And so I think that if you
want a really secure solution, you have to use
WideVine or PlayReady. AUDIENCE: So how
about AndroidTV? Can you use ExoPlayer
on AndroidTV to play your DRM content? MARC BACHINGER: Yeah, sure. Yeah, sure. You can use WideVine and
PlayReady on AndroidTV. AUDIENCE: Thank you. MARC BACHINGER: So
maybe the last question. Yep? AUDIENCE: Hi. So I had a question
on how do you detect cloned Android
devices from the perspective of the ExoPlayer? Also, can you say something
about the ad insertion capabilities? MARC BACHINGER: Yeah. So there is nothing
specifically for ad insertion, currently in ExoPlayer. So we have partners which
do this for themselves. So you have to– that’s
exactly one of the fields which ExoPlayer is very good at. You can replace one
of those components, and do the ad insertion itself. But there’s nothing
provided outside the box. AUDIENCE: OK. What about the cloned devices,
is there a way to detect? MARC BACHINGER:
What devices, sorry? AUDIENCE: Cloned. Let’s say I have a cloned
instance of a valid — like a virtual instance of
a valid Android install, and I’m running that
from the ExoPlayer. I’m running the same
ExoPlayer, same content on it. Is there a way to detect whether
a device is a cloned device or a real device? MARC BACHINGER: Not
built-in into ExoPlayer. You have to do this
for yourself as well. AUDIENCE: OK. Thanks MARC BACHINGER: Thank you. So thank you very much
for your attention. [APPLAUSE] [MUSIC PLAYING]


5 thoughts on “Streaming media with ExoPlayer – Google I/O 2016”

  • Brian Wernick says:

    If you want a super simple way to implement the ExoPlayer in your app you should look at which handles the setup he was talking about and provides you with an API very similar to the MediaPlayer and VideoView

  • Hi, Im following this guideline
    when I open demo project in Android studio, It does load depended project ( such as ffmpeg, flac ,vv..) ,
    (the relevant folders of the demo app have NOT been expanded):

  • Rahul Shrivans says:

    Hi , Thank you very much for the EXO Player & your Video.
    We are trying to use this player for our online Radio Station. The original Library has the best playing capability & plays instantly when stopped or played back. But using this one in the internet Radio app, the challenge occurs while I am travelling & the network is lost on the go!
    So in the initially used FFMPEG player we have done some caching of upto 2 minutes in the player it selves in our internet radio. This allows the player to keep sourcing for the new data & the player never stop even when the data lost for few minutes in case of unstable network.

    But we are trying our best to do the Same thing in ExoPlayer. We got the success too. The caching is happening unto 2 minutes, but some times the player does create issues like taking too long for the to fire up playing.

    Can you please help me if any ready made code with caching is available that I can use in my Android Radio App.
    I shall be great full if you can reply me sooner, since we are struggling on the same since very long.

Leave a Reply

Your email address will not be published. Required fields are marked *