mirror of https://github.com/ekimekim/wubloader
Auto-format JS files with prettier
Prettier is a tool for formatting JS files. We add a minimal configuration to suit our purposes, and run it on all our JS files. The main things this corrects is mixed tab and space indent issues (replacing fully with tabs), overly long lines, inconsistent quote usage (prefers double-quotes instead), and missing semicolons.pull/225/head
parent
6c97bd462e
commit
ce73f7b0ea
@ -0,0 +1,11 @@
|
|||||||
|
# Config for auto-formatting of our JS files using prettier
|
||||||
|
# https://prettier.io/docs/en/configuration.html
|
||||||
|
|
||||||
|
# This is NOT a length limit but a hint to the auto-formatter for how long lines should try to be.
|
||||||
|
printWidth: 100
|
||||||
|
# Use tabs for indentation, spaces for alignment
|
||||||
|
useTabs: true
|
||||||
|
# do {foo: bar} not { foo: bar }. personal preference.
|
||||||
|
bracketSpacing: false
|
||||||
|
# prefer "arg => body" over "(arg) => body" when possible
|
||||||
|
arrowParens: avoid
|
@ -1,423 +1,515 @@
|
|||||||
var desertBusStart = new Date("1970-01-01T00:00:00Z");
|
var desertBusStart = new Date("1970-01-01T00:00:00Z");
|
||||||
var timeFormat = 'AGO';
|
var timeFormat = "AGO";
|
||||||
|
|
||||||
pageSetup = function(isEditor) {
|
pageSetup = function (isEditor) {
|
||||||
|
//Get values from ThrimShim
|
||||||
//Get values from ThrimShim
|
if (isEditor && /id=/.test(document.location.search)) {
|
||||||
if(isEditor && /id=/.test(document.location.search)) {
|
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
||||||
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
fetch("/thrimshim/" + rowId)
|
||||||
fetch("/thrimshim/"+rowId).then(data => data.json()).then(function (data) {
|
.then(data => data.json())
|
||||||
if (!data) {
|
.then(function (data) {
|
||||||
alert("No video available for stream.");
|
if (!data) {
|
||||||
return;
|
alert("No video available for stream.");
|
||||||
}
|
return;
|
||||||
document.data = data
|
}
|
||||||
desertBusStart = new Date(data.bustime_start);
|
document.data = data;
|
||||||
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
|
desertBusStart = new Date(data.bustime_start);
|
||||||
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
|
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
|
||||||
|
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
|
||||||
document.getElementById("StreamName").value = data.video_channel;
|
|
||||||
document.getElementById("hiddenSubmissionID").value = data.id;
|
document.getElementById("StreamName").value = data.video_channel;
|
||||||
// for editor, switch to bustime since that's the default
|
document.getElementById("hiddenSubmissionID").value = data.id;
|
||||||
timeFormat = 'BUSTIME';
|
// for editor, switch to bustime since that's the default
|
||||||
// Apply padding - start 1min early, finish 2min late because these times are generally
|
timeFormat = "BUSTIME";
|
||||||
// rounded down to the minute, so if something ends at "00:10" it might actually end
|
// Apply padding - start 1min early, finish 2min late because these times are generally
|
||||||
// at 00:10:59 so we should pad to 00:12:00.
|
// rounded down to the minute, so if something ends at "00:10" it might actually end
|
||||||
var start = (data.event_start) ? new Date(fromTimestamp(data.event_start).getTime() - 60*1000) : null;
|
// at 00:10:59 so we should pad to 00:12:00.
|
||||||
var end = (data.event_end) ? new Date(fromTimestamp(data.event_end).getTime() + 2*60*1000) : null;
|
var start = data.event_start
|
||||||
setTimeRange(start, end);
|
? new Date(fromTimestamp(data.event_start).getTime() - 60 * 1000)
|
||||||
// title and description both default to row description
|
: null;
|
||||||
document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description;
|
var end = data.event_end
|
||||||
document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description;
|
? new Date(fromTimestamp(data.event_end).getTime() + 2 * 60 * 1000)
|
||||||
// tags default to tags from sheet
|
: null;
|
||||||
document.getElementById("VideoTags").value = tags_list_to_string(data.video_tags ? data.video_tags : data.tags);
|
setTimeRange(start, end);
|
||||||
|
// title and description both default to row description
|
||||||
// If any edit notes, show them
|
document.getElementById("VideoTitle").value = data.video_title
|
||||||
if (data.notes.length > 0) {
|
? data.video_title
|
||||||
document.getElementById("EditNotes").value = data.notes;
|
: data.description;
|
||||||
document.getElementById("EditNotesPane").style.display = "block";
|
document.getElementById("VideoDescription").value = data.video_description
|
||||||
}
|
? data.video_description
|
||||||
|
: data.description;
|
||||||
// Restore advanced options. If any of these are non-default, automatically expand the advanced options pane.
|
// tags default to tags from sheet
|
||||||
setOptions('uploadLocation', data.upload_locations, data.upload_location);
|
document.getElementById("VideoTags").value = tags_list_to_string(
|
||||||
document.getElementById("AllowHoles").checked = data.allow_holes;
|
data.video_tags ? data.video_tags : data.tags
|
||||||
document.getElementById("uploaderWhitelist").value = (!!data.uploader_whitelist) ? data.uploader_whitelist.join(",") : "";
|
);
|
||||||
if (
|
|
||||||
(
|
// If any edit notes, show them
|
||||||
data.upload_locations.length > 0
|
if (data.notes.length > 0) {
|
||||||
&& data.upload_location != null
|
document.getElementById("EditNotes").value = data.notes;
|
||||||
&& data.upload_location != data.upload_locations[0]
|
document.getElementById("EditNotesPane").style.display = "block";
|
||||||
)
|
}
|
||||||
|| data.allow_holes
|
|
||||||
|| !!data.uploader_whitelist
|
// Restore advanced options. If any of these are non-default, automatically expand the advanced options pane.
|
||||||
) {
|
setOptions("uploadLocation", data.upload_locations, data.upload_location);
|
||||||
document.getElementById('wubloaderAdvancedInputTable').style.display = "block";
|
document.getElementById("AllowHoles").checked = data.allow_holes;
|
||||||
}
|
document.getElementById("uploaderWhitelist").value = !!data.uploader_whitelist
|
||||||
|
? data.uploader_whitelist.join(",")
|
||||||
loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality);
|
: "";
|
||||||
});
|
if (
|
||||||
}
|
(data.upload_locations.length > 0 &&
|
||||||
else {
|
data.upload_location != null &&
|
||||||
if (isEditor) { document.getElementById('SubmitButton').disabled = true; }
|
data.upload_location != data.upload_locations[0]) ||
|
||||||
|
data.allow_holes ||
|
||||||
fetch("/thrimshim/defaults").then(data => data.json()).then(function (data) {
|
!!data.uploader_whitelist
|
||||||
if (!data) {
|
) {
|
||||||
alert("Editor results call failed, is thrimshim running?");
|
document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
desertBusStart = new Date(data.bustime_start);
|
loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality);
|
||||||
document.getElementById("StreamName").value = data.video_channel;
|
});
|
||||||
if (isEditor) {
|
} else {
|
||||||
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
|
if (isEditor) {
|
||||||
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
|
document.getElementById("SubmitButton").disabled = true;
|
||||||
setOptions('uploadLocation', data.upload_locations);
|
}
|
||||||
}
|
|
||||||
|
fetch("/thrimshim/defaults")
|
||||||
// Default time format changes depending on mode.
|
.then(data => data.json())
|
||||||
// But in both cases the default input value is 10min ago / "",
|
.then(function (data) {
|
||||||
// it's just for editor we convert it before the user sees.
|
if (!data) {
|
||||||
if (isEditor) {
|
alert("Editor results call failed, is thrimshim running?");
|
||||||
toggleTimeInput('BUSTIME');
|
return;
|
||||||
}
|
}
|
||||||
|
desertBusStart = new Date(data.bustime_start);
|
||||||
loadPlaylist(isEditor);
|
document.getElementById("StreamName").value = data.video_channel;
|
||||||
});
|
if (isEditor) {
|
||||||
|
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
|
||||||
}
|
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
|
||||||
|
setOptions("uploadLocation", data.upload_locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default time format changes depending on mode.
|
||||||
|
// But in both cases the default input value is 10min ago / "",
|
||||||
|
// it's just for editor we convert it before the user sees.
|
||||||
|
if (isEditor) {
|
||||||
|
toggleTimeInput("BUSTIME");
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPlaylist(isEditor);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Time-formatting functions
|
// Time-formatting functions
|
||||||
|
|
||||||
parseDuration = function(duration) {
|
parseDuration = function (duration) {
|
||||||
var direction = 1;
|
var direction = 1;
|
||||||
if(duration.startsWith("-")) {
|
if (duration.startsWith("-")) {
|
||||||
duration = duration.slice(1);
|
duration = duration.slice(1);
|
||||||
direction = -1;
|
direction = -1;
|
||||||
}
|
}
|
||||||
var parts = duration.split(':');
|
var parts = duration.split(":");
|
||||||
return (parseInt(parts[0]) + (parts[1] || "0")/60 + (parts[2] || "0")/3600) * 60 * 60 * direction;
|
return (
|
||||||
}
|
(parseInt(parts[0]) + (parts[1] || "0") / 60 + (parts[2] || "0") / 3600) * 60 * 60 * direction
|
||||||
|
);
|
||||||
toBustime = function(date) {
|
};
|
||||||
return (date < desertBusStart ? "-":"") + videojs.formatTime(Math.abs((date - desertBusStart)/1000), 600.01).padStart(7, "0:");
|
|
||||||
|
toBustime = function (date) {
|
||||||
|
return (
|
||||||
|
(date < desertBusStart ? "-" : "") +
|
||||||
|
videojs.formatTime(Math.abs((date - desertBusStart) / 1000), 600.01).padStart(7, "0:")
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
fromBustime = function(bustime) {
|
fromBustime = function (bustime) {
|
||||||
return new Date(desertBusStart.getTime() + 1000 * parseDuration(bustime));
|
return new Date(desertBusStart.getTime() + 1000 * parseDuration(bustime));
|
||||||
};
|
};
|
||||||
|
|
||||||
toTimestamp = function(date) {
|
toTimestamp = function (date) {
|
||||||
return date.toISOString().substring(0, 19);
|
return date.toISOString().substring(0, 19);
|
||||||
}
|
};
|
||||||
|
|
||||||
fromTimestamp = function(ts) {
|
fromTimestamp = function (ts) {
|
||||||
return new Date(ts + "Z");
|
return new Date(ts + "Z");
|
||||||
}
|
};
|
||||||
|
|
||||||
toAgo = function(date) {
|
toAgo = function (date) {
|
||||||
now = new Date()
|
now = new Date();
|
||||||
return (date < now ? "":"-") + videojs.formatTime(Math.abs((date - now)/1000), 600.01).padStart(7, "0:");
|
return (
|
||||||
}
|
(date < now ? "" : "-") +
|
||||||
|
videojs.formatTime(Math.abs((date - now) / 1000), 600.01).padStart(7, "0:")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
fromAgo = function(ago) {
|
fromAgo = function (ago) {
|
||||||
return new Date(new Date().getTime() - 1000 * parseDuration(ago));
|
return new Date(new Date().getTime() - 1000 * parseDuration(ago));
|
||||||
}
|
};
|
||||||
|
|
||||||
// Set the stream start/end range from a pair of Dates using the current format
|
// Set the stream start/end range from a pair of Dates using the current format
|
||||||
// If given null, sets to blank.
|
// If given null, sets to blank.
|
||||||
setTimeRange = function(start, end) {
|
setTimeRange = function (start, end) {
|
||||||
var toFunc = {
|
var toFunc = {
|
||||||
UTC: toTimestamp,
|
UTC: toTimestamp,
|
||||||
BUSTIME: toBustime,
|
BUSTIME: toBustime,
|
||||||
AGO: toAgo,
|
AGO: toAgo,
|
||||||
}[timeFormat];
|
}[timeFormat];
|
||||||
document.getElementById("StreamStart").value = (start) ? toFunc(start) : "";
|
document.getElementById("StreamStart").value = start ? toFunc(start) : "";
|
||||||
document.getElementById("StreamEnd").value = (end) ? toFunc(end) : "";
|
document.getElementById("StreamEnd").value = end ? toFunc(end) : "";
|
||||||
}
|
};
|
||||||
|
|
||||||
// Get the current start/end range as Dates using the current format
|
// Get the current start/end range as Dates using the current format
|
||||||
// Returns an object containing 'start' and 'end' fields.
|
// Returns an object containing 'start' and 'end' fields.
|
||||||
// If either is empty / invalid, returns null.
|
// If either is empty / invalid, returns null.
|
||||||
getTimeRange = function() {
|
getTimeRange = function () {
|
||||||
var fromFunc = {
|
var fromFunc = {
|
||||||
UTC: fromTimestamp,
|
UTC: fromTimestamp,
|
||||||
BUSTIME: fromBustime,
|
BUSTIME: fromBustime,
|
||||||
AGO: fromAgo,
|
AGO: fromAgo,
|
||||||
}[timeFormat];
|
}[timeFormat];
|
||||||
var convert = function(value) {
|
var convert = function (value) {
|
||||||
if (!value) { return null; }
|
if (!value) {
|
||||||
var date = fromFunc(value);
|
return null;
|
||||||
return (isNaN(date)) ? null : date;
|
}
|
||||||
};
|
var date = fromFunc(value);
|
||||||
return {
|
return isNaN(date) ? null : date;
|
||||||
start: convert(document.getElementById("StreamStart").value),
|
};
|
||||||
end: convert(document.getElementById("StreamEnd").value),
|
return {
|
||||||
};
|
start: convert(document.getElementById("StreamStart").value),
|
||||||
}
|
end: convert(document.getElementById("StreamEnd").value),
|
||||||
|
};
|
||||||
getTimeRangeAsTimestamp = function() {
|
};
|
||||||
var range = getTimeRange();
|
|
||||||
return {
|
getTimeRangeAsTimestamp = function () {
|
||||||
// if not null, format as timestamp
|
var range = getTimeRange();
|
||||||
start: range.start && toTimestamp(range.start),
|
return {
|
||||||
end: range.end && toTimestamp(range.end),
|
// if not null, format as timestamp
|
||||||
};
|
start: range.start && toTimestamp(range.start),
|
||||||
}
|
end: range.end && toTimestamp(range.end),
|
||||||
|
};
|
||||||
toggleHiddenPane = function(paneID) {
|
};
|
||||||
var pane = document.getElementById(paneID);
|
|
||||||
pane.style.display = (pane.style.display === "none") ? "block":"none";
|
toggleHiddenPane = function (paneID) {
|
||||||
}
|
var pane = document.getElementById(paneID);
|
||||||
|
pane.style.display = pane.style.display === "none" ? "block" : "none";
|
||||||
toggleUltrawide = function() {
|
};
|
||||||
var body = document.getElementsByTagName("Body")[0];
|
|
||||||
body.classList.contains("ultrawide") ? body.classList.remove("ultrawide"):body.classList.add("ultrawide");
|
toggleUltrawide = function () {
|
||||||
}
|
var body = document.getElementsByTagName("Body")[0];
|
||||||
|
body.classList.contains("ultrawide")
|
||||||
toggleTimeInput = function(toggleInput) {
|
? body.classList.remove("ultrawide")
|
||||||
// Get times using current format, then change format, then write them back
|
: body.classList.add("ultrawide");
|
||||||
var range = getTimeRange();
|
};
|
||||||
timeFormat = toggleInput;
|
|
||||||
setTimeRange(range.start, range.end);
|
toggleTimeInput = function (toggleInput) {
|
||||||
}
|
// Get times using current format, then change format, then write them back
|
||||||
|
var range = getTimeRange();
|
||||||
|
timeFormat = toggleInput;
|
||||||
|
setTimeRange(range.start, range.end);
|
||||||
|
};
|
||||||
|
|
||||||
// For a given select input element id, add the given list of options.
|
// For a given select input element id, add the given list of options.
|
||||||
// If selected is given, it should be the name of an option to select.
|
// If selected is given, it should be the name of an option to select.
|
||||||
// Otherwise the first one is used.
|
// Otherwise the first one is used.
|
||||||
setOptions = function(element, options, selected) {
|
setOptions = function (element, options, selected) {
|
||||||
if (!selected && options.length > 0) {
|
if (!selected && options.length > 0) {
|
||||||
selected = options[0]
|
selected = options[0];
|
||||||
}
|
}
|
||||||
options.forEach(function(option) {
|
options.forEach(function (option) {
|
||||||
document.getElementById(element).innerHTML += '<option value="'+option+'" '+(option==selected ? 'selected':'')+'>'+option+'</option>';
|
document.getElementById(element).innerHTML +=
|
||||||
});
|
'<option value="' +
|
||||||
}
|
option +
|
||||||
|
'" ' +
|
||||||
buildQuery = function(params) {
|
(option == selected ? "selected" : "") +
|
||||||
return Object.keys(params).filter(key => params[key] !== null).map(key =>
|
">" +
|
||||||
encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
|
option +
|
||||||
).join('&');
|
"</option>";
|
||||||
}
|
});
|
||||||
|
};
|
||||||
loadPlaylist = function(isEditor, startTrim, endTrim, defaultQuality) {
|
|
||||||
var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8";
|
buildQuery = function (params) {
|
||||||
|
return Object.keys(params)
|
||||||
var range = getTimeRangeAsTimestamp();
|
.filter(key => params[key] !== null)
|
||||||
var queryString = buildQuery(range);
|
.map(key => encodeURIComponent(key) + "=" + encodeURIComponent(params[key]))
|
||||||
|
.join("&");
|
||||||
|
};
|
||||||
|
|
||||||
|
loadPlaylist = function (isEditor, startTrim, endTrim, defaultQuality) {
|
||||||
|
var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8";
|
||||||
|
|
||||||
|
var range = getTimeRangeAsTimestamp();
|
||||||
|
var queryString = buildQuery(range);
|
||||||
|
|
||||||
// Preserve existing edit times
|
// Preserve existing edit times
|
||||||
if (player && player.trimmingControls && player.vhs.playlists.master) {
|
if (player && player.trimmingControls && player.vhs.playlists.master) {
|
||||||
var discontinuities = mapDiscontinuities();
|
var discontinuities = mapDiscontinuities();
|
||||||
if (!startTrim) {
|
if (!startTrim) {
|
||||||
startTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
|
startTrim = getRealTimeForPlayerTime(
|
||||||
if (startTrim) {startTrim = startTrim.replace('Z','');}
|
discontinuities,
|
||||||
|
player.trimmingControls().options.startTrim
|
||||||
|
);
|
||||||
|
if (startTrim) {
|
||||||
|
startTrim = startTrim.replace("Z", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!endTrim) {
|
if (!endTrim) {
|
||||||
endTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
|
endTrim = getRealTimeForPlayerTime(
|
||||||
if (endTrim) {endTrim = endTrim.replace('Z','');}
|
discontinuities,
|
||||||
|
player.trimmingControls().options.endTrim
|
||||||
|
);
|
||||||
|
if (endTrim) {
|
||||||
|
endTrim = endTrim.replace("Z", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupPlayer(isEditor, playlist + '?' + queryString, startTrim, endTrim);
|
setupPlayer(isEditor, playlist + "?" + queryString, startTrim, endTrim);
|
||||||
|
|
||||||
//Get quality levels for advanced properties / download
|
//Get quality levels for advanced properties / download
|
||||||
document.getElementById('qualityLevel').innerHTML = "";
|
document.getElementById("qualityLevel").innerHTML = "";
|
||||||
fetch('/files/' + document.getElementById('StreamName').value).then(data => data.json()).then(function (data) {
|
fetch("/files/" + document.getElementById("StreamName").value)
|
||||||
if (!data.length) {
|
.then(data => data.json())
|
||||||
console.log("Could not retrieve quality levels");
|
.then(function (data) {
|
||||||
return;
|
if (!data.length) {
|
||||||
}
|
console.log("Could not retrieve quality levels");
|
||||||
var qualityLevels = data.sort().reverse();
|
return;
|
||||||
setOptions('qualityLevel', qualityLevels, defaultQuality);
|
}
|
||||||
if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) {
|
var qualityLevels = data.sort().reverse();
|
||||||
document.getElementById('wubloaderAdvancedInputTable').style.display = "block";
|
setOptions("qualityLevel", qualityLevels, defaultQuality);
|
||||||
}
|
if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) {
|
||||||
});
|
document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
thrimbletrimmerSubmit = function(state, override_changes=false) {
|
thrimbletrimmerSubmit = function (state, override_changes = false) {
|
||||||
document.getElementById('SubmitButton').disabled = true;
|
document.getElementById("SubmitButton").disabled = true;
|
||||||
var discontinuities = mapDiscontinuities();
|
var discontinuities = mapDiscontinuities();
|
||||||
|
|
||||||
var start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
|
var start = getRealTimeForPlayerTime(
|
||||||
if (start) {start = start.replace('Z','');}
|
discontinuities,
|
||||||
|
player.trimmingControls().options.startTrim
|
||||||
|
);
|
||||||
|
if (start) {
|
||||||
|
start = start.replace("Z", "");
|
||||||
|
}
|
||||||
var end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
|
var end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
|
||||||
if (end) {end = end.replace('Z','');}
|
if (end) {
|
||||||
|
end = end.replace("Z", "");
|
||||||
var wubData = {
|
}
|
||||||
video_start:start,
|
|
||||||
video_end:end,
|
var wubData = {
|
||||||
video_title:document.getElementById("VideoTitle").value,
|
video_start: start,
|
||||||
video_description:document.getElementById("VideoDescription").value,
|
video_end: end,
|
||||||
video_tags:tags_string_to_list(document.getElementById("VideoTags").value),
|
video_title: document.getElementById("VideoTitle").value,
|
||||||
allow_holes:document.getElementById('AllowHoles').checked,
|
video_description: document.getElementById("VideoDescription").value,
|
||||||
upload_location:document.getElementById('uploadLocation').value,
|
video_tags: tags_string_to_list(document.getElementById("VideoTags").value),
|
||||||
video_channel:document.getElementById("StreamName").value,
|
allow_holes: document.getElementById("AllowHoles").checked,
|
||||||
video_quality:document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value,
|
upload_location: document.getElementById("uploadLocation").value,
|
||||||
uploader_whitelist:(document.getElementById('uploaderWhitelist').value ? document.getElementById('uploaderWhitelist').value.split(','):null),
|
video_channel: document.getElementById("StreamName").value,
|
||||||
state:state,
|
video_quality:
|
||||||
|
document.getElementById("qualityLevel").options[
|
||||||
|
document.getElementById("qualityLevel").options.selectedIndex
|
||||||
|
].value,
|
||||||
|
uploader_whitelist: document.getElementById("uploaderWhitelist").value
|
||||||
|
? document.getElementById("uploaderWhitelist").value.split(",")
|
||||||
|
: null,
|
||||||
|
state: state,
|
||||||
//pass back the sheet columns to check if any have changed
|
//pass back the sheet columns to check if any have changed
|
||||||
sheet_name:document.data.sheet_name,
|
sheet_name: document.data.sheet_name,
|
||||||
event_start:document.data.event_start,
|
event_start: document.data.event_start,
|
||||||
event_end:document.data.event_end,
|
event_end: document.data.event_end,
|
||||||
category:document.data.category,
|
category: document.data.category,
|
||||||
description:document.data.description,
|
description: document.data.description,
|
||||||
notes:document.data.notes,
|
notes: document.data.notes,
|
||||||
tags:document.data.tags,
|
tags: document.data.tags,
|
||||||
};
|
};
|
||||||
if (!!user) {
|
if (!!user) {
|
||||||
wubData.token = user.getAuthResponse().id_token
|
wubData.token = user.getAuthResponse().id_token;
|
||||||
}
|
}
|
||||||
if (override_changes) {
|
if (override_changes) {
|
||||||
wubData["override_changes"] = true;
|
wubData["override_changes"] = true;
|
||||||
}
|
}
|
||||||
console.log(wubData);
|
console.log(wubData);
|
||||||
console.log(JSON.stringify(wubData));
|
console.log(JSON.stringify(wubData));
|
||||||
|
|
||||||
if (!wubData.video_start) {alert("No start time set"); return;}
|
if (!wubData.video_start) {
|
||||||
if (!wubData.video_end) {alert("No end time set"); return;}
|
alert("No start time set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!wubData.video_end) {
|
||||||
|
alert("No end time set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Submit to thrimshim
|
//Submit to thrimshim
|
||||||
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
||||||
fetch("/thrimshim/" + rowId, {
|
fetch("/thrimshim/" + rowId, {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
Accept: "application/json",
|
||||||
'Content-Type': 'application/json'
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(wubData)
|
body: JSON.stringify(wubData),
|
||||||
})
|
}).then(response =>
|
||||||
.then(response => response.text().then(text => {
|
response.text().then(text => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
var error = response.statusText + ": " + text;
|
var error = response.statusText + ": " + text;
|
||||||
if (response.status == 409) {
|
if (response.status == 409) {
|
||||||
dialogue = text + "\nClick Ok to submit anyway; Click Cancel to return to editing"
|
dialogue = text + "\nClick Ok to submit anyway; Click Cancel to return to editing";
|
||||||
if (confirm(dialogue)) {
|
if (confirm(dialogue)) {
|
||||||
thrimbletrimmerSubmit(state, true);
|
thrimbletrimmerSubmit(state, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert(error);
|
alert(error);
|
||||||
}
|
}
|
||||||
} else if (state == 'EDITED') {
|
} else if (state == "EDITED") {
|
||||||
alert(`Edit submitted for video from ${start} to ${end}`)
|
alert(`Edit submitted for video from ${start} to ${end}`);
|
||||||
} else {
|
} else {
|
||||||
alert("Draft saved");
|
alert("Draft saved");
|
||||||
}
|
}
|
||||||
document.getElementById('SubmitButton').disabled = false;
|
document.getElementById("SubmitButton").disabled = false;
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
thrimbletrimmerDownload = function(isEditor) {
|
thrimbletrimmerDownload = function (isEditor) {
|
||||||
var range = getTimeRangeAsTimestamp();
|
var range = getTimeRangeAsTimestamp();
|
||||||
if (isEditor) {
|
if (isEditor) {
|
||||||
if(player.trimmingControls().options.startTrim >= player.trimmingControls().options.endTrim) {
|
if (player.trimmingControls().options.startTrim >= player.trimmingControls().options.endTrim) {
|
||||||
alert("End Time must be greater than Start Time");
|
alert("End Time must be greater than Start Time");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var discontinuities = mapDiscontinuities();
|
var discontinuities = mapDiscontinuities();
|
||||||
range.start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
|
range.start = getRealTimeForPlayerTime(
|
||||||
range.end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
|
discontinuities,
|
||||||
}
|
player.trimmingControls().options.startTrim
|
||||||
|
);
|
||||||
var targetURL = "/cut/" + document.getElementById("StreamName").value +
|
range.end = getRealTimeForPlayerTime(
|
||||||
"/"+document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value+".ts" +
|
discontinuities,
|
||||||
"?" + buildQuery({
|
player.trimmingControls().options.endTrim
|
||||||
start: range.start,
|
);
|
||||||
end: range.end,
|
}
|
||||||
|
|
||||||
|
var targetURL =
|
||||||
|
"/cut/" +
|
||||||
|
document.getElementById("StreamName").value +
|
||||||
|
"/" +
|
||||||
|
document.getElementById("qualityLevel").options[
|
||||||
|
document.getElementById("qualityLevel").options.selectedIndex
|
||||||
|
].value +
|
||||||
|
".ts" +
|
||||||
|
"?" +
|
||||||
|
buildQuery({
|
||||||
|
start: range.start,
|
||||||
|
end: range.end,
|
||||||
// In non-editor, always use rough cut. They don't have the edit controls to do
|
// In non-editor, always use rough cut. They don't have the edit controls to do
|
||||||
// fine time selection anyway.
|
// fine time selection anyway.
|
||||||
type: (isEditor) ? (
|
type: isEditor
|
||||||
document.getElementById('DownloadType').options[document.getElementById('DownloadType').options.selectedIndex].value
|
? document.getElementById("DownloadType").options[
|
||||||
) : "rough",
|
document.getElementById("DownloadType").options.selectedIndex
|
||||||
// Always allow holes in non-editor, accidentially including holes isn't important
|
].value
|
||||||
allow_holes: (isEditor) ? String(document.getElementById('AllowHoles').checked) : "true",
|
: "rough",
|
||||||
});
|
// Always allow holes in non-editor, accidentially including holes isn't important
|
||||||
console.log(targetURL);
|
allow_holes: isEditor ? String(document.getElementById("AllowHoles").checked) : "true",
|
||||||
document.getElementById('DownloadLink').href = targetURL;
|
});
|
||||||
document.getElementById('DownloadLink').style.display = "";
|
console.log(targetURL);
|
||||||
|
document.getElementById("DownloadLink").href = targetURL;
|
||||||
|
document.getElementById("DownloadLink").style.display = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
thrimbletrimmerManualLink = function() {
|
thrimbletrimmerManualLink = function () {
|
||||||
document.getElementById("ManualButton").disabled = true;
|
document.getElementById("ManualButton").disabled = true;
|
||||||
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
||||||
var upload_location = (document.getElementById("ManualYoutube").checked) ? "youtube-manual" : "manual";
|
var upload_location = document.getElementById("ManualYoutube").checked
|
||||||
var body = {link: document.getElementById("ManualLink").value, upload_location: upload_location};
|
? "youtube-manual"
|
||||||
if (!!user) {
|
: "manual";
|
||||||
body.token = user.getAuthResponse().id_token;
|
var body = {
|
||||||
}
|
link: document.getElementById("ManualLink").value,
|
||||||
fetch("/thrimshim/manual-link/"+rowId, {
|
upload_location: upload_location,
|
||||||
method: 'POST',
|
};
|
||||||
headers: {
|
if (!!user) {
|
||||||
'Accept': 'application/json',
|
body.token = user.getAuthResponse().id_token;
|
||||||
'Content-Type': 'application/json'
|
}
|
||||||
},
|
fetch("/thrimshim/manual-link/" + rowId, {
|
||||||
body: JSON.stringify(body)
|
method: "POST",
|
||||||
})
|
headers: {
|
||||||
.then(response => response.text().then(text => {
|
Accept: "application/json",
|
||||||
if (!response.ok) {
|
"Content-Type": "application/json",
|
||||||
var error = response.statusText + ": " + text;
|
},
|
||||||
console.log(error);
|
body: JSON.stringify(body),
|
||||||
alert(error);
|
}).then(response =>
|
||||||
document.getElementById("ManualButton").disabled = false;
|
response.text().then(text => {
|
||||||
} else {
|
if (!response.ok) {
|
||||||
alert("Manual link set to " + body.link);
|
var error = response.statusText + ": " + text;
|
||||||
setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500);
|
console.log(error);
|
||||||
}
|
alert(error);
|
||||||
}));
|
document.getElementById("ManualButton").disabled = false;
|
||||||
|
} else {
|
||||||
|
alert("Manual link set to " + body.link);
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "/thrimbletrimmer/dashboard.html";
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
thrimbletrimmerResetLink = function(force) {
|
thrimbletrimmerResetLink = function (force) {
|
||||||
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
|
||||||
if(force && !confirm(
|
if (
|
||||||
'Are you sure you want to reset this event? ' +
|
force &&
|
||||||
'This will set the row back to UNEDITED and forget about any video that already may exist. ' +
|
!confirm(
|
||||||
'It is intended as a last-ditch command to clear a malfunctioning cutter, ' +
|
"Are you sure you want to reset this event? " +
|
||||||
'or if a video needs to be re-edited and replaced. ' +
|
"This will set the row back to UNEDITED and forget about any video that already may exist. " +
|
||||||
'IT IS YOUR RESPONSIBILITY TO DEAL WITH ANY VIDEO THAT MAY HAVE ALREADY BEEN UPLOADED. '
|
"It is intended as a last-ditch command to clear a malfunctioning cutter, " +
|
||||||
)) {
|
"or if a video needs to be re-edited and replaced. " +
|
||||||
return;
|
"IT IS YOUR RESPONSIBILITY TO DEAL WITH ANY VIDEO THAT MAY HAVE ALREADY BEEN UPLOADED. "
|
||||||
}
|
)
|
||||||
document.getElementById("ResetButton").disabled = true;
|
) {
|
||||||
document.getElementById("CancelButton").disabled = true;
|
return;
|
||||||
var body = {}
|
}
|
||||||
if (!!user) {
|
document.getElementById("ResetButton").disabled = true;
|
||||||
body.token = user.getAuthResponse().id_token;
|
document.getElementById("CancelButton").disabled = true;
|
||||||
}
|
var body = {};
|
||||||
fetch("/thrimshim/reset/"+rowId + "?force=" + force, {
|
if (!!user) {
|
||||||
method: 'POST',
|
body.token = user.getAuthResponse().id_token;
|
||||||
headers: {
|
}
|
||||||
'Accept': 'application/json',
|
fetch("/thrimshim/reset/" + rowId + "?force=" + force, {
|
||||||
'Content-Type': 'application/json'
|
method: "POST",
|
||||||
},
|
headers: {
|
||||||
body: JSON.stringify(body)
|
Accept: "application/json",
|
||||||
})
|
"Content-Type": "application/json",
|
||||||
.then(response => response.text().then(text => {
|
},
|
||||||
if (!response.ok) {
|
body: JSON.stringify(body),
|
||||||
var error = response.statusText + ": " + text;
|
}).then(response =>
|
||||||
console.log(error);
|
response.text().then(text => {
|
||||||
alert(error);
|
if (!response.ok) {
|
||||||
document.getElementById("ResetButton").disabled = false;
|
var error = response.statusText + ": " + text;
|
||||||
document.getElementById("CancelButton").disabled = true;
|
console.log(error);
|
||||||
} else {
|
alert(error);
|
||||||
alert("Row has been " + ((force) ? "reset" : "cancelled") +". Reloading...");
|
document.getElementById("ResetButton").disabled = false;
|
||||||
setTimeout(() => { window.location.reload(); }, 500);
|
document.getElementById("CancelButton").disabled = true;
|
||||||
}
|
} else {
|
||||||
}));
|
alert("Row has been " + (force ? "reset" : "cancelled") + ". Reloading...");
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
tags_list_to_string = function(tag_list) {
|
tags_list_to_string = function (tag_list) {
|
||||||
return tag_list.join(", ");
|
return tag_list.join(", ");
|
||||||
}
|
};
|
||||||
|
|
||||||
tags_string_to_list = function(tag_string) {
|
tags_string_to_list = function (tag_string) {
|
||||||
return tag_string.split(",").map(tag => tag.trim()).filter(tag => tag.length > 0);
|
return tag_string
|
||||||
}
|
.split(",")
|
||||||
|
.map(tag => tag.trim())
|
||||||
|
.filter(tag => tag.length > 0);
|
||||||
|
};
|
||||||
|
|
||||||
round_trip_tag_string = function() {
|
round_trip_tag_string = function () {
|
||||||
var element = document.getElementById("VideoTags");
|
var element = document.getElementById("VideoTags");
|
||||||
element.value = tags_list_to_string(
|
element.value = tags_list_to_string(tags_string_to_list(element.value));
|
||||||
tags_string_to_list(
|
};
|
||||||
element.value
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -1,98 +1,115 @@
|
|||||||
var player = null;
|
var player = null;
|
||||||
|
|
||||||
function setupPlayer(isEditor, source, startTrim, endTrim) {
|
function setupPlayer(isEditor, source, startTrim, endTrim) {
|
||||||
document.getElementById("my-player").style.display = "";
|
document.getElementById("my-player").style.display = "";
|
||||||
//Make poster of DB logo in correct aspect ratio, to control initial size of fluid container.
|
//Make poster of DB logo in correct aspect ratio, to control initial size of fluid container.
|
||||||
var options = {
|
var options = {
|
||||||
sources: [{ src: source }],
|
sources: [{src: source}],
|
||||||
liveui: true,
|
liveui: true,
|
||||||
//fluid:true,
|
//fluid:true,
|
||||||
controls:true,
|
controls: true,
|
||||||
autoplay:false,
|
autoplay: false,
|
||||||
width:1280,
|
width: 1280,
|
||||||
height:420,
|
height: 420,
|
||||||
playbackRates: [0.5, 1, 1.25, 1.5, 2],
|
playbackRates: [0.5, 1, 1.25, 1.5, 2],
|
||||||
inactivityTimeout: 0,
|
inactivityTimeout: 0,
|
||||||
controlBar: {
|
controlBar: {
|
||||||
fullscreenToggle: true,
|
fullscreenToggle: true,
|
||||||
volumePanel: {
|
volumePanel: {
|
||||||
inline: false
|
inline: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
if(player) { //Destroy and recreate the player if it already exists.
|
if (player) {
|
||||||
player.dispose();
|
//Destroy and recreate the player if it already exists.
|
||||||
document.getElementById("EditorContainer").innerHTML = `
|
player.dispose();
|
||||||
|
document.getElementById("EditorContainer").innerHTML = `
|
||||||
<video id="my-player" class="video-js" controls disablePictureInPicture preload="auto">
|
<video id="my-player" class="video-js" controls disablePictureInPicture preload="auto">
|
||||||
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
||||||
</video>
|
</video>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
player = videojs('my-player', options, function onPlayerReady() {
|
player = videojs("my-player", options, function onPlayerReady() {
|
||||||
videojs.log('Your player is ready!');
|
videojs.log("Your player is ready!");
|
||||||
|
|
||||||
// Set player volume to 50% by default
|
// Set player volume to 50% by default
|
||||||
var defaultVolume = 0.5;
|
var defaultVolume = 0.5;
|
||||||
this.volume(defaultVolume);
|
this.volume(defaultVolume);
|
||||||
|
|
||||||
// In this context, `this` is the player that was created by Video.js.
|
// In this context, `this` is the player that was created by Video.js.
|
||||||
this.on('ready', function() {
|
this.on("ready", function () {
|
||||||
//this.play();
|
//this.play();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.vhs.playlists.on('loadedmetadata', function() {
|
this.vhs.playlists.on("loadedmetadata", function () {
|
||||||
// setTimeout(function() { player.play(); }, 1000);
|
// setTimeout(function() { player.play(); }, 1000);
|
||||||
player.hasStarted(true); //So it displays all the controls.
|
player.hasStarted(true); //So it displays all the controls.
|
||||||
if (isEditor) {
|
if (isEditor) {
|
||||||
var stream_start = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.discontinuityStarts !== "undefined")[0].dateTimeObject;
|
var stream_start = player.vhs.playlists.master.playlists.filter(
|
||||||
startTrim = startTrim ? (new Date(startTrim+"Z")-stream_start)/1000:0;
|
playlist => typeof playlist.discontinuityStarts !== "undefined"
|
||||||
endTrim = endTrim ? (new Date(endTrim+"Z")-stream_start)/1000:player.duration();
|
)[0].dateTimeObject;
|
||||||
var trimmingControls = player.trimmingControls({ startTrim:startTrim, endTrim:endTrim });
|
startTrim = startTrim ? (new Date(startTrim + "Z") - stream_start) / 1000 : 0;
|
||||||
}
|
endTrim = endTrim ? (new Date(endTrim + "Z") - stream_start) / 1000 : player.duration();
|
||||||
});
|
var trimmingControls = player.trimmingControls({startTrim: startTrim, endTrim: endTrim});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// How about an event listener?
|
// How about an event listener?
|
||||||
this.on('ended', function() {
|
this.on("ended", function () {
|
||||||
videojs.log('Awww...over so soon?!');
|
videojs.log("Awww...over so soon?!");
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('error', function() {
|
this.on("error", function () {
|
||||||
videojs.log("Could not load video stream");
|
videojs.log("Could not load video stream");
|
||||||
alert("No video available for stream.");
|
alert("No video available for stream.");
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
var hlsQS = player.hlsQualitySelector();
|
var hlsQS = player.hlsQualitySelector();
|
||||||
}
|
}
|
||||||
|
|
||||||
mapDiscontinuities = function() {
|
mapDiscontinuities = function () {
|
||||||
var playlist = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.discontinuityStarts !== "undefined")[0]; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one.
|
var playlist = player.vhs.playlists.master.playlists.filter(
|
||||||
var discontinuities = playlist.discontinuityStarts.map(segmentIndex => { return {segmentIndex:segmentIndex, segmentTimestamp:playlist.segments[segmentIndex].dateTimeObject, playbackIndex:null}; });
|
playlist => typeof playlist.discontinuityStarts !== "undefined"
|
||||||
//var lastDiscontinuity = Math.max(...playlist.discontinuityStarts);
|
)[0]; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one.
|
||||||
var lastDiscontinuity = playlist.discontinuityStarts.slice(-1).pop(); //Assumes discontinuities are sorted in ascending order.
|
var discontinuities = playlist.discontinuityStarts.map(segmentIndex => {
|
||||||
|
return {
|
||||||
|
segmentIndex: segmentIndex,
|
||||||
|
segmentTimestamp: playlist.segments[segmentIndex].dateTimeObject,
|
||||||
|
playbackIndex: null,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
//var lastDiscontinuity = Math.max(...playlist.discontinuityStarts);
|
||||||
|
var lastDiscontinuity = playlist.discontinuityStarts.slice(-1).pop(); //Assumes discontinuities are sorted in ascending order.
|
||||||
|
|
||||||
var durationMarker = 0;
|
var durationMarker = 0;
|
||||||
for (var index = 0; index <= lastDiscontinuity; index++) {
|
for (var index = 0; index <= lastDiscontinuity; index++) {
|
||||||
let segment = playlist.segments[index];
|
let segment = playlist.segments[index];
|
||||||
if(segment.discontinuity) {
|
if (segment.discontinuity) {
|
||||||
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex = durationMarker;
|
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex =
|
||||||
}
|
durationMarker;
|
||||||
durationMarker += segment.duration;
|
}
|
||||||
}
|
durationMarker += segment.duration;
|
||||||
|
}
|
||||||
|
|
||||||
return discontinuities;
|
return discontinuities;
|
||||||
};
|
};
|
||||||
|
|
||||||
getRealTimeForPlayerTime = function(discontinuities, playbackIndex) {
|
getRealTimeForPlayerTime = function (discontinuities, playbackIndex) {
|
||||||
var streamStart = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.dateTimeObject !== "undefined")[0].dateTimeObject; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one.
|
var streamStart = player.vhs.playlists.master.playlists.filter(
|
||||||
|
playlist => typeof playlist.dateTimeObject !== "undefined"
|
||||||
|
)[0].dateTimeObject; //Only one of the playlists will have the discontinuity or stream start objects, and it's not necessarily the first one or the source one.
|
||||||
|
|
||||||
//Find last discontinuity before playbackIndex
|
//Find last discontinuity before playbackIndex
|
||||||
var lastDiscontinuity = discontinuities.filter(discontinuity => discontinuity.playbackIndex < playbackIndex).slice(-1).pop();
|
var lastDiscontinuity = discontinuities
|
||||||
if(lastDiscontinuity) {
|
.filter(discontinuity => discontinuity.playbackIndex < playbackIndex)
|
||||||
streamStart = lastDiscontinuity.segmentTimestamp;
|
.slice(-1)
|
||||||
playbackIndex -= lastDiscontinuity.playbackIndex;
|
.pop();
|
||||||
}
|
if (lastDiscontinuity) {
|
||||||
|
streamStart = lastDiscontinuity.segmentTimestamp;
|
||||||
|
playbackIndex -= lastDiscontinuity.playbackIndex;
|
||||||
|
}
|
||||||
|
|
||||||
var realTime = streamStart.getTime()+playbackIndex*1000;
|
var realTime = streamStart.getTime() + playbackIndex * 1000;
|
||||||
|
|
||||||
return (isFinite(realTime)) ? new Date(realTime).toISOString() : null;
|
return isFinite(realTime) ? new Date(realTime).toISOString() : null;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue