summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/js/embed.js50
-rw-r--r--assets/js/player.js282
-rw-r--r--assets/js/watch.js32
-rw-r--r--locales/ar.json24
-rw-r--r--locales/fr.json66
-rw-r--r--src/invidious/helpers/utils.cr2
6 files changed, 231 insertions, 225 deletions
diff --git a/assets/js/embed.js b/assets/js/embed.js
index 074a9d8d..534c30ff 100644
--- a/assets/js/embed.js
+++ b/assets/js/embed.js
@@ -69,32 +69,34 @@ function get_playlist(plid, retries) {
xhr.send();
}
-if (video_data.plid) {
- get_playlist(video_data.plid);
-} else if (video_data.video_series) {
- player.on('ended', function () {
- var url = new URL('https://example.com/embed/' + video_data.video_series.shift());
-
- if (video_data.params.autoplay || video_data.params.continue_autoplay) {
- url.searchParams.set('autoplay', '1');
- }
+window.addEventListener('load', function (e) {
+ if (video_data.plid) {
+ get_playlist(video_data.plid);
+ } else if (video_data.video_series) {
+ player.on('ended', function () {
+ var url = new URL('https://example.com/embed/' + video_data.video_series.shift());
+
+ if (video_data.params.autoplay || video_data.params.continue_autoplay) {
+ url.searchParams.set('autoplay', '1');
+ }
- if (video_data.params.listen !== video_data.preferences.listen) {
- url.searchParams.set('listen', video_data.params.listen);
- }
+ if (video_data.params.listen !== video_data.preferences.listen) {
+ url.searchParams.set('listen', video_data.params.listen);
+ }
- if (video_data.params.speed !== video_data.preferences.speed) {
- url.searchParams.set('speed', video_data.params.speed);
- }
+ if (video_data.params.speed !== video_data.preferences.speed) {
+ url.searchParams.set('speed', video_data.params.speed);
+ }
- if (video_data.params.local !== video_data.preferences.local) {
- url.searchParams.set('local', video_data.params.local);
- }
+ if (video_data.params.local !== video_data.preferences.local) {
+ url.searchParams.set('local', video_data.params.local);
+ }
- if (video_data.video_series.length !== 0) {
- url.searchParams.set('playlist', video_data.video_series.join(','))
- }
+ if (video_data.video_series.length !== 0) {
+ url.searchParams.set('playlist', video_data.video_series.join(','))
+ }
- location.assign(url.pathname + url.search);
- });
-}
+ location.assign(url.pathname + url.search);
+ });
+ }
+});
diff --git a/assets/js/player.js b/assets/js/player.js
index 0d0ecebd..e58af0cd 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -151,45 +151,47 @@ player.vttThumbnails({
// Enable annotations
if (!video_data.params.listen && video_data.params.annotations) {
- var video_container = document.getElementById('player');
- let xhr = new XMLHttpRequest();
- xhr.responseType = 'text';
- xhr.timeout = 60000;
- xhr.open('GET', '/api/v1/annotations/' + video_data.id, true);
-
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- videojs.registerPlugin('youtubeAnnotationsPlugin', youtubeAnnotationsPlugin);
- if (!player.paused()) {
- player.youtubeAnnotationsPlugin({ annotationXml: xhr.response, videoContainer: video_container });
- } else {
- player.one('play', function (event) {
+ window.addEventListener('load', function (e) {
+ var video_container = document.getElementById('player');
+ let xhr = new XMLHttpRequest();
+ xhr.responseType = 'text';
+ xhr.timeout = 60000;
+ xhr.open('GET', '/api/v1/annotations/' + video_data.id, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ videojs.registerPlugin('youtubeAnnotationsPlugin', youtubeAnnotationsPlugin);
+ if (!player.paused()) {
player.youtubeAnnotationsPlugin({ annotationXml: xhr.response, videoContainer: video_container });
- });
+ } else {
+ player.one('play', function (event) {
+ player.youtubeAnnotationsPlugin({ annotationXml: xhr.response, videoContainer: video_container });
+ });
+ }
}
}
}
- }
- window.addEventListener('__ar_annotation_click', e => {
- const { url, target, seconds } = e.detail;
- var path = new URL(url);
+ window.addEventListener('__ar_annotation_click', e => {
+ const { url, target, seconds } = e.detail;
+ var path = new URL(url);
- if (path.href.startsWith('https://www.youtube.com/watch?') && seconds) {
- path.search += '&t=' + seconds;
- }
+ if (path.href.startsWith('https://www.youtube.com/watch?') && seconds) {
+ path.search += '&t=' + seconds;
+ }
- path = path.pathname + path.search;
+ path = path.pathname + path.search;
- if (target === 'current') {
- window.location.href = path;
- } else if (target === 'new') {
- window.open(path, '_blank');
- }
- });
+ if (target === 'current') {
+ window.location.href = path;
+ } else if (target === 'new') {
+ window.open(path, '_blank');
+ }
+ });
- xhr.send();
+ xhr.send();
+ });
}
function increase_volume(delta) {
@@ -234,25 +236,25 @@ function toggle_play() {
}
}
-const toggle_captions = (function() {
+const toggle_captions = (function () {
let toggledTrack = null;
- const onChange = function(e) {
+ const onChange = function (e) {
toggledTrack = null;
};
- const bindChange = function(onOrOff) {
+ const bindChange = function (onOrOff) {
player.textTracks()[onOrOff]('change', onChange);
};
// Wrapper function to ignore our own emitted events and only listen
// to events emitted by Video.js on click on the captions menu items.
- const setMode = function(track, mode) {
+ const setMode = function (track, mode) {
bindChange('off');
track.mode = mode;
- window.setTimeout(function() {
+ window.setTimeout(function () {
bindChange('on');
}, 0);
};
bindChange('on');
- return function() {
+ return function () {
if (toggledTrack !== null) {
if (toggledTrack.mode !== 'showing') {
setMode(toggledTrack, 'showing');
@@ -323,95 +325,95 @@ window.addEventListener('keydown', e => {
|| e.target === document.querySelector('.vjs-tech')
|| e.target === document.querySelector('.iframeblocker')
|| e.target === document.querySelector('.vjs-control-bar')
- ;
+ ;
let action = null;
const code = e.keyCode;
const decoratedKey =
e.key
- + (e.altKey ? '+alt' : '')
+ + (e.altKey ? '+alt' : '')
+ (e.ctrlKey ? '+ctrl' : '')
+ (e.metaKey ? '+meta' : '')
- ;
+ ;
switch (decoratedKey) {
- case ' ':
- case 'k':
- action = toggle_play;
- break;
-
- case 'ArrowUp':
- if (isPlayerFocused) {
- action = increase_volume.bind(this, 0.1);
- }
- break;
- case 'ArrowDown':
- if (isPlayerFocused) {
- action = increase_volume.bind(this, -0.1);
- }
- break;
-
- case 'm':
- action = toggle_muted;
- break;
-
- case 'ArrowRight':
- action = skip_seconds.bind(this, 5);
- break;
- case 'ArrowLeft':
- action = skip_seconds.bind(this, -5);
- break;
- case 'l':
- action = skip_seconds.bind(this, 10);
- break;
- case 'j':
- action = skip_seconds.bind(this, -10);
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- 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 'N':
- action = next_video;
- break;
- case 'P':
- // TODO: Add support to play back previous video.
- break;
-
- case '.':
- // TODO: Add support for next-frame-stepping.
- break;
- case ',':
- // 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;
-
- default:
- console.info('Unhandled key down event: %s:', decoratedKey, e);
- break;
+ case ' ':
+ case 'k':
+ action = toggle_play;
+ break;
+
+ case 'ArrowUp':
+ if (isPlayerFocused) {
+ action = increase_volume.bind(this, 0.1);
+ }
+ break;
+ case 'ArrowDown':
+ if (isPlayerFocused) {
+ action = increase_volume.bind(this, -0.1);
+ }
+ break;
+
+ case 'm':
+ action = toggle_muted;
+ break;
+
+ case 'ArrowRight':
+ action = skip_seconds.bind(this, 5);
+ break;
+ case 'ArrowLeft':
+ action = skip_seconds.bind(this, -5);
+ break;
+ case 'l':
+ action = skip_seconds.bind(this, 10);
+ break;
+ case 'j':
+ action = skip_seconds.bind(this, -10);
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ 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 'N':
+ action = next_video;
+ break;
+ case 'P':
+ // TODO: Add support to play back previous video.
+ break;
+
+ case '.':
+ // TODO: Add support for next-frame-stepping.
+ break;
+ case ',':
+ // 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;
+
+ default:
+ console.info('Unhandled key down event: %s:', decoratedKey, e);
+ break;
}
if (action) {
@@ -422,7 +424,7 @@ window.addEventListener('keydown', e => {
// Add support for controlling the player volume by scrolling over it. Adapted from
// https://github.com/ctd1500/videojs-hotkeys/blob/bb4a158b2e214ccab87c2e7b95f42bc45c6bfd87/videojs.hotkeys.js#L292-L328
-(function() {
+(function () {
const volumeStep = 0.05;
const enableVolumeScroll = true;
const enableHoverScroll = true;
@@ -432,33 +434,33 @@ window.addEventListener('keydown', e => {
var volumeHover = false;
var volumeSelector = pEl.querySelector('.vjs-volume-menu-button') || pEl.querySelector('.vjs-volume-panel');
if (volumeSelector != null) {
- volumeSelector.onmouseover = function() { volumeHover = true; };
- volumeSelector.onmouseout = function() { volumeHover = false; };
+ volumeSelector.onmouseover = function () { volumeHover = true; };
+ volumeSelector.onmouseout = function () { volumeHover = false; };
}
var mouseScroll = function mouseScroll(event) {
- var activeEl = doc.activeElement;
- if (enableHoverScroll) {
- // If we leave this undefined then it can match non-existent elements below
- activeEl = 0;
- }
-
- // When controls are disabled, hotkeys will be disabled as well
- if (player.controls()) {
- if (volumeHover) {
- if (enableVolumeScroll) {
- event = window.event || event;
- var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
- event.preventDefault();
-
- if (delta == 1) {
- increase_volume(volumeStep);
- } else if (delta == -1) {
- increase_volume(-volumeStep);
+ var activeEl = doc.activeElement;
+ if (enableHoverScroll) {
+ // If we leave this undefined then it can match non-existent elements below
+ activeEl = 0;
+ }
+
+ // When controls are disabled, hotkeys will be disabled as well
+ if (player.controls()) {
+ if (volumeHover) {
+ if (enableVolumeScroll) {
+ event = window.event || event;
+ var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
+ event.preventDefault();
+
+ if (delta == 1) {
+ increase_volume(volumeStep);
+ } else if (delta == -1) {
+ increase_volume(-volumeStep);
+ }
+ }
}
- }
}
- }
};
player.on('mousewheel', mouseScroll);
diff --git a/assets/js/watch.js b/assets/js/watch.js
index 80cb1769..a26cb505 100644
--- a/assets/js/watch.js
+++ b/assets/js/watch.js
@@ -439,19 +439,21 @@ if (video_data.play_next) {
});
}
-if (video_data.plid) {
- get_playlist(video_data.plid);
-}
+window.addEventListener('load', function (e) {
+ if (video_data.plid) {
+ get_playlist(video_data.plid);
+ }
-if (video_data.params.comments[0] === 'youtube') {
- get_youtube_comments();
-} else if (video_data.params.comments[0] === 'reddit') {
- get_reddit_comments();
-} else if (video_data.params.comments[1] === 'youtube') {
- get_youtube_comments();
-} else if (video_data.params.comments[1] === 'reddit') {
- get_reddit_comments();
-} else {
- comments = document.getElementById('comments');
- comments.innerHTML = '';
-}
+ if (video_data.params.comments[0] === 'youtube') {
+ get_youtube_comments();
+ } else if (video_data.params.comments[0] === 'reddit') {
+ get_reddit_comments();
+ } else if (video_data.params.comments[1] === 'youtube') {
+ get_youtube_comments();
+ } else if (video_data.params.comments[1] === 'reddit') {
+ get_reddit_comments();
+ } else {
+ comments = document.getElementById('comments');
+ comments.innerHTML = '';
+ }
+});
diff --git a/locales/ar.json b/locales/ar.json
index 4c717435..c580a2d5 100644
--- a/locales/ar.json
+++ b/locales/ar.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` المشتركين",
"`x` videos": "`x` الفيديوهات",
- "`x` playlists": "",
+ "`x` playlists": "`x` قوائم التشغيل",
"LIVE": "مباشر",
"Shared `x` ago": "تم رفع الفيديو منذ `x`",
"Unsubscribe": "إلغاء الإشتراك",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "مشاهدة معلومات حول تراخيص الجافاسكريبت.",
"View privacy policy.": "عرض سياسة الخصوصية.",
"Trending": "الشائع",
- "Public": "",
+ "Public": "عام",
"Unlisted": "غير مصنف",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "خاص",
+ "View all playlists": "عرض جميع قوائم التشغيل",
+ "Updated `x` ago": "تم تحديثه منذ `x`",
+ "Delete playlist `x`?": "حذف قائمه التشغيل `x` ?",
+ "Delete playlist": "حذف قائمه التغشيل",
+ "Create playlist": "إنشاء قائمه تشغيل",
+ "Title": "العنوان",
+ "Playlist privacy": "إعدادات الخصوصيه",
+ "Editing playlist `x`": "تعديل قائمه التشفيل `x`",
"Watch on YouTube": "مشاهدة الفيديو على اليوتيوب",
"Hide annotations": "إخفاء الملاحظات فى الفيديو",
"Show annotations": "عرض الملاحظات فى الفيديو",
@@ -333,4 +333,4 @@
"Playlists": "قوائم التشغيل",
"Community": "المجتمع",
"Current version: ": "الإصدار الحالي: "
-} \ No newline at end of file
+}
diff --git a/locales/fr.json b/locales/fr.json
index de80cae8..928904c1 100644
--- a/locales/fr.json
+++ b/locales/fr.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` abonnés",
"`x` videos": "`x` vidéos",
- "`x` playlists": "",
+ "`x` playlists": "`x` listes de lecture",
"LIVE": "EN DIRECT",
"Shared `x` ago": "Ajoutée il y a `x`",
"Unsubscribe": "Se désabonner",
@@ -53,9 +53,9 @@
"Preferences": "Préférences",
"Player preferences": "Préférences du lecteur",
"Always loop: ": "Lire en boucle : ",
- "Autoplay: ": "Lecture automatique : ",
+ "Autoplay: ": "Lancer la lecture automatiquement : ",
"Play next by default: ": "Lire les vidéos suivantes par défaut : ",
- "Autoplay next video: ": "Lecture automatique pour la vidéo suivante : ",
+ "Autoplay next video: ": "Lancer la lecture automatiquement pour la vidéo suivant la vidéo regardée : ",
"Listen by default: ": "Audio uniquement : ",
"Proxy videos: ": "Charger les vidéos à travers un proxy : ",
"Default speed: ": "Vitesse par défaut : ",
@@ -70,11 +70,11 @@
"Show annotations by default: ": "Afficher les annotations par défaut : ",
"Visual preferences": "Préférences du site",
"Player style: ": "Style du lecteur : ",
- "Dark mode: ": "Mode Sombre : ",
+ "Dark mode: ": "Mode sombre : ",
"Theme: ": "Thème : ",
"dark": "sombre",
"light": "clair",
- "Thin mode: ": "Mode Simplifié : ",
+ "Thin mode: ": "Mode léger : ",
"Subscription preferences": "Préférences de la page d'abonnements",
"Show annotations by default for subscribed channels: ": "Afficher les annotations par défaut sur les chaînes auxquelles vous êtes abonnés : ",
"Redirect homepage to feed: ": "Rediriger la page d'accueil vers la page d'abonnements : ",
@@ -86,12 +86,12 @@
"alphabetically - reverse": "alphabétiquement - inversé",
"channel name": "nom de la chaîne",
"channel name - reverse": "nom de la chaîne - inversé",
- "Only show latest video from channel: ": "Afficher uniquement la dernière vidéo des chaîne auxquelles vous êtes abonnés : ",
- "Only show latest unwatched video from channel: ": "Afficher uniquement la dernière vidéo des chaîne auxquelles vous êtes abonnés que n'a pas était regardée : ",
+ "Only show latest video from channel: ": "Afficher uniquement la dernière vidéo des chaînes auxquelles vous êtes abonnés : ",
+ "Only show latest unwatched video from channel: ": "Afficher uniquement la dernière vidéo des chaînes auxquelles vous êtes abonnés qui n'a pas était regardée : ",
"Only show unwatched: ": "Afficher uniquement les vidéos qui n'ont pas étaient regardées : ",
"Only show notifications (if there are any): ": "Afficher uniquement les notifications (s'il y en a) : ",
"Enable web notifications": "Activer les notifications web",
- "`x` uploaded a video": "`x` a partagé(e) une video",
+ "`x` uploaded a video": "`x` a partagé(e) une vidéo",
"`x` is live": "`x` est en direct",
"Data preferences": "Préférences liées aux données",
"Clear watch history": "Supprimer l'historique des vidéos regardées",
@@ -101,7 +101,7 @@
"Manage tokens": "Gérer les tokens",
"Watch history": "Historique de visionnage",
"Delete account": "Supprimer votre compte",
- "Administrator preferences": "Préferences d'Administrateur",
+ "Administrator preferences": "Préferences d'Administration",
"Default homepage: ": "Page d'accueil par défaut : ",
"Feed menu: ": "Préferences des abonnements : ",
"Top enabled: ": "Top activé : ",
@@ -123,29 +123,29 @@
"search": "rechercher",
"Log out": "Déconnexion",
"Released under the AGPLv3 by Omar Roth.": "Publié sous licence AGPLv3 par Omar Roth.",
- "Source available here.": "Code Source disponible ici.",
+ "Source available here.": "Code source disponible ici.",
"View JavaScript license information.": "Informations des licences JavaScript.",
"View privacy policy.": "Politique de confidentialité.",
"Trending": "Tendances",
- "Public": "",
+ "Public": "Publique",
"Unlisted": "Non répertoriée",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Privée",
+ "View all playlists": "Voir toutes vos playlists",
+ "Updated `x` ago": "Dernière mise à jour il y a `x`",
+ "Delete playlist `x`?": "Êtes-vous sûr de vouloir supprimer la liste de lecture ?",
+ "Delete playlist": "Supprimer la liste de lecture",
+ "Create playlist": "Créer une liste de lecture",
+ "Title": "Titre",
+ "Playlist privacy": "Paramètres de confidentialité de la liste de lecture",
+ "Editing playlist `x`": "Liste de lecture modifier le `x`",
"Watch on YouTube": "Voir la vidéo sur Youtube",
"Hide annotations": "Masquer les annotations",
"Show annotations": "Afficher les annotations",
"Genre: ": "Genre : ",
"License: ": "Licence : ",
- "Family friendly? ": "Tout Public ? ",
+ "Family friendly? ": "Vidéo tout public ? ",
"Wilson score: ": "Score de Wilson : ",
- "Engagement: ": "Poucentage de spectateur aillant Like ou Dislike la vidéo : ",
+ "Engagement: ": "Pourcentage de spectateur aillant appuyé sur \"J'aime\" ou \"J'aime Pas\" : ",
"Whitelisted regions: ": "Régions sur liste blanche : ",
"Blacklisted regions: ": "Régions sur liste noire : ",
"Shared `x`": "Ajoutée le `x`",
@@ -160,7 +160,7 @@
"Hide replies": "Masquer les réponses",
"Show replies": "Afficher les réponses",
"Incorrect password": "Mot de passe incorrect",
- "Quota exceeded, try again in a few hours": "Nombre de tentative de connexion dépassé, réessayez dans quelques heures",
+ "Quota exceeded, try again in a few hours": "Nombre de tentative de connexion dépassée, réessayez dans quelques heures",
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Impossible de se connecter, si après plusieurs tentative vous ne parvenez toujours pas à vous connecter, assurez-vous que l'authentification à deux facteurs (Authenticator ou SMS) est activée.",
"Invalid TFA code": "Code d'authentification à deux facteurs invalide",
"Login failed. This may be because two-factor authentication is not turned on for your account.": "La connexion a échoué. Cela peut être dû au fait que l'authentification à deux facteurs n'est pas activée sur votre compte.",
@@ -182,17 +182,17 @@
"Could not fetch comments": "Impossible de charger les commentaires",
"View `x` replies": "Voir `x` réponses",
"`x` ago": "il y a `x`",
- "Load more": "Charger plus",
+ "Load more": "Voir plus",
"`x` points": "`x` points",
"Could not create mix.": "Impossible de charger cette liste de lecture.",
- "Empty playlist": "Liste de lecture vide",
- "Not a playlist.": "Liste de lecture invalide.",
+ "Empty playlist": "La liste de lecture est vide",
+ "Not a playlist.": "La liste de lecture est invalide.",
"Playlist does not exist.": "La liste de lecture n'existe pas.",
"Could not pull trending pages.": "Impossible de charger les pages de tendances.",
"Hidden field \"challenge\" is a required field": "Le champ masqué \"challenge\" est un champ obligatoire",
"Hidden field \"token\" is a required field": "Le champ caché \"token\" est requis",
- "Erroneous challenge": "Challenge Erroné",
- "Erroneous token": "Token Erroné",
+ "Erroneous challenge": "Challenge invalide",
+ "Erroneous token": "Token invalide",
"No such user": "Cet utilisateur n'existe pas",
"Token is expired, please try again": "Le token est expiré, veuillez réessayer",
"English": "Anglais",
@@ -325,12 +325,12 @@
"%A %B %-d, %Y": "%A %-d %B %Y",
"(edited)": "(modifié)",
"YouTube comment permalink": "Lien permanent vers le commentaire sur YouTube",
- "permalink": "permalien",
+ "permalink": "Lien permanent",
"`x` marked it with a ❤": "`x` l'a marqué d'un ❤",
- "Audio mode": "Mode Audio",
- "Video mode": "Mode Vidéo",
+ "Audio mode": "Mode audio",
+ "Video mode": "Mode vidéo",
"Videos": "Vidéos",
- "Playlists": "Liste de lecture",
+ "Playlists": "Listes de lecture",
"Community": "Communauté",
"Current version: ": "Version actuelle : "
-} \ No newline at end of file
+}
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index ed55dc9c..117a5dbe 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -20,7 +20,7 @@ end
def make_client(url : URI, region = nil)
client = HTTPClient.new(url)
- client.family = CONFIG.force_resolve
+ client.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::UNSPEC
client.read_timeout = 15.seconds
client.connect_timeout = 15.seconds