From aacbf07ad726a4ef9bd79da33e4675dcf31bbad8 Mon Sep 17 00:00:00 2001
From: James Taylor <user234683@users.noreply.github.com>
Date: Sat, 28 Aug 2021 09:32:30 -0700
Subject: av-merge: Use tickEnd+1 when calculating segment time ranges
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

tickEnd is inclusive, so two segments might have the following
ticks:

-- Segment 0 --
tickStart: 0
tickEnd: 44099

-- Segment 1 --
tickStart: 44100
tickEnd: 88199

When doing calculations in seconds about segment extent, there
were gaps between segment 0's end and segment 1's beginning. This
sometimes resulted in errors of not finding the corresponding
segment index inside these gaps.

Using (tickEnd+1)/this.sidx.timeScale is the correct method.

Signed-off-by: Jesús <heckyel@hyperbola.info>
---
 youtube/static/js/av-merge.js | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'youtube/static')

diff --git a/youtube/static/js/av-merge.js b/youtube/static/js/av-merge.js
index 84e121c..93664b9 100644
--- a/youtube/static/js/av-merge.js
+++ b/youtube/static/js/av-merge.js
@@ -225,7 +225,7 @@ Stream.prototype.appendSegment = function(segmentIdx, chunk) {
         while (numDeleted < 3 && i < currentSegment) {
             let entry = this.sidx.entries[i];
             let start = entry.tickStart/this.sidx.timeScale;
-            let end = entry.tickEnd/this.sidx.timeScale;
+            let end = (entry.tickEnd+1)/this.sidx.timeScale;
             if (entry.have) {
                 this.reportWarning('Deleting segment', i);
                 this.sourceBuffer.remove(start, end);
@@ -248,7 +248,7 @@ Stream.prototype.getSegmentIdx = function(videoTime) {
     // go up or down to find correct index
     while (index >= 0 && index < this.sidx.entries.length) {
         var entry = this.sidx.entries[index];
-        if (entry.tickStart <= currentTick && entry.tickEnd >= currentTick){
+        if (entry.tickStart <= currentTick && (entry.tickEnd+1) > currentTick){
             return index;
         }
         index = index + increment;
@@ -296,7 +296,7 @@ Stream.prototype.segmentInBuffer = function(segmentIdx) {
     var entry = this.sidx.entries[segmentIdx];
     // allow for 0.01 second error
     var timeStart = entry.tickStart/this.sidx.timeScale + 0.01;
-    var timeEnd = entry.tickEnd/this.sidx.timeScale - 0.01;
+    var timeEnd = (entry.tickEnd+1)/this.sidx.timeScale - 0.01;
     var timeRanges = this.sourceBuffer.buffered;
     for (var i=0; i < timeRanges.length; i++) {
         if (timeRanges.start(i) <= timeStart && timeEnd <= timeRanges.end(i)) {
@@ -311,7 +311,8 @@ Stream.prototype.fetchSegment = function(segmentIdx) {
     this.reportDebug(
         'Fetching segment', segmentIdx, ', bytes',
         entry.start, entry.end, ', seconds',
-        entry.tickStart/this.sidx.timeScale, entry.tickEnd/this.sidx.timeScale
+        entry.tickStart/this.sidx.timeScale,
+        (entry.tickEnd+1)/this.sidx.timeScale
     )
     fetchRange(
         this.url,
-- 
cgit v1.2.3