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