Delay fillBuffer. Upshift if dl time less than 1s.
Only set up timeupdate and waiting event listeners for fillBuffer and drainBuffer after we have upshifted. This is so that we would download the first segment of the new playlist if the player is setup with autoplay or a user clicks play too early. Also, we should only upshift if our estimated download time for the new segment is less than one second. This is done by estimating the duration length of the segment of the new playlist with the duration of the current segment in the current playlist.
Showing
1 changed file
with
23 additions
and
24 deletions
... | @@ -109,41 +109,40 @@ videojs.Hls.prototype.handleSourceOpen = function() { | ... | @@ -109,41 +109,40 @@ videojs.Hls.prototype.handleSourceOpen = function() { |
109 | this.playlists = new videojs.Hls.PlaylistLoader(this.src_, settings.withCredentials); | 109 | this.playlists = new videojs.Hls.PlaylistLoader(this.src_, settings.withCredentials); |
110 | 110 | ||
111 | this.playlists.on('loadedmetadata', videojs.bind(this, function() { | 111 | this.playlists.on('loadedmetadata', videojs.bind(this, function() { |
112 | var selectedPlaylist, loaderHandler; | 112 | var selectedPlaylist, loaderHandler, newBitrate, segmentDuration, |
113 | segmentDlTime, setupEvents; | ||
113 | 114 | ||
114 | oldMediaPlaylist = this.playlists.media(); | 115 | setupEvents = function() { |
116 | this.fillBuffer(); | ||
115 | 117 | ||
116 | if (this.bandwidth !== this.playlists.bandwidth) { | 118 | // periodically check if new data needs to be downloaded or |
117 | if (this.bandwidth === undefined || this.bandwidth !== undefined && this.bandwidth < this.playlists.bandwidth) { | 119 | // buffered data should be appended to the source buffer |
118 | this.bandwidth = this.playlists.bandwidth; | 120 | player.on('timeupdate', videojs.bind(this, this.fillBuffer)); |
121 | player.on('timeupdate', videojs.bind(this, this.drainBuffer)); | ||
122 | player.on('waiting', videojs.bind(this, this.drainBuffer)); | ||
119 | 123 | ||
124 | player.trigger('loadedmetadata'); | ||
125 | }; | ||
126 | |||
127 | oldMediaPlaylist = this.playlists.media(); | ||
128 | this.bandwidth = this.playlists.bandwidth; | ||
120 | selectedPlaylist = this.selectPlaylist(); | 129 | selectedPlaylist = this.selectPlaylist(); |
121 | if (selectedPlaylist === oldMediaPlaylist) { | 130 | newBitrate = selectedPlaylist.attributes && selectedPlaylist.attributes.BANDWIDTH; |
122 | this.fillBuffer(); | 131 | segmentDuration = oldMediaPlaylist.segments[this.mediaIndex].duration || |
123 | } else { | 132 | oldMediaPlaylist.targetDuration; |
133 | |||
134 | segmentDlTime = (segmentDuration * newBitrate) / this.bandwidth; | ||
135 | |||
136 | if (segmentDlTime <= 1) { | ||
124 | this.playlists.media(selectedPlaylist); | 137 | this.playlists.media(selectedPlaylist); |
125 | loaderHandler = videojs.bind(this, function() { | 138 | loaderHandler = videojs.bind(this, function() { |
126 | this.fillBuffer(); | 139 | setupEvents.call(this); |
127 | this.playlists.off('loadedplaylist', loaderHandler); | 140 | this.playlists.off('loadedplaylist', loaderHandler); |
128 | }); | 141 | }); |
129 | this.playlists.on('loadedplaylist', loaderHandler); | 142 | this.playlists.on('loadedplaylist', loaderHandler); |
130 | } | ||
131 | } else { | ||
132 | this.fillBuffer(); | ||
133 | } | ||
134 | } else { | 143 | } else { |
135 | this.fillBuffer(); | 144 | setupEvents.call(this); |
136 | } | 145 | } |
137 | |||
138 | player.one('play', videojs.bind(this, this.fillBuffer)); | ||
139 | |||
140 | // periodically check if new data needs to be downloaded or | ||
141 | // buffered data should be appended to the source buffer | ||
142 | player.on('timeupdate', videojs.bind(this, this.fillBuffer)); | ||
143 | player.on('timeupdate', videojs.bind(this, this.drainBuffer)); | ||
144 | player.on('waiting', videojs.bind(this, this.drainBuffer)); | ||
145 | |||
146 | player.trigger('loadedmetadata'); | ||
147 | })); | 146 | })); |
148 | 147 | ||
149 | this.playlists.on('error', videojs.bind(this, function() { | 148 | this.playlists.on('error', videojs.bind(this, function() { | ... | ... |
-
Please register or sign in to post a comment