Guard against the xhr callback clearing segmentXr_ or pendingSegment_ when the c…
…allback is no longer valid In XHR, aborts eventually cause timeouts which cause the callback to be issued again later. We would see that it was a timeout and clear two important state holding properties on the Hls object which could cause problems processing the current segment
Showing
1 changed file
with
17 additions
and
2 deletions
... | @@ -984,17 +984,25 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { | ... | @@ -984,17 +984,25 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { |
984 | // decrease in network performance or a server issue. | 984 | // decrease in network performance or a server issue. |
985 | timeout: (segment.duration * 1.5) * 1000 | 985 | timeout: (segment.duration * 1.5) * 1000 |
986 | }, function(error, request) { | 986 | }, function(error, request) { |
987 | // the segment request is no longer outstanding | 987 | // This is a timeout of a previously aborted segment request |
988 | self.segmentXhr_ = null; | 988 | // so simply ignore it |
989 | if (!self.segmentXhr_ || request !== self.segmentXhr_) { | ||
990 | return; | ||
991 | } | ||
989 | 992 | ||
990 | // if a segment request times out, we may have better luck with another playlist | 993 | // if a segment request times out, we may have better luck with another playlist |
991 | if (request.timedout) { | 994 | if (request.timedout) { |
995 | // the segment request is no longer outstanding | ||
996 | self.segmentXhr_ = null; | ||
992 | self.bandwidth = 1; | 997 | self.bandwidth = 1; |
993 | return self.playlists.media(self.selectPlaylist()); | 998 | return self.playlists.media(self.selectPlaylist()); |
994 | } | 999 | } |
995 | 1000 | ||
996 | // otherwise, trigger a network error | 1001 | // otherwise, trigger a network error |
997 | if (!request.aborted && error) { | 1002 | if (!request.aborted && error) { |
1003 | // the segment request is no longer outstanding | ||
1004 | self.segmentXhr_ = null; | ||
1005 | |||
998 | self.pendingSegment_ = null; | 1006 | self.pendingSegment_ = null; |
999 | return self.blacklistCurrentPlaylist_({ | 1007 | return self.blacklistCurrentPlaylist_({ |
1000 | status: request.status, | 1008 | status: request.status, |
... | @@ -1005,6 +1013,8 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { | ... | @@ -1005,6 +1013,8 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { |
1005 | 1013 | ||
1006 | // stop processing if the request was aborted | 1014 | // stop processing if the request was aborted |
1007 | if (!request.response) { | 1015 | if (!request.response) { |
1016 | // the segment request is no longer outstanding | ||
1017 | self.segmentXhr_ = null; | ||
1008 | return; | 1018 | return; |
1009 | } | 1019 | } |
1010 | 1020 | ||
... | @@ -1016,10 +1026,15 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { | ... | @@ -1016,10 +1026,15 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { |
1016 | } else { | 1026 | } else { |
1017 | segmentInfo.bytes = new Uint8Array(request.response); | 1027 | segmentInfo.bytes = new Uint8Array(request.response); |
1018 | } | 1028 | } |
1029 | |||
1019 | self.pendingSegment_ = segmentInfo; | 1030 | self.pendingSegment_ = segmentInfo; |
1031 | |||
1020 | self.tech_.trigger('progress'); | 1032 | self.tech_.trigger('progress'); |
1021 | self.drainBuffer(); | 1033 | self.drainBuffer(); |
1022 | 1034 | ||
1035 | // the segment request is no longer outstanding | ||
1036 | self.segmentXhr_ = null; | ||
1037 | |||
1023 | // figure out what stream the next segment should be downloaded from | 1038 | // figure out what stream the next segment should be downloaded from |
1024 | // with the updated bandwidth information | 1039 | // with the updated bandwidth information |
1025 | self.playlists.media(self.selectPlaylist()); | 1040 | self.playlists.media(self.selectPlaylist()); | ... | ... |
-
Please register or sign in to post a comment