assets/scripts.js: More seek/timing logic fixes

This commit is contained in:
Vladimir Panteleev 2019-07-28 03:58:16 +00:00
parent 9367a9fba9
commit ab29b0e5c8

View file

@ -215,47 +215,60 @@ function momentEnd(m, seeked) {
var timerId = 0; var timerId = 0;
var lastMs = 0; var lastMs = 0;
var lastSegment = null;
var segmentTransition = false;
function ontimeupdate(evt) { function ontimeupdate(evt) {
var ms = getCurrentMs(); var ms = getCurrentMs();
var segmentId = getSegmentId(ms); currentSegment = getSegmentId(ms);
// ontimeupdate resolution is about a second. Augment it using timer. // ontimeupdate resolution is about a second. Augment it using timer.
if (timerId) { if (timerId) {
clearTimeout(timerId); clearTimeout(timerId);
timerId = 0; timerId = 0;
} }
if (segmentId && nextSegment && nextSegment != segmentId) { if (currentSegment && nextSegment && nextSegment != currentSegment) {
var timeLeft = segmentMap.segments[segmentId].endTimeMs - ms; var timeLeft = segmentMap.segments[currentSegment].endTimeMs - ms;
timerId = setTimeout(ontimeupdate, timeLeft); timerId = setTimeout(ontimeupdate, timeLeft);
} }
// Distinguish between the user seeking manually with <video> controls, // Distinguish between the user seeking manually with <video> controls,
// and the video playing normally (past some timestamp / boundary). // and the video playing normally (past some timestamp / boundary).
let timeElapsed = ms - lastMs; let timeElapsed = ms - lastMs;
let seeked = timeElapsed >= 0 && timeElapsed < 2000; let seeked = timeElapsed < 0 || timeElapsed >= 2000;
lastMs = ms; lastMs = ms;
// Recalculate title and hash only when we pass some meaningful timestamp. // Recalculate title and hash only when we pass some meaningful timestamp.
let placeChanged = false; let placeChanged = false;
if (currentSegment != segmentId) { // Handle segment change
console.log('ontimeupdate', currentSegment, segmentId, ms, msToString(ms)); if (lastSegment != currentSegment) {
if (seeked) { console.log('ontimeupdate', lastSegment, '->', currentSegment, ms, msToString(ms), seeked);
playSegment(segmentId, true); lastSegment = currentSegment;
} else { if (!seeked) {
// TODO: activate and apply user choice (whether or not it // TODO: activate and apply user choice (whether or not it
// was default) instead of just playing the next segment. // was default) instead of just playing the next segment.
playSegment(nextSegment, true); segmentTransition = true;
if (playSegment(nextSegment, true)) {
// playSegment decided to seek, which means that this
// currentSegment is invalid, and a recursive
// ontimeupdate invocation should have taken care of
// things already. Return.
return;
} }
currentSegment = segmentId; }
setNextSegment(null);
addZones(currentSegment);
placeChanged = true; placeChanged = true;
} }
var moments = getMoments(segmentId, ms); var naturalTransition = !seeked || segmentTransition;
segmentTransition = false;
var moments = getMoments(currentSegment, ms);
for (let k in currentMoments) for (let k in currentMoments)
if (!(k in moments)) { if (!(k in moments)) {
momentEnd(currentMoments[k], seeked); momentEnd(currentMoments[k], !naturalTransition);
placeChanged = true; placeChanged = true;
} }
for (let k in currentMoments) for (let k in currentMoments)
@ -263,14 +276,14 @@ function ontimeupdate(evt) {
momentUpdate(currentMoments[k], ms); momentUpdate(currentMoments[k], ms);
for (let k in moments) for (let k in moments)
if (!(k in currentMoments)) { if (!(k in currentMoments)) {
momentStart(moments[k], seeked); momentStart(moments[k], !naturalTransition);
placeChanged = true; placeChanged = true;
} }
currentMoments = moments; currentMoments = moments;
if (placeChanged) { if (placeChanged) {
let title = 'Bandersnatch'; let title = 'Bandersnatch';
title += ' - Chapter ' + segmentId; title += ' - Chapter ' + currentSegment;
for (let k in moments) { for (let k in moments) {
let m = moments[k]; let m = moments[k];
if (m.type.substr(0, 6) == 'scene:') { if (m.type.substr(0, 6) == 'scene:') {
@ -282,9 +295,9 @@ function ontimeupdate(evt) {
} }
document.title = title; document.title = title;
let hash = segmentId; let hash = currentSegment;
// Pick the moment which starts closer to the current timestamp. // Pick the moment which starts closer to the current timestamp.
let bestMomentStart = segmentMap.segments[segmentId].startTimeMs; let bestMomentStart = segmentMap.segments[currentSegment].startTimeMs;
for (let k in moments) { for (let k in moments) {
let m = moments[k]; let m = moments[k];
if (m.startMs > bestMomentStart) { if (m.startMs > bestMomentStart) {
@ -433,9 +446,8 @@ function seek(ms) {
clearTimeout(timerId); clearTimeout(timerId);
console.log('seek', ms); console.log('seek', ms);
momentSelected = null; momentSelected = null;
lastMs = ms;
currentSegment = getSegmentId(ms);
document.getElementById("video").currentTime = ms / 1000.0; document.getElementById("video").currentTime = ms / 1000.0;
ontimeupdate(null);
} }
function choice(choiceId, text, id) { function choice(choiceId, text, id) {
@ -464,7 +476,9 @@ function playSegment(segmentId, noSeek) {
if (!noSeek || oldSegment != segmentId) { if (!noSeek || oldSegment != segmentId) {
var ms = getSegmentMs(segmentId); var ms = getSegmentMs(segmentId);
seek(ms); seek(ms);
return true;
} }
return false;
} }
var lastHash = ''; var lastHash = '';