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
Mike Lang 3 years ago committed by Mike Lang
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,17 +1,18 @@
var desertBusStart = new Date("1970-01-01T00:00:00Z");
var timeFormat = 'AGO';
pageSetup = function(isEditor) {
var timeFormat = "AGO";
pageSetup = function (isEditor) {
//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];
fetch("/thrimshim/"+rowId).then(data => data.json()).then(function (data) {
fetch("/thrimshim/" + rowId)
.then(data => data.json())
.then(function (data) {
if (!data) {
alert("No video available for stream.");
return;
}
document.data = data
document.data = data;
desertBusStart = new Date(data.bustime_start);
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
@ -19,18 +20,28 @@ pageSetup = function(isEditor) {
document.getElementById("StreamName").value = data.video_channel;
document.getElementById("hiddenSubmissionID").value = data.id;
// for editor, switch to bustime since that's the default
timeFormat = 'BUSTIME';
timeFormat = "BUSTIME";
// Apply padding - start 1min early, finish 2min late because these times are generally
// rounded down to the minute, so if something ends at "00:10" it might actually end
// at 00:10:59 so we should pad to 00:12:00.
var start = (data.event_start) ? new Date(fromTimestamp(data.event_start).getTime() - 60*1000) : null;
var end = (data.event_end) ? new Date(fromTimestamp(data.event_end).getTime() + 2*60*1000) : null;
var start = data.event_start
? new Date(fromTimestamp(data.event_start).getTime() - 60 * 1000)
: null;
var end = data.event_end
? new Date(fromTimestamp(data.event_end).getTime() + 2 * 60 * 1000)
: null;
setTimeRange(start, end);
// title and description both default to row description
document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description;
document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description;
document.getElementById("VideoTitle").value = data.video_title
? data.video_title
: data.description;
document.getElementById("VideoDescription").value = data.video_description
? data.video_description
: data.description;
// tags default to tags from sheet
document.getElementById("VideoTags").value = tags_list_to_string(data.video_tags ? data.video_tags : data.tags);
document.getElementById("VideoTags").value = tags_list_to_string(
data.video_tags ? data.video_tags : data.tags
);
// If any edit notes, show them
if (data.notes.length > 0) {
@ -39,28 +50,31 @@ pageSetup = function(isEditor) {
}
// Restore advanced options. If any of these are non-default, automatically expand the advanced options pane.
setOptions('uploadLocation', data.upload_locations, data.upload_location);
setOptions("uploadLocation", data.upload_locations, data.upload_location);
document.getElementById("AllowHoles").checked = data.allow_holes;
document.getElementById("uploaderWhitelist").value = (!!data.uploader_whitelist) ? data.uploader_whitelist.join(",") : "";
document.getElementById("uploaderWhitelist").value = !!data.uploader_whitelist
? data.uploader_whitelist.join(",")
: "";
if (
(
data.upload_locations.length > 0
&& data.upload_location != null
&& data.upload_location != data.upload_locations[0]
)
|| data.allow_holes
|| !!data.uploader_whitelist
(data.upload_locations.length > 0 &&
data.upload_location != null &&
data.upload_location != data.upload_locations[0]) ||
data.allow_holes ||
!!data.uploader_whitelist
) {
document.getElementById('wubloaderAdvancedInputTable').style.display = "block";
document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
}
loadPlaylist(isEditor, data.video_start, data.video_end, data.video_quality);
});
} else {
if (isEditor) {
document.getElementById("SubmitButton").disabled = true;
}
else {
if (isEditor) { document.getElementById('SubmitButton').disabled = true; }
fetch("/thrimshim/defaults").then(data => data.json()).then(function (data) {
fetch("/thrimshim/defaults")
.then(data => data.json())
.then(function (data) {
if (!data) {
alert("Editor results call failed, is thrimshim running?");
return;
@ -70,136 +84,155 @@ pageSetup = function(isEditor) {
if (isEditor) {
document.getElementById("VideoTitlePrefix").value = data.title_prefix;
document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length);
setOptions('uploadLocation', data.upload_locations);
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');
toggleTimeInput("BUSTIME");
}
loadPlaylist(isEditor);
});
}
};
// Time-formatting functions
parseDuration = function(duration) {
parseDuration = function (duration) {
var direction = 1;
if(duration.startsWith("-")) {
if (duration.startsWith("-")) {
duration = duration.slice(1);
direction = -1;
}
var parts = duration.split(':');
return (parseInt(parts[0]) + (parts[1] || "0")/60 + (parts[2] || "0")/3600) * 60 * 60 * direction;
}
var parts = duration.split(":");
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));
};
toTimestamp = function(date) {
toTimestamp = function (date) {
return date.toISOString().substring(0, 19);
}
};
fromTimestamp = function(ts) {
fromTimestamp = function (ts) {
return new Date(ts + "Z");
}
};
toAgo = function(date) {
now = new Date()
return (date < now ? "":"-") + videojs.formatTime(Math.abs((date - now)/1000), 600.01).padStart(7, "0:");
}
toAgo = function (date) {
now = new Date();
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));
}
};
// Set the stream start/end range from a pair of Dates using the current format
// If given null, sets to blank.
setTimeRange = function(start, end) {
setTimeRange = function (start, end) {
var toFunc = {
UTC: toTimestamp,
BUSTIME: toBustime,
AGO: toAgo,
}[timeFormat];
document.getElementById("StreamStart").value = (start) ? toFunc(start) : "";
document.getElementById("StreamEnd").value = (end) ? toFunc(end) : "";
}
document.getElementById("StreamStart").value = start ? toFunc(start) : "";
document.getElementById("StreamEnd").value = end ? toFunc(end) : "";
};
// Get the current start/end range as Dates using the current format
// Returns an object containing 'start' and 'end' fields.
// If either is empty / invalid, returns null.
getTimeRange = function() {
getTimeRange = function () {
var fromFunc = {
UTC: fromTimestamp,
BUSTIME: fromBustime,
AGO: fromAgo,
}[timeFormat];
var convert = function(value) {
if (!value) { return null; }
var convert = function (value) {
if (!value) {
return null;
}
var date = fromFunc(value);
return (isNaN(date)) ? null : date;
return isNaN(date) ? null : date;
};
return {
start: convert(document.getElementById("StreamStart").value),
end: convert(document.getElementById("StreamEnd").value),
};
}
};
getTimeRangeAsTimestamp = function() {
getTimeRangeAsTimestamp = function () {
var range = getTimeRange();
return {
// if not null, format as timestamp
start: range.start && toTimestamp(range.start),
end: range.end && toTimestamp(range.end),
};
}
};
toggleHiddenPane = function(paneID) {
toggleHiddenPane = function (paneID) {
var pane = document.getElementById(paneID);
pane.style.display = (pane.style.display === "none") ? "block":"none";
}
pane.style.display = pane.style.display === "none" ? "block" : "none";
};
toggleUltrawide = function() {
toggleUltrawide = function () {
var body = document.getElementsByTagName("Body")[0];
body.classList.contains("ultrawide") ? body.classList.remove("ultrawide"):body.classList.add("ultrawide");
}
body.classList.contains("ultrawide")
? body.classList.remove("ultrawide")
: body.classList.add("ultrawide");
};
toggleTimeInput = function(toggleInput) {
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.
// If selected is given, it should be the name of an option to select.
// Otherwise the first one is used.
setOptions = function(element, options, selected) {
setOptions = function (element, options, selected) {
if (!selected && options.length > 0) {
selected = options[0]
selected = options[0];
}
options.forEach(function(option) {
document.getElementById(element).innerHTML += '<option value="'+option+'" '+(option==selected ? 'selected':'')+'>'+option+'</option>';
options.forEach(function (option) {
document.getElementById(element).innerHTML +=
'<option value="' +
option +
'" ' +
(option == selected ? "selected" : "") +
">" +
option +
"</option>";
});
}
};
buildQuery = function(params) {
return Object.keys(params).filter(key => params[key] !== null).map(key =>
encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
).join('&');
}
buildQuery = function (params) {
return Object.keys(params)
.filter(key => params[key] !== null)
.map(key => encodeURIComponent(key) + "=" + encodeURIComponent(params[key]))
.join("&");
};
loadPlaylist = function(isEditor, startTrim, endTrim, defaultQuality) {
loadPlaylist = function (isEditor, startTrim, endTrim, defaultQuality) {
var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8";
var range = getTimeRangeAsTimestamp();
@ -209,64 +242,88 @@ loadPlaylist = function(isEditor, startTrim, endTrim, defaultQuality) {
if (player && player.trimmingControls && player.vhs.playlists.master) {
var discontinuities = mapDiscontinuities();
if (!startTrim) {
startTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
if (startTrim) {startTrim = startTrim.replace('Z','');}
startTrim = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.startTrim
);
if (startTrim) {
startTrim = startTrim.replace("Z", "");
}
}
if (!endTrim) {
endTrim = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
if (endTrim) {endTrim = endTrim.replace('Z','');}
endTrim = getRealTimeForPlayerTime(
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
document.getElementById('qualityLevel').innerHTML = "";
fetch('/files/' + document.getElementById('StreamName').value).then(data => data.json()).then(function (data) {
document.getElementById("qualityLevel").innerHTML = "";
fetch("/files/" + document.getElementById("StreamName").value)
.then(data => data.json())
.then(function (data) {
if (!data.length) {
console.log("Could not retrieve quality levels");
return;
}
var qualityLevels = data.sort().reverse();
setOptions('qualityLevel', qualityLevels, defaultQuality);
setOptions("qualityLevel", qualityLevels, defaultQuality);
if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) {
document.getElementById('wubloaderAdvancedInputTable').style.display = "block";
document.getElementById("wubloaderAdvancedInputTable").style.display = "block";
}
});
};
thrimbletrimmerSubmit = function(state, override_changes=false) {
document.getElementById('SubmitButton').disabled = true;
thrimbletrimmerSubmit = function (state, override_changes = false) {
document.getElementById("SubmitButton").disabled = true;
var discontinuities = mapDiscontinuities();
var start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
if (start) {start = start.replace('Z','');}
var start = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.startTrim
);
if (start) {
start = start.replace("Z", "");
}
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,
video_title:document.getElementById("VideoTitle").value,
video_description:document.getElementById("VideoDescription").value,
video_tags:tags_string_to_list(document.getElementById("VideoTags").value),
allow_holes:document.getElementById('AllowHoles').checked,
upload_location:document.getElementById('uploadLocation').value,
video_channel:document.getElementById("StreamName").value,
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,
video_start: start,
video_end: end,
video_title: document.getElementById("VideoTitle").value,
video_description: document.getElementById("VideoDescription").value,
video_tags: tags_string_to_list(document.getElementById("VideoTags").value),
allow_holes: document.getElementById("AllowHoles").checked,
upload_location: document.getElementById("uploadLocation").value,
video_channel: document.getElementById("StreamName").value,
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
sheet_name:document.data.sheet_name,
event_start:document.data.event_start,
event_end:document.data.event_end,
category:document.data.category,
description:document.data.description,
notes:document.data.notes,
tags:document.data.tags,
sheet_name: document.data.sheet_name,
event_start: document.data.event_start,
event_end: document.data.event_end,
category: document.data.category,
description: document.data.description,
notes: document.data.notes,
tags: document.data.tags,
};
if (!!user) {
wubData.token = user.getAuthResponse().id_token
wubData.token = user.getAuthResponse().id_token;
}
if (override_changes) {
wubData["override_changes"] = true;
@ -274,86 +331,113 @@ thrimbletrimmerSubmit = function(state, override_changes=false) {
console.log(wubData);
console.log(JSON.stringify(wubData));
if (!wubData.video_start) {alert("No start time set"); return;}
if (!wubData.video_end) {alert("No end time set"); return;}
if (!wubData.video_start) {
alert("No start time set");
return;
}
if (!wubData.video_end) {
alert("No end time set");
return;
}
//Submit to thrimshim
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
fetch("/thrimshim/" + rowId, {
method: 'POST',
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(wubData)
})
.then(response => response.text().then(text => {
body: JSON.stringify(wubData),
}).then(response =>
response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
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)) {
thrimbletrimmerSubmit(state, true);
}
} else {
alert(error);
}
} else if (state == 'EDITED') {
alert(`Edit submitted for video from ${start} to ${end}`)
} else if (state == "EDITED") {
alert(`Edit submitted for video from ${start} to ${end}`);
} else {
alert("Draft saved");
}
document.getElementById('SubmitButton').disabled = false;
}));
document.getElementById("SubmitButton").disabled = false;
})
);
};
thrimbletrimmerDownload = function(isEditor) {
thrimbletrimmerDownload = function (isEditor) {
var range = getTimeRangeAsTimestamp();
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");
return;
}
var discontinuities = mapDiscontinuities();
range.start = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.startTrim);
range.end = getRealTimeForPlayerTime(discontinuities, player.trimmingControls().options.endTrim);
range.start = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.startTrim
);
range.end = getRealTimeForPlayerTime(
discontinuities,
player.trimmingControls().options.endTrim
);
}
var targetURL = "/cut/" + document.getElementById("StreamName").value +
"/"+document.getElementById('qualityLevel').options[document.getElementById('qualityLevel').options.selectedIndex].value+".ts" +
"?" + buildQuery({
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
// fine time selection anyway.
type: (isEditor) ? (
document.getElementById('DownloadType').options[document.getElementById('DownloadType').options.selectedIndex].value
) : "rough",
type: isEditor
? document.getElementById("DownloadType").options[
document.getElementById("DownloadType").options.selectedIndex
].value
: "rough",
// Always allow holes in non-editor, accidentially including holes isn't important
allow_holes: (isEditor) ? String(document.getElementById('AllowHoles').checked) : "true",
allow_holes: isEditor ? String(document.getElementById("AllowHoles").checked) : "true",
});
console.log(targetURL);
document.getElementById('DownloadLink').href = targetURL;
document.getElementById('DownloadLink').style.display = "";
document.getElementById("DownloadLink").href = targetURL;
document.getElementById("DownloadLink").style.display = "";
};
thrimbletrimmerManualLink = function() {
thrimbletrimmerManualLink = function () {
document.getElementById("ManualButton").disabled = true;
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
var upload_location = (document.getElementById("ManualYoutube").checked) ? "youtube-manual" : "manual";
var body = {link: document.getElementById("ManualLink").value, upload_location: upload_location};
var upload_location = document.getElementById("ManualYoutube").checked
? "youtube-manual"
: "manual";
var body = {
link: document.getElementById("ManualLink").value,
upload_location: upload_location,
};
if (!!user) {
body.token = user.getAuthResponse().id_token;
}
fetch("/thrimshim/manual-link/"+rowId, {
method: 'POST',
fetch("/thrimshim/manual-link/" + rowId, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(body)
})
.then(response => response.text().then(text => {
body: JSON.stringify(body),
}).then(response =>
response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
console.log(error);
@ -361,37 +445,43 @@ thrimbletrimmerManualLink = function() {
document.getElementById("ManualButton").disabled = false;
} else {
alert("Manual link set to " + body.link);
setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500);
setTimeout(() => {
window.location.href = "/thrimbletrimmer/dashboard.html";
}, 500);
}
}));
})
);
};
thrimbletrimmerResetLink = function(force) {
thrimbletrimmerResetLink = function (force) {
var rowId = /id=(.*)(?:&|$)/.exec(document.location.search)[1];
if(force && !confirm(
'Are you sure you want to reset this event? ' +
'This will set the row back to UNEDITED and forget about any video that already may exist. ' +
'It is intended as a last-ditch command to clear a malfunctioning cutter, ' +
'or if a video needs to be re-edited and replaced. ' +
'IT IS YOUR RESPONSIBILITY TO DEAL WITH ANY VIDEO THAT MAY HAVE ALREADY BEEN UPLOADED. '
)) {
if (
force &&
!confirm(
"Are you sure you want to reset this event? " +
"This will set the row back to UNEDITED and forget about any video that already may exist. " +
"It is intended as a last-ditch command to clear a malfunctioning cutter, " +
"or if a video needs to be re-edited and replaced. " +
"IT IS YOUR RESPONSIBILITY TO DEAL WITH ANY VIDEO THAT MAY HAVE ALREADY BEEN UPLOADED. "
)
) {
return;
}
document.getElementById("ResetButton").disabled = true;
document.getElementById("CancelButton").disabled = true;
var body = {}
var body = {};
if (!!user) {
body.token = user.getAuthResponse().id_token;
}
fetch("/thrimshim/reset/"+rowId + "?force=" + force, {
method: 'POST',
fetch("/thrimshim/reset/" + rowId + "?force=" + force, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(body)
})
.then(response => response.text().then(text => {
body: JSON.stringify(body),
}).then(response =>
response.text().then(text => {
if (!response.ok) {
var error = response.statusText + ": " + text;
console.log(error);
@ -399,25 +489,27 @@ thrimbletrimmerResetLink = function(force) {
document.getElementById("ResetButton").disabled = false;
document.getElementById("CancelButton").disabled = true;
} else {
alert("Row has been " + ((force) ? "reset" : "cancelled") +". Reloading...");
setTimeout(() => { window.location.reload(); }, 500);
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(", ");
}
};
tags_string_to_list = function(tag_string) {
return tag_string.split(",").map(tag => tag.trim()).filter(tag => tag.length > 0);
}
tags_string_to_list = function (tag_string) {
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");
element.value = tags_list_to_string(
tags_string_to_list(
element.value
)
);
}
element.value = tags_list_to_string(tags_string_to_list(element.value));
};

@ -8,72 +8,76 @@ function changeSpeed(direction) {
var newIndex = currentIndex + direction;
if (newIndex < 0 || newIndex >= speeds.length) {
// out of range
return
return;
}
player.playbackRate(speeds[newIndex]);
}
document.addEventListener('keypress', (event) => {
document.addEventListener("keypress", event => {
//if(event.target.nodeName == "BODY") {
if(event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch(event.key) {
if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch (event.key) {
case "j":
player.currentTime(player.currentTime()-10);
player.currentTime(player.currentTime() - 10);
break;
case "k":
case " ": // also pause on space
player.paused() ? player.play():player.pause();
player.paused() ? player.play() : player.pause();
break;
case "l":
player.currentTime(player.currentTime()+10);
player.currentTime(player.currentTime() + 10);
break;
case ",":
player.currentTime(player.currentTime()-0.1);
player.currentTime(player.currentTime() - 0.1);
break;
case ".":
player.currentTime(player.currentTime()+0.1);
player.currentTime(player.currentTime() + 0.1);
break;
case "i":
player.trimmingControls().updateTrimTimes(player.currentTime(), player.trimmingControls().options.endTrim);
player
.trimmingControls()
.updateTrimTimes(player.currentTime(), player.trimmingControls().options.endTrim);
break;
case "o":
player.trimmingControls().updateTrimTimes(player.trimmingControls().options.startTrim, player.currentTime());
player
.trimmingControls()
.updateTrimTimes(player.trimmingControls().options.startTrim, player.currentTime());
break;
case "=":
changeSpeed(1);
break
break;
case "-":
changeSpeed(-1);
break
break;
case "0":
player.currentTime(0);
break;
case "1":
player.currentTime(player.duration()*0.1);
player.currentTime(player.duration() * 0.1);
break;
case "2":
player.currentTime(player.duration()*0.2);
player.currentTime(player.duration() * 0.2);
break;
case "3":
player.currentTime(player.duration()*0.3);
player.currentTime(player.duration() * 0.3);
break;
case "4":
player.currentTime(player.duration()*0.4);
player.currentTime(player.duration() * 0.4);
break;
case "5":
player.currentTime(player.duration()*0.5);
player.currentTime(player.duration() * 0.5);
break;
case "6":
player.currentTime(player.duration()*0.6);
player.currentTime(player.duration() * 0.6);
break;
case "7":
player.currentTime(player.duration()*0.7);
player.currentTime(player.duration() * 0.7);
break;
case "8":
player.currentTime(player.duration()*0.8);
player.currentTime(player.duration() * 0.8);
break;
case "9":
player.currentTime(player.duration()*0.9);
player.currentTime(player.duration() * 0.9);
break;
}
}
@ -84,16 +88,15 @@ document.addEventListener('keypress', (event) => {
});
//Arrow keys only detected on keydown, keypress only works in "some" browsers
document.addEventListener('keydown', (event) => {
if(event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch(event.keyCode) {
document.addEventListener("keydown", event => {
if (event.target.nodeName !== "INPUT" && event.target.nodeName !== "TEXTAREA") {
switch (event.keyCode) {
case 37:
player.currentTime(player.currentTime()-5);
player.currentTime(player.currentTime() - 5);
break;
case 39:
player.currentTime(player.currentTime()+5);
player.currentTime(player.currentTime() + 5);
break;
}
}
});

@ -4,23 +4,24 @@ function setupPlayer(isEditor, source, startTrim, endTrim) {
document.getElementById("my-player").style.display = "";
//Make poster of DB logo in correct aspect ratio, to control initial size of fluid container.
var options = {
sources: [{ src: source }],
sources: [{src: source}],
liveui: true,
//fluid:true,
controls:true,
autoplay:false,
width:1280,
height:420,
controls: true,
autoplay: false,
width: 1280,
height: 420,
playbackRates: [0.5, 1, 1.25, 1.5, 2],
inactivityTimeout: 0,
controlBar: {
fullscreenToggle: true,
volumePanel: {
inline: false
}
}
inline: false,
},
},
};
if(player) { //Destroy and recreate the player if it already exists.
if (player) {
//Destroy and recreate the player if it already exists.
player.dispose();
document.getElementById("EditorContainer").innerHTML = `
<video id="my-player" class="video-js" controls disablePictureInPicture preload="auto">
@ -28,53 +29,64 @@ function setupPlayer(isEditor, source, startTrim, endTrim) {
</video>
`;
}
player = videojs('my-player', options, function onPlayerReady() {
videojs.log('Your player is ready!');
player = videojs("my-player", options, function onPlayerReady() {
videojs.log("Your player is ready!");
// Set player volume to 50% by default
var defaultVolume = 0.5;
this.volume(defaultVolume);
// In this context, `this` is the player that was created by Video.js.
this.on('ready', function() {
this.on("ready", function () {
//this.play();
});
this.vhs.playlists.on('loadedmetadata', function() {
this.vhs.playlists.on("loadedmetadata", function () {
// setTimeout(function() { player.play(); }, 1000);
player.hasStarted(true); //So it displays all the controls.
if (isEditor) {
var stream_start = player.vhs.playlists.master.playlists.filter(playlist => typeof playlist.discontinuityStarts !== "undefined")[0].dateTimeObject;
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 });
var stream_start = player.vhs.playlists.master.playlists.filter(
playlist => typeof playlist.discontinuityStarts !== "undefined"
)[0].dateTimeObject;
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?
this.on('ended', function() {
videojs.log('Awww...over so soon?!');
this.on("ended", function () {
videojs.log("Awww...over so soon?!");
});
this.on('error', function() {
this.on("error", function () {
videojs.log("Could not load video stream");
alert("No video available for stream.");
})
});
});
var hlsQS = player.hlsQualitySelector();
}
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 discontinuities = playlist.discontinuityStarts.map(segmentIndex => { return {segmentIndex:segmentIndex, segmentTimestamp:playlist.segments[segmentIndex].dateTimeObject, playbackIndex:null}; });
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 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;
for (var index = 0; index <= lastDiscontinuity; index++) {
let segment = playlist.segments[index];
if(segment.discontinuity) {
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex = durationMarker;
if (segment.discontinuity) {
discontinuities.find(discontinuity => discontinuity.segmentIndex == index).playbackIndex =
durationMarker;
}
durationMarker += segment.duration;
}
@ -82,17 +94,22 @@ mapDiscontinuities = function() {
return discontinuities;
};
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.
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.
//Find last discontinuity before playbackIndex
var lastDiscontinuity = discontinuities.filter(discontinuity => discontinuity.playbackIndex < playbackIndex).slice(-1).pop();
if(lastDiscontinuity) {
var lastDiscontinuity = discontinuities
.filter(discontinuity => discontinuity.playbackIndex < playbackIndex)
.slice(-1)
.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…
Cancel
Save