Clear buffered segments on seek
If we're approaching a discontinuity, there may be segments queued up waiting to be appended. Make sure those are cleared if we seek. Add tests.
Showing
2 changed files
with
97 additions
and
0 deletions
... | @@ -239,6 +239,9 @@ var | ... | @@ -239,6 +239,9 @@ var |
239 | segmentXhr.abort(); | 239 | segmentXhr.abort(); |
240 | } | 240 | } |
241 | 241 | ||
242 | // clear out any buffered segments | ||
243 | segmentBuffer = []; | ||
244 | |||
242 | // begin filling the buffer at the new position | 245 | // begin filling the buffer at the new position |
243 | fillBuffer(currentTime * 1000); | 246 | fillBuffer(currentTime * 1000); |
244 | }; | 247 | }; | ... | ... |
... | @@ -1050,6 +1050,100 @@ test('does not break if the playlist has no segments', function() { | ... | @@ -1050,6 +1050,100 @@ test('does not break if the playlist has no segments', function() { |
1050 | strictEqual(requests.length, 1, 'no requests for non-existent segments were queued'); | 1050 | strictEqual(requests.length, 1, 'no requests for non-existent segments were queued'); |
1051 | }); | 1051 | }); |
1052 | 1052 | ||
1053 | test('waits until the buffer is empty before appending bytes at a discontinuity', function() { | ||
1054 | var aborts = 0, currentTime, bufferEnd; | ||
1055 | |||
1056 | player.src({ | ||
1057 | src: 'disc.m3u8', | ||
1058 | type: 'application/vnd.apple.mpegurl' | ||
1059 | }); | ||
1060 | player.hls.mediaSource.trigger({ | ||
1061 | type: 'sourceopen' | ||
1062 | }); | ||
1063 | player.currentTime = function() { return currentTime; }; | ||
1064 | player.buffered = function() { | ||
1065 | return videojs.createTimeRange(0, bufferEnd); | ||
1066 | }; | ||
1067 | player.hls.sourceBuffer.abort = function() { | ||
1068 | aborts++; | ||
1069 | }; | ||
1070 | |||
1071 | requests.pop().respond(200, null, | ||
1072 | '#EXTM3U\n' + | ||
1073 | '#EXTINF:10,0\n' + | ||
1074 | '1.ts\n' + | ||
1075 | '#EXT-X-DISCONTINUITY\n' + | ||
1076 | '#EXTINF:10,0\n' + | ||
1077 | '2.ts\n'); | ||
1078 | standardXHRResponse(requests.pop()); | ||
1079 | |||
1080 | // play to 6s to trigger the next segment request | ||
1081 | currentTime = 6; | ||
1082 | bufferEnd = 10; | ||
1083 | player.trigger('timeupdate'); | ||
1084 | strictEqual(aborts, 0, 'no aborts before the buffer empties'); | ||
1085 | |||
1086 | standardXHRResponse(requests.pop()); | ||
1087 | strictEqual(aborts, 0, 'no aborts before the buffer empties'); | ||
1088 | |||
1089 | // pretend the buffer has emptied | ||
1090 | player.trigger('waiting'); | ||
1091 | strictEqual(aborts, 1, 'aborted before appending the new segment'); | ||
1092 | }); | ||
1093 | |||
1094 | test('clears the segment buffer on seek', function() { | ||
1095 | var aborts = 0, tags = [], currentTime, bufferEnd, oldCurrentTime; | ||
1096 | |||
1097 | videojs.Hls.SegmentParser = mockSegmentParser(tags); | ||
1098 | |||
1099 | player.src({ | ||
1100 | src: 'disc.m3u8', | ||
1101 | type: 'application/vnd.apple.mpegurl' | ||
1102 | }); | ||
1103 | player.hls.mediaSource.trigger({ | ||
1104 | type: 'sourceopen' | ||
1105 | }); | ||
1106 | oldCurrentTime = player.currentTime; | ||
1107 | player.currentTime = function(time) { | ||
1108 | if (time !== undefined) { | ||
1109 | return oldCurrentTime.call(player, time); | ||
1110 | } | ||
1111 | return currentTime; | ||
1112 | }; | ||
1113 | player.buffered = function() { | ||
1114 | return videojs.createTimeRange(0, bufferEnd); | ||
1115 | }; | ||
1116 | player.hls.sourceBuffer.abort = function() { | ||
1117 | aborts++; | ||
1118 | }; | ||
1119 | |||
1120 | requests.pop().respond(200, null, | ||
1121 | '#EXTM3U\n' + | ||
1122 | '#EXTINF:10,0\n' + | ||
1123 | '1.ts\n' + | ||
1124 | '#EXT-X-DISCONTINUITY\n' + | ||
1125 | '#EXTINF:10,0\n' + | ||
1126 | '2.ts\n'); | ||
1127 | standardXHRResponse(requests.pop()); | ||
1128 | |||
1129 | // play to 6s to trigger the next segment request | ||
1130 | currentTime = 6; | ||
1131 | bufferEnd = 10; | ||
1132 | player.trigger('timeupdate'); | ||
1133 | |||
1134 | standardXHRResponse(requests.pop()); | ||
1135 | |||
1136 | // seek back to the beginning | ||
1137 | player.currentTime(0); | ||
1138 | tags.push({ pts: 0, bytes: 0 }); | ||
1139 | standardXHRResponse(requests.pop()); | ||
1140 | strictEqual(aborts, 1, 'aborted once for the seek'); | ||
1141 | |||
1142 | // the source buffer empties. is 2.ts still in the segment buffer? | ||
1143 | player.trigger('waiting'); | ||
1144 | strictEqual(aborts, 1, 'cleared the segment buffer on a seek'); | ||
1145 | }); | ||
1146 | |||
1053 | test('disposes the playlist loader', function() { | 1147 | test('disposes the playlist loader', function() { |
1054 | var disposes = 0, player, loaderDispose; | 1148 | var disposes = 0, player, loaderDispose; |
1055 | player = createPlayer(); | 1149 | player = createPlayer(); | ... | ... |
-
Please register or sign in to post a comment