1*30877f79SAndroid Build Coastguard Worker---
2*30877f79SAndroid Build Coastguard Workertitle: Live streaming
3*30877f79SAndroid Build Coastguard Worker---
4*30877f79SAndroid Build Coastguard Worker
5*30877f79SAndroid Build Coastguard WorkerExoPlayer plays most adaptive live streams out-of-the-box without any special
6*30877f79SAndroid Build Coastguard Workerconfiguration. See the [Supported Formats page][] for more details.
7*30877f79SAndroid Build Coastguard Worker
8*30877f79SAndroid Build Coastguard WorkerAdaptive live streams offer a window of available media that is updated in
9*30877f79SAndroid Build Coastguard Workerregular intervals to move with the current real-time. That means the playback
10*30877f79SAndroid Build Coastguard Workerposition will always be somewhere in this window, in most cases close to the
11*30877f79SAndroid Build Coastguard Workercurrent real-time at which the stream is being produced. The difference between
12*30877f79SAndroid Build Coastguard Workerthe current real-time and the playback position is called the *live offset*.
13*30877f79SAndroid Build Coastguard Worker
14*30877f79SAndroid Build Coastguard WorkerUnlike adaptive live streams, progressive live streams do not have a live window
15*30877f79SAndroid Build Coastguard Workerand can only be played at one position. The documentation on this page is only
16*30877f79SAndroid Build Coastguard Workerrelevant to adaptive live streams.
17*30877f79SAndroid Build Coastguard Worker{:.info}
18*30877f79SAndroid Build Coastguard Worker
19*30877f79SAndroid Build Coastguard WorkerExoPlayer adjusts the live offset by slightly changing the playback speed.
20*30877f79SAndroid Build Coastguard WorkerThe player will try to match user and media preferences, but will also try to
21*30877f79SAndroid Build Coastguard Workerreact to changing network conditions. For example, if rebuffers occur during
22*30877f79SAndroid Build Coastguard Workerplayback, the player will move further away from the live edge. If there is
23*30877f79SAndroid Build Coastguard Workerenough available buffer over a longer period of time, the player will move
24*30877f79SAndroid Build Coastguard Workercloser to the live edge again.
25*30877f79SAndroid Build Coastguard Worker
26*30877f79SAndroid Build Coastguard Worker## Detecting and monitoring live playbacks ##
27*30877f79SAndroid Build Coastguard Worker
28*30877f79SAndroid Build Coastguard WorkerEvery time a live window is updated, registered `Player.Listener` instances
29*30877f79SAndroid Build Coastguard Workerwill receive an `onTimelineChanged` event. You can retrieve details about the
30*30877f79SAndroid Build Coastguard Workercurrent live playback by querying various `Player` and `Timeline.Window`
31*30877f79SAndroid Build Coastguard Workermethods, as listed below and shown in the following figure.
32*30877f79SAndroid Build Coastguard Worker
33*30877f79SAndroid Build Coastguard Worker{% include figure.html url="/images/live-window.png" index="1" caption="Live window" %}
34*30877f79SAndroid Build Coastguard Worker
35*30877f79SAndroid Build Coastguard Worker* `Player.isCurrentWindowLive` indicates whether the currently playing media
36*30877f79SAndroid Build Coastguard Worker  item is a live stream. This value is still true even if the live stream has
37*30877f79SAndroid Build Coastguard Worker  ended.
38*30877f79SAndroid Build Coastguard Worker* `Player.isCurrentWindowDynamic` indicates whether the currently playing media
39*30877f79SAndroid Build Coastguard Worker  item is still being updated. This is usually true for live streams that are
40*30877f79SAndroid Build Coastguard Worker  not yet ended. Note that this flag is also true for non-live streams in some
41*30877f79SAndroid Build Coastguard Worker  cases.
42*30877f79SAndroid Build Coastguard Worker* `Player.getCurrentLiveOffset` returns the offset between the current real
43*30877f79SAndroid Build Coastguard Worker  time and the playback position (if available).
44*30877f79SAndroid Build Coastguard Worker* `Player.getDuration` returns the length of the current live window.
45*30877f79SAndroid Build Coastguard Worker* `Player.getCurrentPosition` returns the playback position relative to the
46*30877f79SAndroid Build Coastguard Worker  start of the live window.
47*30877f79SAndroid Build Coastguard Worker* `Player.getCurrentMediaItem` returns the current media item, where
48*30877f79SAndroid Build Coastguard Worker  `MediaItem.liveConfiguration` contains app-provided overrides for the target
49*30877f79SAndroid Build Coastguard Worker  live offset and live offset adjustment parameters.
50*30877f79SAndroid Build Coastguard Worker* `Player.getCurrentTimeline` returns the current media structure in a
51*30877f79SAndroid Build Coastguard Worker  `Timeline`. The current `Timeline.Window` can be retrieved from the `Timeline`
52*30877f79SAndroid Build Coastguard Worker  using `Player.getCurrentWindowIndex` and `Timeline.getWindow`. Within the
53*30877f79SAndroid Build Coastguard Worker  `Window`:
54*30877f79SAndroid Build Coastguard Worker  * `Window.liveConfiguration` contains the target live offset and and live
55*30877f79SAndroid Build Coastguard Worker    offset adjustment parameters. These values are based on information in the
56*30877f79SAndroid Build Coastguard Worker    media and any app-provided overrides set in `MediaItem.liveConfiguration`.
57*30877f79SAndroid Build Coastguard Worker  * `Window.windowStartTimeMs` is the time since the Unix Epoch at which the
58*30877f79SAndroid Build Coastguard Worker    live window starts.
59*30877f79SAndroid Build Coastguard Worker  * `Window.getCurrentUnixTimeMs` is the time since the Unix Epoch of the
60*30877f79SAndroid Build Coastguard Worker    current real-time. This value may be corrected by a known clock difference
61*30877f79SAndroid Build Coastguard Worker    between the server and the client.
62*30877f79SAndroid Build Coastguard Worker  * `Window.getDefaultPositionMs` is the position in the live window at which
63*30877f79SAndroid Build Coastguard Worker    the player will start playback by default.
64*30877f79SAndroid Build Coastguard Worker
65*30877f79SAndroid Build Coastguard Worker## Seeking in live streams ##
66*30877f79SAndroid Build Coastguard Worker
67*30877f79SAndroid Build Coastguard WorkerYou can seek to anywhere within the live window using `Player.seekTo`. The seek
68*30877f79SAndroid Build Coastguard Workerposition passed is relative to the start of the live window. For example,
69*30877f79SAndroid Build Coastguard Worker `seekTo(0)` will seek to the start of the live window. The player will try to
70*30877f79SAndroid Build Coastguard Workerkeep the same live offset as the seeked-to position after a seek.
71*30877f79SAndroid Build Coastguard Worker
72*30877f79SAndroid Build Coastguard WorkerThe live window also has a default position at which playback is supposed to
73*30877f79SAndroid Build Coastguard Workerstart. This position is usually somewhere close to the live edge. You can seek
74*30877f79SAndroid Build Coastguard Workerto the default position by calling `Player.seekToDefaultPosition`.
75*30877f79SAndroid Build Coastguard Worker
76*30877f79SAndroid Build Coastguard Worker## Live playback UI ##
77*30877f79SAndroid Build Coastguard Worker
78*30877f79SAndroid Build Coastguard WorkerExoPlayer's [default UI components][] show the duration of the live window and
79*30877f79SAndroid Build Coastguard Workerthe current playback position within it. This means the position will appear to
80*30877f79SAndroid Build Coastguard Workerjump backwards each time the live window is updated. If you need different
81*30877f79SAndroid Build Coastguard Workerbehavior, for example showing the Unix time or the current live offset, you can
82*30877f79SAndroid Build Coastguard Workerfork `StyledPlayerControlView` and modify it to suit your needs.
83*30877f79SAndroid Build Coastguard Worker
84*30877f79SAndroid Build Coastguard WorkerThere is a [pending feature request (#2213)][] for ExoPlayer's default UI
85*30877f79SAndroid Build Coastguard Workercomponents to support additional modes when playing live streams.
86*30877f79SAndroid Build Coastguard Worker{:.info}
87*30877f79SAndroid Build Coastguard Worker
88*30877f79SAndroid Build Coastguard Worker## Configuring live playback parameters ##
89*30877f79SAndroid Build Coastguard Worker
90*30877f79SAndroid Build Coastguard WorkerBy default, ExoPlayer uses live playback parameters defined by the media. If you
91*30877f79SAndroid Build Coastguard Workerwant to configure the live playback parameters yourself, you can set them on a
92*30877f79SAndroid Build Coastguard Workerper `MediaItem` basis by calling `MediaItem.Builder.setLiveConfiguration`. If
93*30877f79SAndroid Build Coastguard Workeryou'd like to set these values globally for all items, you can set them on the
94*30877f79SAndroid Build Coastguard Worker`DefaultMediaSourceFactory` provided to the player. In both cases, the provided
95*30877f79SAndroid Build Coastguard Workervalues will override parameters defined by the media.
96*30877f79SAndroid Build Coastguard Worker
97*30877f79SAndroid Build Coastguard Worker~~~
98*30877f79SAndroid Build Coastguard Worker// Global settings.
99*30877f79SAndroid Build Coastguard WorkerExoPlayer player =
100*30877f79SAndroid Build Coastguard Worker    new ExoPlayer.Builder(context)
101*30877f79SAndroid Build Coastguard Worker        .setMediaSourceFactory(
102*30877f79SAndroid Build Coastguard Worker            new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000))
103*30877f79SAndroid Build Coastguard Worker        .build();
104*30877f79SAndroid Build Coastguard Worker
105*30877f79SAndroid Build Coastguard Worker// Per MediaItem settings.
106*30877f79SAndroid Build Coastguard WorkerMediaItem mediaItem =
107*30877f79SAndroid Build Coastguard Worker    new MediaItem.Builder()
108*30877f79SAndroid Build Coastguard Worker        .setUri(mediaUri)
109*30877f79SAndroid Build Coastguard Worker        .setLiveConfiguration(
110*30877f79SAndroid Build Coastguard Worker            new MediaItem.LiveConfiguration.Builder()
111*30877f79SAndroid Build Coastguard Worker                .setMaxPlaybackSpeed(1.02f)
112*30877f79SAndroid Build Coastguard Worker                .build())
113*30877f79SAndroid Build Coastguard Worker        .build();
114*30877f79SAndroid Build Coastguard Workerplayer.setMediaItem(mediaItem);
115*30877f79SAndroid Build Coastguard Worker~~~
116*30877f79SAndroid Build Coastguard Worker{: .language-java}
117*30877f79SAndroid Build Coastguard Worker
118*30877f79SAndroid Build Coastguard WorkerAvailable configuration values are:
119*30877f79SAndroid Build Coastguard Worker
120*30877f79SAndroid Build Coastguard Worker* `targetOffsetMs`: The target live offset. The player will attempt to get
121*30877f79SAndroid Build Coastguard Worker  close to this live offset during playback if possible.
122*30877f79SAndroid Build Coastguard Worker* `minOffsetMs`: The minimum allowed live offset. Even when adjusting the
123*30877f79SAndroid Build Coastguard Worker  offset to current network conditions, the player will not attempt to get below
124*30877f79SAndroid Build Coastguard Worker  this offset during playback.
125*30877f79SAndroid Build Coastguard Worker* `maxOffsetMs`: The maximum allowed live offset. Even when adjusting the
126*30877f79SAndroid Build Coastguard Worker  offset to current network conditions, the player will not attempt to get above
127*30877f79SAndroid Build Coastguard Worker  this offset during playback.
128*30877f79SAndroid Build Coastguard Worker* `minPlaybackSpeed`: The minimum playback speed the player can use to fall back
129*30877f79SAndroid Build Coastguard Worker  when trying to reach the target live offset.
130*30877f79SAndroid Build Coastguard Worker* `maxPlaybackSpeed`: The maximum playback speed the player can use to catch up
131*30877f79SAndroid Build Coastguard Worker  when trying to reach the target live offset.
132*30877f79SAndroid Build Coastguard Worker
133*30877f79SAndroid Build Coastguard WorkerIf automatic playback speed adjustment is not desired, it can be disabled by
134*30877f79SAndroid Build Coastguard Workersetting `minPlaybackSpeed` and `maxPlaybackSpeed` to `1.0f`.
135*30877f79SAndroid Build Coastguard Worker
136*30877f79SAndroid Build Coastguard Worker## BehindLiveWindowException and ERROR_CODE_BEHIND_LIVE_WINDOW ##
137*30877f79SAndroid Build Coastguard Worker
138*30877f79SAndroid Build Coastguard WorkerThe playback position may fall behind the live window, for example if the player
139*30877f79SAndroid Build Coastguard Workeris paused or buffering for a long enough period of time. If this happens then
140*30877f79SAndroid Build Coastguard Workerplayback will fail and an exception with error code
141*30877f79SAndroid Build Coastguard Worker`ERROR_CODE_BEHIND_LIVE_WINDOW` will be reported via
142*30877f79SAndroid Build Coastguard Worker`Player.Listener.onPlayerError`. Application code may wish to handle such
143*30877f79SAndroid Build Coastguard Workererrors by resuming playback at the default position. The [PlayerActivity][] of
144*30877f79SAndroid Build Coastguard Workerthe demo app exemplifies this approach.
145*30877f79SAndroid Build Coastguard Worker
146*30877f79SAndroid Build Coastguard Worker~~~
147*30877f79SAndroid Build Coastguard Worker@Override
148*30877f79SAndroid Build Coastguard Workerpublic void onPlayerError(PlaybackException error) {
149*30877f79SAndroid Build Coastguard Worker  if (eror.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) {
150*30877f79SAndroid Build Coastguard Worker    // Re-initialize player at the current live window default position.
151*30877f79SAndroid Build Coastguard Worker    player.seekToDefaultPosition();
152*30877f79SAndroid Build Coastguard Worker    player.prepare();
153*30877f79SAndroid Build Coastguard Worker  } else {
154*30877f79SAndroid Build Coastguard Worker    // Handle other errors.
155*30877f79SAndroid Build Coastguard Worker  }
156*30877f79SAndroid Build Coastguard Worker}
157*30877f79SAndroid Build Coastguard Worker~~~
158*30877f79SAndroid Build Coastguard Worker{: .language-java}
159*30877f79SAndroid Build Coastguard Worker
160*30877f79SAndroid Build Coastguard Worker## Customizing the playback speed adjustment algorithm ##
161*30877f79SAndroid Build Coastguard Worker
162*30877f79SAndroid Build Coastguard WorkerTo stay close to the target live offset, a `LivePlaybackSpeedControl` is used to
163*30877f79SAndroid Build Coastguard Workermake adjustments to the playback speed during live playbacks. It's possible to
164*30877f79SAndroid Build Coastguard Workerimplement a custom `LivePlaybackSpeedControl`, or to customize the default
165*30877f79SAndroid Build Coastguard Workerimplementation, which is `DefaultLivePlaybackSpeedControl`. In both cases an
166*30877f79SAndroid Build Coastguard Workerinstance can be set when building the player:
167*30877f79SAndroid Build Coastguard Worker
168*30877f79SAndroid Build Coastguard Worker~~~
169*30877f79SAndroid Build Coastguard WorkerExoPlayer player =
170*30877f79SAndroid Build Coastguard Worker    new ExoPlayer.Builder(context)
171*30877f79SAndroid Build Coastguard Worker        .setLivePlaybackSpeedControl(
172*30877f79SAndroid Build Coastguard Worker            new DefaultLivePlaybackSpeedControl.Builder()
173*30877f79SAndroid Build Coastguard Worker                .setFallbackMaxPlaybackSpeed(1.04f)
174*30877f79SAndroid Build Coastguard Worker                .build())
175*30877f79SAndroid Build Coastguard Worker        .build();
176*30877f79SAndroid Build Coastguard Worker~~~
177*30877f79SAndroid Build Coastguard Worker{: .language-java}
178*30877f79SAndroid Build Coastguard Worker
179*30877f79SAndroid Build Coastguard WorkerRelevant customization parameters of `DefaultLivePlaybackSpeedControl` are:
180*30877f79SAndroid Build Coastguard Worker
181*30877f79SAndroid Build Coastguard Worker* `fallbackMinPlaybackSpeed` and `fallbackMaxPlaybackSpeed`: The minimum and
182*30877f79SAndroid Build Coastguard Worker  maximum playback speeds that can be used for adjustment if neither the media
183*30877f79SAndroid Build Coastguard Worker  nor the app-provided `MediaItem` define limits.
184*30877f79SAndroid Build Coastguard Worker* `proportionalControlFactor`: Controls how smooth the speed adjustment is. A
185*30877f79SAndroid Build Coastguard Worker  high value makes adjustments more sudden and reactive, but also more likely to
186*30877f79SAndroid Build Coastguard Worker  be audible. A smaller value results in a smoother transition between speeds,
187*30877f79SAndroid Build Coastguard Worker  at the cost of being slower.
188*30877f79SAndroid Build Coastguard Worker* `targetLiveOffsetIncrementOnRebufferMs`: This value is added to the target
189*30877f79SAndroid Build Coastguard Worker  live offset whenever a rebuffer occurs, in order to proceed more cautiously.
190*30877f79SAndroid Build Coastguard Worker  This feature can be disabled by setting the value to 0.
191*30877f79SAndroid Build Coastguard Worker* `minPossibleLiveOffsetSmoothingFactor`: An exponential smoothing factor that
192*30877f79SAndroid Build Coastguard Worker  is used to track the minimum possible live offset based on the currently
193*30877f79SAndroid Build Coastguard Worker  buffered media. A value very close to 1 means that the estimation is more
194*30877f79SAndroid Build Coastguard Worker  cautious and may take longer to adjust to improved network conditions, whereas
195*30877f79SAndroid Build Coastguard Worker  a lower value means the estimation will adjust faster at a higher risk of
196*30877f79SAndroid Build Coastguard Worker  running into rebuffers.
197*30877f79SAndroid Build Coastguard Worker
198*30877f79SAndroid Build Coastguard Worker[Supported Formats page]: {{ site.baseurl }}/supported-formats.html
199*30877f79SAndroid Build Coastguard Worker[default UI components]: {{ site.baseurl }}/ui-components.html
200*30877f79SAndroid Build Coastguard Worker[pending feature request (#2213)]: https://github.com/google/ExoPlayer/issues/2213
201*30877f79SAndroid Build Coastguard Worker[PlayerActivity]: {{ site.release_v2 }}/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
202