46460d84 by Gary Katsevman

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.
1 parent 9d190d3e
...@@ -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() {
115
116 if (this.bandwidth !== this.playlists.bandwidth) {
117 if (this.bandwidth === undefined || this.bandwidth !== undefined && this.bandwidth < this.playlists.bandwidth) {
118 this.bandwidth = this.playlists.bandwidth;
119
120 selectedPlaylist = this.selectPlaylist();
121 if (selectedPlaylist === oldMediaPlaylist) {
122 this.fillBuffer();
123 } else {
124 this.playlists.media(selectedPlaylist);
125 loaderHandler = videojs.bind(this, function() {
126 this.fillBuffer();
127 this.playlists.off('loadedplaylist', loaderHandler);
128 });
129 this.playlists.on('loadedplaylist', loaderHandler);
130 }
131 } else {
132 this.fillBuffer();
133 }
134 } else {
135 this.fillBuffer(); 116 this.fillBuffer();
136 }
137 117
138 player.one('play', videojs.bind(this, this.fillBuffer)); 118 // periodically check if new data needs to be downloaded or
119 // buffered data should be appended to the source buffer
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));
139 123
140 // periodically check if new data needs to be downloaded or 124 player.trigger('loadedmetadata');
141 // buffered data should be appended to the source buffer 125 };
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 126
146 player.trigger('loadedmetadata'); 127 oldMediaPlaylist = this.playlists.media();
128 this.bandwidth = this.playlists.bandwidth;
129 selectedPlaylist = this.selectPlaylist();
130 newBitrate = selectedPlaylist.attributes && selectedPlaylist.attributes.BANDWIDTH;
131 segmentDuration = oldMediaPlaylist.segments[this.mediaIndex].duration ||
132 oldMediaPlaylist.targetDuration;
133
134 segmentDlTime = (segmentDuration * newBitrate) / this.bandwidth;
135
136 if (segmentDlTime <= 1) {
137 this.playlists.media(selectedPlaylist);
138 loaderHandler = videojs.bind(this, function() {
139 setupEvents.call(this);
140 this.playlists.off('loadedplaylist', loaderHandler);
141 });
142 this.playlists.on('loadedplaylist', loaderHandler);
143 } else {
144 setupEvents.call(this);
145 }
147 })); 146 }));
148 147
149 this.playlists.on('error', videojs.bind(this, function() { 148 this.playlists.on('error', videojs.bind(this, function() {
......