Skip to content

Commit

Permalink
Fix sample replacement test
Browse files Browse the repository at this point in the history
  • Loading branch information
varumugam123 committed Oct 28, 2023
1 parent d669635 commit 4c1db0a
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 55 deletions.
5 changes: 1 addition & 4 deletions mse/lib/big_buck_bunny_720p_30fps.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ function bufferIndexFromTime(time, segmentDuration = 4) {
}

function urlsThroughNumber(urlTemplate, start, end) {
var result = []
for (let i = start; i <= end; ++i)
result.push(urlTemplate.replace('$Number$', i))
return result
return range(start, end).map((i) => urlTemplate.replace('$Number$', i));
}

13 changes: 12 additions & 1 deletion mse/lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,16 @@ function logAllSourceBufferInfo() {
forAllSourceBuffers(logSourceBufferInfo);
}

// Ref : https://dev.to/ycmjason/how-to-create-range-in-javascript-539i#:~:text=range%20is%20a%20function%20that,be%20using%20a%20for%20loop.
const rangeImpl = (s, e) => e > s ? Array(e - s + 1).fill(0).map((x, y) => y + s) : Array(s - e + 1).fill(0).map((x, y) => - y + s);
function range(start, end) {
if (end === undefined) {
end = start;
start = 0;
}
return rangeImpl(start, end);
}

// Cleanup functions

function performCommonCleanup() {
Expand All @@ -209,4 +219,5 @@ function performCommonCleanup() {
video.src = ''
video.remove()
}).catch((e) => { console.log("VIVEK-DBG: Failed to remove video, " + e); });
}
}

