Don't abort a playlist request just to re-issue the same request
Check the outstanding request URL before aborting playlist requests when a switch is requested. Don't filter out requests that are generated as a result of another request finishing in the switcher simulator. Actual playlist switching is showing up in the graph now.
Showing
4 changed files
with
48 additions
and
16 deletions
... | @@ -147,10 +147,17 @@ | ... | @@ -147,10 +147,17 @@ |
147 | return; | 147 | return; |
148 | } | 148 | } |
149 | 149 | ||
150 | |||
151 | |||
150 | loader.state = 'SWITCHING_MEDIA'; | 152 | loader.state = 'SWITCHING_MEDIA'; |
151 | 153 | ||
152 | // abort any outstanding playlist refreshes | 154 | // there is already an outstanding playlist request |
153 | if (request) { | 155 | if (request) { |
156 | if (resolveUrl(loader.master.uri, playlist.uri) === request.url) { | ||
157 | // requesting to switch to the same playlist multiple times | ||
158 | // has no effect after the first | ||
159 | return; | ||
160 | } | ||
154 | request.abort(); | 161 | request.abort(); |
155 | request = null; | 162 | request = null; |
156 | } | 163 | } | ... | ... |
... | @@ -563,6 +563,7 @@ xhr = videojs.Hls.xhr = function(url, callback) { | ... | @@ -563,6 +563,7 @@ xhr = videojs.Hls.xhr = function(url, callback) { |
563 | 563 | ||
564 | request = new window.XMLHttpRequest(); | 564 | request = new window.XMLHttpRequest(); |
565 | request.open(options.method, url); | 565 | request.open(options.method, url); |
566 | request.url = url; | ||
566 | 567 | ||
567 | if (options.responseType) { | 568 | if (options.responseType) { |
568 | request.responseType = options.responseType; | 569 | request.responseType = options.responseType; | ... | ... |
... | @@ -349,6 +349,27 @@ | ... | @@ -349,6 +349,27 @@ |
349 | strictEqual(requests.length, 0, 'no requests is sent'); | 349 | strictEqual(requests.length, 0, 'no requests is sent'); |
350 | }); | 350 | }); |
351 | 351 | ||
352 | test('does not abort requests when the same playlist is re-requested', function() { | ||
353 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); | ||
354 | requests.pop().respond(200, null, | ||
355 | '#EXTM3U\n' + | ||
356 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + | ||
357 | 'low.m3u8\n' + | ||
358 | '#EXT-X-STREAM-INF:BANDWIDTH=2\n' + | ||
359 | 'high.m3u8\n'); | ||
360 | requests.pop().respond(200, null, | ||
361 | '#EXTM3U\n' + | ||
362 | '#EXT-X-MEDIA-SEQUENCE:0\n' + | ||
363 | '#EXTINF:10,\n' + | ||
364 | 'low-0.ts\n' + | ||
365 | '#EXT-X-ENDLIST\n'); | ||
366 | loader.media('high.m3u8'); | ||
367 | loader.media('high.m3u8'); | ||
368 | |||
369 | strictEqual(requests.length, 1, 'made only one request'); | ||
370 | ok(!requests[0].aborted, 'request not aborted'); | ||
371 | }); | ||
372 | |||
352 | test('throws an error if a media switch is initiated too early', function() { | 373 | test('throws an error if a media switch is initiated too early', function() { |
353 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); | 374 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
354 | 375 | ... | ... |
... | @@ -135,7 +135,7 @@ | ... | @@ -135,7 +135,7 @@ |
135 | var master = '#EXTM3U\n' + | 135 | var master = '#EXTM3U\n' + |
136 | options.playlists.reduce(function(playlists, value) { | 136 | options.playlists.reduce(function(playlists, value) { |
137 | return playlists + | 137 | return playlists + |
138 | '#EXT-X-STREAM-INF:' + value + '\n' + | 138 | '#EXT-X-STREAM-INF:BANDWIDTH=' + value + '\n' + |
139 | 'playlist-' + value + '\n'; | 139 | 'playlist-' + value + '\n'; |
140 | }, ''), | 140 | }, ''), |
141 | buffered = 0, | 141 | buffered = 0, |
... | @@ -171,26 +171,23 @@ | ... | @@ -171,26 +171,23 @@ |
171 | }); | 171 | }); |
172 | 172 | ||
173 | // deliver responses if they're ready | 173 | // deliver responses if they're ready |
174 | requests = requests.reduce(function(remaining, request) { | 174 | requests.forEach(function(request, i) { |
175 | var arrival = request.startTime + propagationDelay, | 175 | var arrival = request.startTime + propagationDelay, |
176 | segmentSize = +request.url.match(/(\d+)-\d+$/)[1] * segmentDuration; | 176 | segmentSize; |
177 | 177 | ||
178 | // playlist responses | 178 | // playlist responses |
179 | if (/playlist-\d+$/.test(request.url)) { | 179 | if (/playlist-\d+$/.test(request.url)) { |
180 | // playlist responses have no trasmission time | 180 | // for simplicity, playlist responses have zero trasmission time |
181 | if (t === arrival) { | 181 | if (t === arrival) { |
182 | request.respond(200, null, playlistResponse(+requests[0].url.match(/\d+$/))); | 182 | request.respond(200, null, playlistResponse(+requests[0].url.match(/\d+$/))); |
183 | return remaining; | 183 | // the request is completed |
184 | return requests.splice(requests.indexOf(request), 1); | ||
184 | } | 185 | } |
185 | // the response has not arrived. re-enqueue it for later. | 186 | return; |
186 | return remaining.concat(request); | ||
187 | } | 187 | } |
188 | 188 | ||
189 | // segment responses | 189 | // segment responses |
190 | if (t >= arrival) { | 190 | segmentSize = +request.url.match(/(\d+)-\d+$/)[1] * segmentDuration; |
191 | request.delivered += results.bandwidth[t].bandwidth; | ||
192 | |||
193 | } | ||
194 | // segment response headers arrive after the propogation delay | 191 | // segment response headers arrive after the propogation delay |
195 | if (t === arrival) { | 192 | if (t === arrival) { |
196 | results.playlists.push({ | 193 | results.playlists.push({ |
... | @@ -205,12 +202,18 @@ | ... | @@ -205,12 +202,18 @@ |
205 | if (request.delivered >= segmentSize) { | 202 | if (request.delivered >= segmentSize) { |
206 | buffered += segmentDuration; | 203 | buffered += segmentDuration; |
207 | request.status = 200; | 204 | request.status = 200; |
208 | request.response = new Uint8Array(segmentSize); | 205 | request.response = new Uint8Array(segmentSize * 0.125); |
209 | request.setResponseBody(''); | 206 | request.setResponseBody(''); |
210 | return remaining; | 207 | // the request is completed |
208 | return requests.splice(requests.indexOf(request), 1); | ||
209 | } | ||
210 | // transmit the bits for this tick | ||
211 | if (t >= arrival) { | ||
212 | request.delivered += results.bandwidth[t].bandwidth; | ||
213 | |||
211 | } | 214 | } |
212 | // response has not arrived fully, re-enqueue it for later | 215 | // response has not arrived fully |
213 | return remaining.concat(request); | 216 | return; |
214 | }, []); | 217 | }, []); |
215 | 218 | ||
216 | // simulate playback | 219 | // simulate playback | ... | ... |
-
Please register or sign in to post a comment