id,summary,reporter,owner,description,type,status,priority,milestone,component,resolution,keywords,cc,thread
1644,"Support ""sliding window"" DVR in HLS",jeroen,jeroen,"With HLS, live streams are implemented using a ''sliding window'' model. If this window is large (e.g. >5min), we could layer additional UX on top of the player to support seeking into this window and jumping back to the ''Live'' playhead. 

 * Attached are screenshots from other DVR interfaces. Note that some of these don't work for us, since the interface presumes knowledge of the start + duration of a DVR stream. We don't have that with HLS. 
 * Also attached are mockups of the timeslider playback state for different stream types.

In order to implement this correctly, we have to make updates to the providers, API and controlbar.

=== Providers ===

On a provider level, we should ensure that the correct ''onTime()'' and ''getDuration()'' events are fired:

 * For VOD, we do what we do today: duration is the media duration and onTime() if fired multiple times / second when playing. 
 * For live (RTMP + HLS + HTML5 iOS/Safari), we set the duration to -1 for live streams and fire a single ''onTime()'' event every time the PLAYING state is entered. 
 * For DVR (only HLS in Flash),  HLS, we should:
   *  Set the duration to -(dvr seeking range), where the DVR seeking range is defined as the duration from the oldest fragment until N-2 (the live head). This because we shouldn't allow users to seek beyond the live head and get buffer underruns.
   * Set the position to - (distance from live head)
   * Fire time ticks every fragment load (not multiple times/second), in both PLAYING and PAUSED state (not just PLAYING). 

Note the difference between HLS Live and DVR is the window size. Live playlists that have  > 60s data are DVR, others are live.

=== API ===

On an API level, we can support the different playback states as follows:

 * ''Idle'' (before playback starts): getDuration() = 0 and no time ticks.
 * ''Ondemand'': getDuration() > 0 and multiple time ticks / second on playing.
 * ''Live'': getDuration() = -1 and only a single time tick on playing.
 * ''DVR'': getDuration() < -60 and time ticks every fragment load on playing AND paused.

Note that components and scripts shouldn't have to listen to the onMeta() call to determine which stream type a playlistItem is. simply listening to the first onTime() tick will tell them enough. 
 
=== Controlbar ===

",feature,new,Normal,Backlog,streaming,,,,