11 changes: 8 additions & 3 deletions mse/lib/feeder.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ function Feeder(sourceBuffer, urls, endedCb, onAppendComplete, isVideo) {
if ((this.sourceBuffer && this.sourceBuffer.updating) || this.urls.length == 0 || this.ended)
return

if (this.fetchindex > 0 && this.appendComplete !== undefined && this.appendComplete != null)
this.appendComplete(isVideo, (this.fetchindex / this.urls.length) * 100)
// This is because first time onUpdateEnd is called by Feeder itself to kick start fetchAndAppend()
if (this.fetchindex > 0) {
this.bufferCount++;
if (this.appendComplete !== undefined && this.appendComplete != null)
this.appendComplete(isVideo, (this.fetchindex / this.urls.length) * 100)
}

if (this.fetchindex == this.urls.length) {
console.log("VIVEK-DBG: All " + (isVideo ? "video" : "audio") + " buffers are pushed");
Expand Down Expand Up @@ -85,10 +89,11 @@ function Feeder(sourceBuffer, urls, endedCb, onAppendComplete, isVideo) {
this.xhr = undefined
this.urls = urls

this.bufferCount = 0
this.sourceBuffer = sourceBuffer
this.sourceBuffer.onupdateend = (e) => { this.onUpdateEnd() }

this.onUpdateEnd()
scheduleTask(() => { this.onUpdateEnd(); }, 10);
}

// Utility functions
Expand Down
103 changes: 57 additions & 46 deletions mse/tests/sample-replacement.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,60 +119,62 @@
function checkBufferPercentageAndwaitForCondition(isVideo, bufferPercentage) {
// console.log("VIVEK-DBG: checkBufferPercentageAndwaitForCondition: " + isVideo + " : " + video.readyState.toString() + ", " + bufferPercentage);

if (video.readyState >= 1) {
if (isVideo) {
if (feeders.video)
feeders.video.appendComplete = undefined;
} else {
if (feeders.audio)
feeders.audio.appendComplete = undefined;
}
let feeder = isVideo ? feeders.video : feeders.audio;
if(feeder === undefined || feeder == null)
return;

let allSourceBuffersHaveData = allFeedersMeetCondition((feeder, isVideo) => {
return (feeder.appendComplete === undefined);
});

if (allSourceBuffersHaveData) {
let checkTimeAfterReplacement = function () {
waitForEvent(video, 'timeupdate', 1000).then(() => {
console.log("VIVEK-DBG: Got timeupdate event");
video.timeCheckCounter = 5;
video.ontimeupdate = () => {
if(video.timeCheckCounter <= 0) {
video.ontimeupdate = null
return;
}
video.timeCheckCounter--;

let currentTime = video.currentTime
let reenqueueTime = (isVideo ? (feeders.video ? feeders.video.timeOfReenqueue : 0) : (feeders.audio ? feeders.audio.timeOfReenqueue : 0))
if(currentTime < reenqueueTime) {
video.ontimeupdate = null
console.log("VIVEK-DBG: Current time " + currentTime + " is less than the time of reenqueue time " + reenqueueTime);
cleanup();
}
// wait for two buffers (including initialization segment) to start playback from 0 and wait for 1 buffer on reenqueue
let buffersToStartMonitoringForPlaying = (feeder.reenqueue && feeder.doneReenqueuing) ? 1 : 2;

// Once enough buffers to get the playback started are appended remove appendBufferCompletion monitoring
if(feeder.bufferCount == buffersToStartMonitoringForPlaying)
feeder.appendComplete = undefined;

let allSourceBuffersHaveData = allFeedersMeetCondition((feeder, isVideo) => {
return (feeder.appendComplete === undefined);
});

// When all sources have enough buffers to get started
if (allSourceBuffersHaveData) {
let checkTimeAfterReplacement = function (count=10) {
waitForEvent(video, 'timeupdate', 1000).then(() => {
console.log("VIVEK-DBG: Got timeupdate event");
video.timeCheckCounter = count;
video.ontimeupdate = () => {
if(video.timeCheckCounter <= 0) {
video.ontimeupdate = null
return;
}
}).catch(() => {
console.log("VIVEK-DBG: Enough data is fed, but timeupdate event is not received");
cleanup()
})
}

waitForEvent(video, 'playing', 10000, "Enough data is fed, but playing event not received").then(() => {
console.log("VIVEK-DBG: Player started playback");
checkTimeAfterReplacement();
}).catch((error) => {
console.log("VIVEK-DBG: " + error);
video.timeCheckCounter--;

let currentTime = video.currentTime
let reenqueueTime = (isVideo ? (feeders.video ? feeders.video.timeOfReenqueue : 0) : (feeders.audio ? feeders.audio.timeOfReenqueue : 0))
if(currentTime < reenqueueTime) {
video.ontimeupdate = null
console.log("VIVEK-DBG: Current time " + currentTime + " is less than the time of reenqueue time " + reenqueueTime);
cleanup();
}
}
}).catch(() => {
console.log("VIVEK-DBG: Enough data is fed, but timeupdate event is not received");
cleanup()
})
}

waitForCondition(checkForPlaying, 10000, "Enough data is fed, but playback hasn't started").then(() => {
console.log("VIVEK-DBG: Player started playback");
if(feeder.doneReenqueuing)
checkTimeAfterReplacement();
}).catch((error) => {
console.log("VIVEK-DBG: " + error);
cleanup()
})
}
}

var finishOrRenenqueue = (isVideo, urls, reenqueueTime) => {
if (feeders.video == null && feeders.audio == null) {
if (feeders.video == null && feeders.audio == null)
return;
}

let feeder = (isVideo ? feeders.video : feeders.audio);
let shouldReenqueue = (isVideo ? feeders.video.reenqueue : feeders.audio.reenqueue);
Expand All @@ -182,7 +184,7 @@
if (shouldReenqueue) {
if (feeder.scheduledReenqueueAt !== undefined && feeder.scheduledReenqueueAt != -1 && video.currentTime < feeder.scheduledReenqueueAt) {
let delta = (feeder.scheduledReenqueueAt >= video.currentTime) ? (feeder.scheduledReenqueueAt - video.currentTime) * 1000 : 0;
let timeOut = (delta > 100) ? delta : 50;
let timeOut = (delta > 50) ? delta : 50;
console.log("Scheduling task to reenqueue in " + timeOut + " ms, for " + (isVideo ? "Video" : "Audio") + " @ " + video.currentTime);
setTimeout(() => { finishOrRenenqueue(isVideo, urls, feeder.reenqueueAt); }, timeOut);
return;
Expand All @@ -191,11 +193,18 @@
let timeOfReenqueue = video.currentTime;
var attachNewFeeder = function () {
let newFeeder = new Feeder(sourceBuffer, urls, onFeedEnded, checkBufferPercentageAndwaitForCondition, isVideo);
newFeeder.reenqueue = feeder.reenqueue;
newFeeder.scheduledReenqueueAt = feeder.scheduledReenqueueAt;
newFeeder.removeFragment = feeder.removeFragment;
newFeeder.timeOfReenqueue = timeOfReenqueue
newFeeder.doneReenqueuing= true;

if (isVideo)
feeders.video = newFeeder;
else
feeders.audio = newFeeder;
newFeeder.timeOfReenqueue = timeOfReenqueue

console.log("VIVEK-DBG: Attached new feeder for " + (isVideo ? "Video" : "Audio"));
}

if (shouldRemoveFragment) {
Expand Down Expand Up @@ -236,6 +245,8 @@
feeder.reenqueue = isVideo ? reenqueueVideo : reenqueueAudio;
feeder.scheduledReenqueueAt = isVideo ? reenqueueVideoAt : reenqueueAudioAt;
feeder.removeFragment = removeDataOnReenqueue;
feeder.doneReenqueuing = false

console.log("VIVEK-DBG: " + (isVideo ? "Video" : "Audio") + ", Reenqueue:" + feeder.reenqueue + ", ReenqueueAt:" + feeder.scheduledReenqueueAt + ", RemoveDataOnReenqueue:" + feeder.removeFragment);
})
}
Expand Down
2 changes: 1 addition & 1 deletion mse/tests/seek-to-unbuffered-range-rewind.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
video.addEventListener('timeupdate', function onTimeUpdate() {
if (video.currentTime >= 15.5) {
video.removeEventListener('timeupdate', onTimeUpdate);
console.log("VIVEK-DBG: Rewinding to 0.25");
console.log("VIVEK-DBG: Rewinding to 0.25, for which no data is pushed yet");
video.currentTime = 0.25;

feeders.video = null;
Expand Down

0 comments on commit 4c1db0a

Please sign in to comment.