Move timestampOffset calculation to fillBuffer from drainBuffer
The state of the player can change between fillBuffer and drainBuffer so we should decide where to place a segment when we decided which segment to fetch
Showing
1 changed file
with
40 additions
and
36 deletions
... | @@ -819,11 +819,14 @@ videojs.HlsHandler.prototype.fillBuffer = function(mediaIndex) { | ... | @@ -819,11 +819,14 @@ videojs.HlsHandler.prototype.fillBuffer = function(mediaIndex) { |
819 | var | 819 | var |
820 | tech = this.tech_, | 820 | tech = this.tech_, |
821 | currentTime = tech.currentTime(), | 821 | currentTime = tech.currentTime(), |
822 | hasBufferedContent = (this.tech_.buffered().length !== 0), | ||
822 | currentBuffered = this.findBufferedRange_(), | 823 | currentBuffered = this.findBufferedRange_(), |
824 | outsideBufferedRanges = !(currentBuffered && currentBuffered.length), | ||
823 | currentBufferedEnd = 0, | 825 | currentBufferedEnd = 0, |
824 | bufferedTime = 0, | 826 | bufferedTime = 0, |
825 | segment, | 827 | segment, |
826 | segmentInfo; | 828 | segmentInfo, |
829 | segmentTimestampOffset; | ||
827 | 830 | ||
828 | // if preload is set to "none", do not download segments until playback is requested | 831 | // if preload is set to "none", do not download segments until playback is requested |
829 | if (this.loadingState_ !== 'segments') { | 832 | if (this.loadingState_ !== 'segments') { |
... | @@ -906,9 +909,39 @@ videojs.HlsHandler.prototype.fillBuffer = function(mediaIndex) { | ... | @@ -906,9 +909,39 @@ videojs.HlsHandler.prototype.fillBuffer = function(mediaIndex) { |
906 | // the state of the buffer before a segment is appended will be | 909 | // the state of the buffer before a segment is appended will be |
907 | // stored here so that the actual segment duration can be | 910 | // stored here so that the actual segment duration can be |
908 | // determined after it has been appended | 911 | // determined after it has been appended |
909 | buffered: null | 912 | buffered: null, |
913 | // The target timestampOffset for this segment when we append it | ||
914 | // to the source buffer | ||
915 | timestampOffset: null | ||
910 | }; | 916 | }; |
911 | 917 | ||
918 | if (mediaIndex > 0) { | ||
919 | segmentTimestampOffset = videojs.Hls.Playlist.duration(segmentInfo.playlist, | ||
920 | segmentInfo.playlist.mediaSequence + mediaIndex) + this.playlists.expired_; | ||
921 | } | ||
922 | |||
923 | // If we have seeked into a non-buffered time-range, remove all buffered | ||
924 | // time-ranges because they could have been incorrectly placed originally | ||
925 | if (this.tech_.seeking() && outsideBufferedRanges) { | ||
926 | // If there are discontinuities in the playlist, we can't be sure of anything | ||
927 | // related to time so we reset the timestamp offset and start appending data | ||
928 | // anew on every seek | ||
929 | if (segmentInfo.playlist.discontinuityStarts.length) { | ||
930 | // Now that the forward buffer is clear, we have to set timestamp offset to | ||
931 | // the start of the buffered region | ||
932 | segmentInfo.timestampOffset = segmentTimestampOffset; | ||
933 | } | ||
934 | } else if (segment.discontinuity && currentBuffered.length) { | ||
935 | // If we aren't seeking and are crossing a discontinuity, we should set | ||
936 | // timestampOffset for new segments to be appended the end of the current | ||
937 | // buffered time-range | ||
938 | segmentInfo.timestampOffset = currentBuffered.end(0); | ||
939 | } else if (!hasBufferedContent && this.tech_.currentTime() > 0.05) { | ||
940 | // If we are trying to play at a position that is not zero but we aren't | ||
941 | // currently seeking according to the video element | ||
942 | segmentInfo.timestampOffset = segmentTimestampOffset; | ||
943 | } | ||
944 | |||
912 | this.loadSegment(segmentInfo); | 945 | this.loadSegment(segmentInfo); |
913 | }; | 946 | }; |
914 | 947 | ||
... | @@ -1068,7 +1101,7 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { | ... | @@ -1068,7 +1101,7 @@ videojs.HlsHandler.prototype.loadSegment = function(segmentInfo) { |
1068 | 1101 | ||
1069 | }; | 1102 | }; |
1070 | 1103 | ||
1071 | videojs.HlsHandler.prototype.drainBuffer = function(event) { | 1104 | videojs.HlsHandler.prototype.drainBuffer = function() { |
1072 | var | 1105 | var |
1073 | segmentInfo, | 1106 | segmentInfo, |
1074 | mediaIndex, | 1107 | mediaIndex, |
... | @@ -1077,11 +1110,7 @@ videojs.HlsHandler.prototype.drainBuffer = function(event) { | ... | @@ -1077,11 +1110,7 @@ videojs.HlsHandler.prototype.drainBuffer = function(event) { |
1077 | bytes, | 1110 | bytes, |
1078 | segment, | 1111 | segment, |
1079 | decrypter, | 1112 | decrypter, |
1080 | segIv, | 1113 | segIv; |
1081 | segmentTimestampOffset = 0, | ||
1082 | hasBufferedContent = (this.tech_.buffered().length !== 0), | ||
1083 | currentBuffered = this.findBufferedRange_(), | ||
1084 | outsideBufferedRanges = !(currentBuffered && currentBuffered.length); | ||
1085 | 1114 | ||
1086 | // if the buffer is empty or the source buffer hasn't been created | 1115 | // if the buffer is empty or the source buffer hasn't been created |
1087 | // yet, do nothing | 1116 | // yet, do nothing |
... | @@ -1144,37 +1173,12 @@ videojs.HlsHandler.prototype.drainBuffer = function(event) { | ... | @@ -1144,37 +1173,12 @@ videojs.HlsHandler.prototype.drainBuffer = function(event) { |
1144 | } | 1173 | } |
1145 | } | 1174 | } |
1146 | 1175 | ||
1147 | event = event || {}; | 1176 | this.pendingSegment_.buffered = this.tech_.buffered(); |
1148 | |||
1149 | if (segmentInfo.mediaIndex > 0) { | ||
1150 | segmentTimestampOffset = videojs.Hls.Playlist.duration(segmentInfo.playlist, | ||
1151 | playlist.mediaSequence + segmentInfo.mediaIndex); | ||
1152 | } | ||
1153 | 1177 | ||
1154 | // If we have seeked into a non-buffered time-range, remove all buffered | 1178 | if (segmentInfo.timestampOffset !== null) { |
1155 | // time-ranges because they could have been incorrectly placed originally | 1179 | this.sourceBuffer.timestampOffset = segmentInfo.timestampOffset; |
1156 | if (this.tech_.seeking() && outsideBufferedRanges) { | ||
1157 | // If there are discontinuities in the playlist, we can't be sure of anything | ||
1158 | // related to time so we reset the timestamp offset and start appending data | ||
1159 | // anew on every seek | ||
1160 | if (segmentInfo.playlist.discontinuityStarts.length) { | ||
1161 | // Now that the forward buffer is clear, we have to set timestamp offset to | ||
1162 | // the start of the buffered region | ||
1163 | this.sourceBuffer.timestampOffset = segmentTimestampOffset; | ||
1164 | } | ||
1165 | } else if (segment.discontinuity && currentBuffered.length) { | ||
1166 | // If we aren't seeking and are crossing a discontinuity, we should set | ||
1167 | // timestampOffset for new segments to be appended the end of the current | ||
1168 | // buffered time-range | ||
1169 | this.sourceBuffer.timestampOffset = currentBuffered.end(0); | ||
1170 | } else if (!hasBufferedContent && this.tech_.currentTime() > 0.05) { | ||
1171 | // If we are trying to play at a position that is not zero but we aren't | ||
1172 | // currently seeking according to the video element | ||
1173 | this.sourceBuffer.timestampOffset = segmentTimestampOffset; | ||
1174 | } | 1180 | } |
1175 | 1181 | ||
1176 | this.pendingSegment_.buffered = this.tech_.buffered(); | ||
1177 | |||
1178 | // the segment is asynchronously added to the current buffered data | 1182 | // the segment is asynchronously added to the current buffered data |
1179 | this.sourceBuffer.appendBuffer(bytes); | 1183 | this.sourceBuffer.appendBuffer(bytes); |
1180 | }; | 1184 | }; | ... | ... |
-
Please register or sign in to post a comment