diff --git a/Makefile b/Makefile
index ef6c4e16..7f56d722 100644
--- a/Makefile
+++ b/Makefile
@@ -62,7 +62,8 @@ test:
crystal spec
verify:
- crystal build src/invidious.cr --no-codegen --progress --stats --error-trace
+ crystal build src/invidious.cr -Dskip_videojs_download \
+ --no-codegen --progress --stats --error-trace
# -----------------------
diff --git a/assets/js/handlers.js b/assets/js/handlers.js
index d3957b89..02175957 100644
--- a/assets/js/handlers.js
+++ b/assets/js/handlers.js
@@ -150,13 +150,13 @@
// Ignore shortcuts if any text input is focused
let focused_tag = document.activeElement.tagName.toLowerCase();
- let focused_type = document.activeElement.type.toLowerCase();
- let allowed = /^(button|checkbox|file|radio|submit)$/;
+ const allowed = /^(button|checkbox|file|radio|submit)$/;
- if (focused_tag === "textarea" ||
- (focused_tag === "input" && !focused_type.match(allowed))
- )
- return;
+ if (focused_tag === "textarea") return;
+ if (focused_tag === "input") {
+ let focused_type = document.activeElement.type.toLowerCase();
+ if (!focused_type.match(allowed)) return;
+ }
// Focus search bar on '/'
if (event.key == "/") {
diff --git a/assets/js/player.js b/assets/js/player.js
index a5ea08ec..81a27009 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -60,29 +60,19 @@ videojs.Vhs.xhr.beforeRequest = function(options) {
var player = videojs('player', options);
const storage = (() => {
- try {
- if (localStorage.length !== -1) {
- return localStorage;
- }
- } catch (e) {
- console.info('No storage available: ' + e);
- }
+ try { if (localStorage.length !== -1) return localStorage; }
+ catch (e) { console.info('No storage available: ' + e); }
+
return undefined;
})();
if (location.pathname.startsWith('/embed/')) {
+ var overlay_content = '
';
player.overlay({
- overlays: [{
- start: 'loadstart',
- content: '',
- end: 'playing',
- align: 'top'
- }, {
- start: 'pause',
- content: '',
- end: 'playing',
- align: 'top'
- }]
+ overlays: [
+ { start: 'loadstart', content: overlay_content, end: 'playing', align: 'top'},
+ { start: 'pause', content: overlay_content, end: 'playing', align: 'top'}
+ ]
});
}
@@ -99,9 +89,7 @@ if (isMobile()) {
buttons = ["playToggle", "volumePanel", "captionsButton"];
- if (video_data.params.quality !== 'dash') {
- buttons.push("qualitySelector")
- }
+ if (video_data.params.quality !== 'dash') buttons.push("qualitySelector")
// Create new control bar object for operation buttons
const ControlBar = videojs.getComponent("controlBar");
@@ -146,16 +134,12 @@ player.on('error', function (event) {
player.load();
- if (currentTime > 0.5) {
- currentTime -= 0.5;
- }
+ if (currentTime > 0.5) currentTime -= 0.5;
player.currentTime(currentTime);
player.playbackRate(playbackRate);
- if (!paused) {
- player.play();
- }
+ if (!paused) player.play();
}, 5000);
}
});
@@ -183,13 +167,8 @@ if (video_data.params.video_start > 0 || video_data.params.video_end > 0) {
player.markers({
onMarkerReached: function (marker) {
- if (marker.text === 'End') {
- if (player.loop()) {
- player.markers.prev('Start');
- } else {
- player.pause();
- }
- }
+ if (marker.text === 'End')
+ player.loop() ? player.markers.prev('Start') : player.pause();
},
markers: markers
});
@@ -217,9 +196,7 @@ if (video_data.params.save_player_pos) {
const remeberedTime = get_video_time();
let lastUpdated = 0;
- if(!hasTimeParam) {
- set_seconds_after_start(remeberedTime);
- }
+ if(!hasTimeParam) set_seconds_after_start(remeberedTime);
const updateTime = () => {
const raw = player.currentTime();
@@ -233,9 +210,7 @@ if (video_data.params.save_player_pos) {
player.on("timeupdate", updateTime);
}
-else {
- remove_all_video_times();
-}
+else remove_all_video_times();
if (video_data.params.autoplay) {
var bpb = player.getChild('bigPlayButton');
@@ -433,26 +408,10 @@ function set_time_percent(percent) {
player.currentTime(newTime);
}
-function play() {
- player.play();
-}
-
-function pause() {
- player.pause();
-}
-
-function stop() {
- player.pause();
- player.currentTime(0);
-}
-
-function toggle_play() {
- if (player.paused()) {
- play();
- } else {
- pause();
- }
-}
+function play() { player.play(); }
+function pause() { player.pause(); }
+function stop() { player.pause(); player.currentTime(0); }
+function toggle_play() { player.paused() ? play() : pause(); }
const toggle_captions = (function () {
let toggledTrack = null;
@@ -490,9 +449,7 @@ const toggle_captions = (function () {
const tracks = player.textTracks();
for (let i = 0; i < tracks.length; i++) {
const track = tracks[i];
- if (track.kind !== 'captions') {
- continue;
- }
+ if (track.kind !== 'captions') continue;
if (fallbackCaptionsTrack === null) {
fallbackCaptionsTrack = track;
@@ -513,11 +470,7 @@ const toggle_captions = (function () {
})();
function toggle_fullscreen() {
- if (player.isFullscreen()) {
- player.exitFullscreen();
- } else {
- player.requestFullscreen();
- }
+ player.isFullscreen() ? player.exitFullscreen() : player.requestFullscreen();
}
function increase_playback_rate(steps) {
@@ -560,27 +513,15 @@ window.addEventListener('keydown', e => {
action = toggle_play;
break;
- case 'MediaPlay':
- action = play;
- break;
-
- case 'MediaPause':
- action = pause;
- break;
-
- case 'MediaStop':
- action = stop;
- break;
+ case 'MediaPlay': action = play; break;
+ case 'MediaPause': action = pause; break;
+ case 'MediaStop': action = stop; break;
case 'ArrowUp':
- if (isPlayerFocused) {
- action = increase_volume.bind(this, 0.1);
- }
+ if (isPlayerFocused) action = increase_volume.bind(this, 0.1);
break;
case 'ArrowDown':
- if (isPlayerFocused) {
- action = increase_volume.bind(this, -0.1);
- }
+ if (isPlayerFocused) action = increase_volume.bind(this, -0.1);
break;
case 'm':
@@ -612,16 +553,15 @@ window.addEventListener('keydown', e => {
case '7':
case '8':
case '9':
+ // Ignore numpad numbers
+ if (code > 57) break;
+
const percent = (code - 48) * 10;
action = set_time_percent.bind(this, percent);
break;
- case 'c':
- action = toggle_captions;
- break;
- case 'f':
- action = toggle_fullscreen;
- break;
+ case 'c': action = toggle_captions; break;
+ case 'f': action = toggle_fullscreen; break;
case 'N':
case 'MediaTrackNext':
@@ -639,12 +579,8 @@ window.addEventListener('keydown', e => {
// TODO: Add support for previous-frame-stepping.
break;
- case '>':
- action = increase_playback_rate.bind(this, 1);
- break;
- case '<':
- action = increase_playback_rate.bind(this, -1);
- break;
+ case '>': action = increase_playback_rate.bind(this, 1); break;
+ case '<': action = increase_playback_rate.bind(this, -1); break;
default:
console.info('Unhandled key down event: %s:', decoratedKey, e);
diff --git a/locales/en-US.json b/locales/en-US.json
index f733f7db..c7f6e178 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -94,7 +94,7 @@
"preferences_related_videos_label": "Show related videos: ",
"preferences_annotations_label": "Show annotations by default: ",
"preferences_extend_desc_label": "Automatically extend video description: ",
- "preferences_vr_mode_label": "Interactive 360 degree videos: ",
+ "preferences_vr_mode_label": "Interactive 360 degree videos (requires WebGL): ",
"preferences_category_visual": "Visual preferences",
"preferences_region_label": "Content country: ",
"preferences_player_style_label": "Player style: ",
@@ -236,6 +236,8 @@
"No such user": "No such user",
"Token is expired, please try again": "Token is expired, please try again",
"English": "English",
+ "English (United Kingdom)": "English (United Kingdom)",
+ "English (United States)": "English (United States)",
"English (auto-generated)": "English (auto-generated)",
"Afrikaans": "Afrikaans",
"Albanian": "Albanian",
@@ -249,23 +251,31 @@
"Bosnian": "Bosnian",
"Bulgarian": "Bulgarian",
"Burmese": "Burmese",
+ "Cantonese (Hong Kong)": "Cantonese (Hong Kong)",
"Catalan": "Catalan",
"Cebuano": "Cebuano",
+ "Chinese": "Chinese",
+ "Chinese (China)": "Chinese (China)",
+ "Chinese (Hong Kong)": "Chinese (Hong Kong)",
"Chinese (Simplified)": "Chinese (Simplified)",
+ "Chinese (Taiwan)": "Chinese (Taiwan)",
"Chinese (Traditional)": "Chinese (Traditional)",
"Corsican": "Corsican",
"Croatian": "Croatian",
"Czech": "Czech",
"Danish": "Danish",
"Dutch": "Dutch",
+ "Dutch (auto-generated)": "Dutch (auto-generated)",
"Esperanto": "Esperanto",
"Estonian": "Estonian",
"Filipino": "Filipino",
"Finnish": "Finnish",
"French": "French",
+ "French (auto-generated)": "French (auto-generated)",
"Galician": "Galician",
"Georgian": "Georgian",
"German": "German",
+ "German (auto-generated)": "German (auto-generated)",
"Greek": "Greek",
"Gujarati": "Gujarati",
"Haitian Creole": "Haitian Creole",
@@ -278,14 +288,19 @@
"Icelandic": "Icelandic",
"Igbo": "Igbo",
"Indonesian": "Indonesian",
+ "Indonesian (auto-generated)": "Indonesian (auto-generated)",
+ "Interlingue": "Interlingue",
"Irish": "Irish",
"Italian": "Italian",
+ "Italian (auto-generated)": "Italian (auto-generated)",
"Japanese": "Japanese",
+ "Japanese (auto-generated)": "Japanese (auto-generated)",
"Javanese": "Javanese",
"Kannada": "Kannada",
"Kazakh": "Kazakh",
"Khmer": "Khmer",
"Korean": "Korean",
+ "Korean (auto-generated)": "Korean (auto-generated)",
"Kurdish": "Kurdish",
"Kyrgyz": "Kyrgyz",
"Lao": "Lao",
@@ -308,9 +323,12 @@
"Persian": "Persian",
"Polish": "Polish",
"Portuguese": "Portuguese",
+ "Portuguese (auto-generated)": "Portuguese (auto-generated)",
+ "Portuguese (Brazil)": "Portuguese (Brazil)",
"Punjabi": "Punjabi",
"Romanian": "Romanian",
"Russian": "Russian",
+ "Russian (auto-generated)": "Russian (auto-generated)",
"Samoan": "Samoan",
"Scottish Gaelic": "Scottish Gaelic",
"Serbian": "Serbian",
@@ -322,7 +340,10 @@
"Somali": "Somali",
"Southern Sotho": "Southern Sotho",
"Spanish": "Spanish",
+ "Spanish (auto-generated)": "Spanish (auto-generated)",
"Spanish (Latin America)": "Spanish (Latin America)",
+ "Spanish (Mexico)": "Spanish (Mexico)",
+ "Spanish (Spain)": "Spanish (Spain)",
"Sundanese": "Sundanese",
"Swahili": "Swahili",
"Swedish": "Swedish",
@@ -331,10 +352,12 @@
"Telugu": "Telugu",
"Thai": "Thai",
"Turkish": "Turkish",
+ "Turkish (auto-generated)": "Turkish (auto-generated)",
"Ukrainian": "Ukrainian",
"Urdu": "Urdu",
"Uzbek": "Uzbek",
"Vietnamese": "Vietnamese",
+ "Vietnamese (auto-generated)": "Vietnamese (auto-generated)",
"Welsh": "Welsh",
"Western Frisian": "Western Frisian",
"Xhosa": "Xhosa",
diff --git a/src/invidious.cr b/src/invidious.cr
index f4cae7ea..1ff70905 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -114,16 +114,18 @@ LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level)
# Check table integrity
Invidious::Database.check_integrity(CONFIG)
-# Resolve player dependencies. This is done at compile time.
-#
-# Running the script by itself would show some colorful feedback while this doesn't.
-# Perhaps we should just move the script to runtime in order to get that feedback?
+{% if !flag?(:skip_videojs_download) %}
+ # Resolve player dependencies. This is done at compile time.
+ #
+ # Running the script by itself would show some colorful feedback while this doesn't.
+ # Perhaps we should just move the script to runtime in order to get that feedback?
-{% puts "\nChecking player dependencies...\n" %}
-{% if flag?(:minified_player_dependencies) %}
- {% puts run("../scripts/fetch-player-dependencies.cr", "--minified").stringify %}
-{% else %}
- {% puts run("../scripts/fetch-player-dependencies.cr").stringify %}
+ {% puts "\nChecking player dependencies...\n" %}
+ {% if flag?(:minified_player_dependencies) %}
+ {% puts run("../scripts/fetch-player-dependencies.cr", "--minified").stringify %}
+ {% else %}
+ {% puts run("../scripts/fetch-player-dependencies.cr").stringify %}
+ {% end %}
{% end %}
# Start jobs
diff --git a/src/invidious/exceptions.cr b/src/invidious/exceptions.cr
index 391a574d..490d98cd 100644
--- a/src/invidious/exceptions.cr
+++ b/src/invidious/exceptions.cr
@@ -1,8 +1,12 @@
# Exception used to hold the name of the missing item
# Should be used in all parsing functions
-class BrokenTubeException < InfoException
+class BrokenTubeException < Exception
getter element : String
def initialize(@element)
end
+
+ def message
+ return "Missing JSON element \"#{@element}\""
+ end
end
diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr
index 3acbac84..6155e561 100644
--- a/src/invidious/helpers/errors.cr
+++ b/src/invidious/helpers/errors.cr
@@ -38,12 +38,15 @@ def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exce
issue_title = "#{exception.message} (#{exception.class})"
- issue_template = %(Title: `#{issue_title}`)
- issue_template += %(\nDate: `#{Time::Format::ISO_8601_DATE_TIME.format(Time.utc)}`)
- issue_template += %(\nRoute: `#{env.request.resource}`)
- issue_template += %(\nVersion: `#{SOFTWARE["version"]} @ #{SOFTWARE["branch"]}`)
- # issue_template += github_details("Preferences", env.get("preferences").as(Preferences).to_pretty_json)
- issue_template += github_details("Backtrace", exception.inspect_with_backtrace)
+ issue_template = <<-TEXT
+ Title: `#{HTML.escape(issue_title)}`
+ Date: `#{Time::Format::ISO_8601_DATE_TIME.format(Time.utc)}`
+ Route: `#{HTML.escape(env.request.resource)}`
+ Version: `#{SOFTWARE["version"]} @ #{SOFTWARE["branch"]}`
+
+ TEXT
+
+ issue_template += github_details("Backtrace", HTML.escape(exception.inspect_with_backtrace))
# URLs for the error message below
url_faq = "https://github.com/iv-org/documentation/blob/master/FAQ.md"
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index 446e8e03..335f6b60 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -2,6 +2,8 @@ CAPTION_LANGUAGES = {
"",
"English",
"English (auto-generated)",
+ "English (United Kingdom)",
+ "English (United States)",
"Afrikaans",
"Albanian",
"Amharic",
@@ -14,23 +16,31 @@ CAPTION_LANGUAGES = {
"Bosnian",
"Bulgarian",
"Burmese",
+ "Cantonese (Hong Kong)",
"Catalan",
"Cebuano",
+ "Chinese",
+ "Chinese (China)",
+ "Chinese (Hong Kong)",
"Chinese (Simplified)",
+ "Chinese (Taiwan)",
"Chinese (Traditional)",
"Corsican",
"Croatian",
"Czech",
"Danish",
"Dutch",
+ "Dutch (auto-generated)",
"Esperanto",
"Estonian",
"Filipino",
"Finnish",
"French",
+ "French (auto-generated)",
"Galician",
"Georgian",
"German",
+ "German (auto-generated)",
"Greek",
"Gujarati",
"Haitian Creole",
@@ -43,14 +53,19 @@ CAPTION_LANGUAGES = {
"Icelandic",
"Igbo",
"Indonesian",
+ "Indonesian (auto-generated)",
+ "Interlingue",
"Irish",
"Italian",
+ "Italian (auto-generated)",
"Japanese",
+ "Japanese (auto-generated)",
"Javanese",
"Kannada",
"Kazakh",
"Khmer",
"Korean",
+ "Korean (auto-generated)",
"Kurdish",
"Kyrgyz",
"Lao",
@@ -73,9 +88,12 @@ CAPTION_LANGUAGES = {
"Persian",
"Polish",
"Portuguese",
+ "Portuguese (auto-generated)",
+ "Portuguese (Brazil)",
"Punjabi",
"Romanian",
"Russian",
+ "Russian (auto-generated)",
"Samoan",
"Scottish Gaelic",
"Serbian",
@@ -87,7 +105,10 @@ CAPTION_LANGUAGES = {
"Somali",
"Southern Sotho",
"Spanish",
+ "Spanish (auto-generated)",
"Spanish (Latin America)",
+ "Spanish (Mexico)",
+ "Spanish (Spain)",
"Sundanese",
"Swahili",
"Swedish",
@@ -96,10 +117,12 @@ CAPTION_LANGUAGES = {
"Telugu",
"Thai",
"Turkish",
+ "Turkish (auto-generated)",
"Ukrainian",
"Urdu",
"Uzbek",
"Vietnamese",
+ "Vietnamese (auto-generated)",
"Welsh",
"Western Frisian",
"Xhosa",
diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr
index cd0fd0d5..27a8e266 100644
--- a/src/invidious/views/embed.ecr
+++ b/src/invidious/views/embed.ecr
@@ -7,7 +7,7 @@
<%= rendered "components/player_sources" %>
-
+
<%= HTML.escape(video.title) %> - Invidious