Merge branch 'iv-org:master' into master

This commit is contained in:
rocket_2019 2023-03-11 10:53:15 +01:00 committed by GitHub
commit 6077b858ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 894 additions and 286 deletions

View File

@ -23,4 +23,4 @@ jobs:
stale-pr-label: "stale" stale-pr-label: "stale"
ascending: true ascending: true
# Never mark feature requests/enhancements as stale # Never mark feature requests/enhancements as stale
exempt-issue-labels: "feature-request,enhancement" exempt-issue-labels: "feature-request,enhancement,exempt-stale"

View File

@ -154,6 +154,8 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab,
- [Yattee](https://github.com/yattee/yattee): Alternative YouTube frontend for iPhone, iPad, Mac and Apple TV. - [Yattee](https://github.com/yattee/yattee): Alternative YouTube frontend for iPhone, iPad, Mac and Apple TV.
- [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client. - [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client.
- [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API) - [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API)
- [Playlet](https://github.com/iBicha/playlet): Unofficial Youtube client for Roku TV
- [Clipious](https://github.com/lamarios/clipious): Unofficial Invidious client for Android
## Liability ## Liability

View File

@ -145,6 +145,24 @@ img.thumbnail {
object-fit: cover; object-fit: cover;
} }
div.watched-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255,255,255,.4);
}
div.watched-indicator {
position: absolute;
left: 0;
bottom: 0;
height: 4px;
width: 100%;
background-color: red;
}
.length { .length {
z-index: 100; z-index: 100;
position: absolute; position: absolute;
@ -490,13 +508,14 @@ hr {
} }
/* Description Expansion Styling*/ /* Description Expansion Styling*/
#descexpansionbutton { #descexpansionbutton,
display: none #music-desc-expansion {
display: none;
} }
#descexpansionbutton ~ div { #descexpansionbutton ~ div {
overflow: hidden; overflow: hidden;
height: 8.3em; max-height: 8.3em;
} }
#descexpansionbutton:checked ~ div { #descexpansionbutton:checked ~ div {
@ -509,7 +528,8 @@ hr {
margin-top: 20px; margin-top: 20px;
} }
label[for="descexpansionbutton"]:hover { label[for="descexpansionbutton"]:hover,
label[for="music-desc-expansion"]:hover {
cursor: pointer; cursor: pointer;
} }
@ -521,7 +541,8 @@ h4,
h5, h5,
p, p,
#descriptionWrapper, #descriptionWrapper,
#description-box { #description-box,
#music-description-box {
unicode-bidi: plaintext; unicode-bidi: plaintext;
text-align: start; text-align: start;
} }
@ -531,6 +552,29 @@ p,
white-space: pre-wrap; white-space: pre-wrap;
} }
#music-description-box {
display: none;
}
#music-desc-expansion:checked ~ #music-description-box {
display: block;
}
#music-desc-expansion ~ label > h3 > .ion-ios-arrow-up,
#music-desc-expansion:checked ~ label > h3 > .ion-ios-arrow-down {
display: none;
}
#music-desc-expansion:checked ~ label > h3 > .ion-ios-arrow-up,
#music-desc-expansion ~ label > h3 > .ion-ios-arrow-down {
display: inline;
}
/* Select all the music items except the first one */
.music-item + .music-item {
border-top: 1px solid #ffffff;
}
/* Center the "invidious" logo on the search page */ /* Center the "invidious" logo on the search page */
#logo > h1 { text-align: center; } #logo > h1 { text-align: center; }

View File

@ -0,0 +1,24 @@
'use strict';
var save_player_pos_key = 'save_player_pos';
function get_all_video_times() {
return helpers.storage.get(save_player_pos_key) || {};
}
document.querySelectorAll('.watched-indicator').forEach(function (indicator) {
var watched_part = get_all_video_times()[indicator.dataset.id];
var total = parseInt(indicator.dataset.length, 10);
if (watched_part === undefined) {
watched_part = total;
}
var percentage = Math.round((watched_part / total) * 100);
if (percentage < 5) {
percentage = 5;
}
if (percentage > 90) {
percentage = 100;
}
indicator.style.width = percentage + '%';
});

1
locales/af.json Normal file
View File

@ -0,0 +1 @@
{}

View File

@ -536,5 +536,12 @@
"generic_count_seconds_3": "{{count}} ثوانٍ", "generic_count_seconds_3": "{{count}} ثوانٍ",
"generic_count_seconds_4": "{{count}} ثانية", "generic_count_seconds_4": "{{count}} ثانية",
"generic_count_seconds_5": "{{count}} ثانية", "generic_count_seconds_5": "{{count}} ثانية",
"error_video_not_in_playlist": "الفيديو المطلوب غير موجود في قائمة التشغيل هذه. <a href=\"`x`\"> انقر هنا للحصول على الصفحة الرئيسية لقائمة التشغيل. </a>" "error_video_not_in_playlist": "الفيديو المطلوب غير موجود في قائمة التشغيل هذه. <a href=\"`x`\"> انقر هنا للحصول على الصفحة الرئيسية لقائمة التشغيل. </a>",
"channel_tab_shorts_label": "الفيديوهات القصيرة",
"channel_tab_streams_label": "البث المباشر",
"channel_tab_playlists_label": "قوائم التشغيل",
"channel_tab_channels_label": "القنوات",
"Music in this video": "الموسيقى في هذا الفيديو",
"Album: ": "الألبوم: ",
"Artist: ": "الفنان: "
} }

View File

@ -63,7 +63,7 @@
"reddit": "Reddit", "reddit": "Reddit",
"preferences_captions_label": "Výchozí titulky: ", "preferences_captions_label": "Výchozí titulky: ",
"Fallback captions: ": "Záložní titulky: ", "Fallback captions: ": "Záložní titulky: ",
"preferences_related_videos_label": "Zobrazit podobné videa: ", "preferences_related_videos_label": "Zobrazit podobná videa: ",
"preferences_annotations_label": "Zobrazovat poznámky ve výchozím nastavení: ", "preferences_annotations_label": "Zobrazovat poznámky ve výchozím nastavení: ",
"preferences_extend_desc_label": "Rozšířit automaticky popis u videa: ", "preferences_extend_desc_label": "Rozšířit automaticky popis u videa: ",
"preferences_category_visual": "Nastavení vzhledu", "preferences_category_visual": "Nastavení vzhledu",
@ -488,5 +488,12 @@
"search_filters_sort_option_relevance": "Relevantnost", "search_filters_sort_option_relevance": "Relevantnost",
"search_filters_apply_button": "Použít vybrané filtry", "search_filters_apply_button": "Použít vybrané filtry",
"Popular enabled: ": "Populární povoleno: ", "Popular enabled: ": "Populární povoleno: ",
"error_video_not_in_playlist": "Požadované video v tomto playlistu neexistuje. <a href=\"`x`\">Klikněte sem pro navštívení domovské stránky playlistu.</a>" "error_video_not_in_playlist": "Požadované video v tomto playlistu neexistuje. <a href=\"`x`\">Klikněte sem pro navštívení domovské stránky playlistu.</a>",
"channel_tab_shorts_label": "Shorts",
"channel_tab_playlists_label": "Playlisty",
"channel_tab_channels_label": "Kanály",
"channel_tab_streams_label": "Živé přenosy",
"Music in this video": "Hudba v tomto videu",
"Artist: ": "Umělec: ",
"Album: ": "Album: "
} }

View File

@ -472,5 +472,12 @@
"search_filters_duration_option_none": "Beliebige Länge", "search_filters_duration_option_none": "Beliebige Länge",
"search_filters_date_label": "Upload-Datum", "search_filters_date_label": "Upload-Datum",
"search_filters_date_option_none": "Beliebiges Datum", "search_filters_date_option_none": "Beliebiges Datum",
"error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. <a href=\"`x`\">Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen.</a>" "error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. <a href=\"`x`\">Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen.</a>",
"channel_tab_shorts_label": "Shorts",
"channel_tab_streams_label": "Livestreams",
"Music in this video": "Musik in diesem Video",
"Artist: ": "Künstler: ",
"Album: ": "Album: ",
"channel_tab_playlists_label": "Wiedergabelisten",
"channel_tab_channels_label": "Kanäle"
} }

View File

@ -366,7 +366,7 @@
"preferences_quality_option_hd720": "HD720", "preferences_quality_option_hd720": "HD720",
"preferences_quality_option_medium": "Μεσαία", "preferences_quality_option_medium": "Μεσαία",
"preferences_quality_option_small": "Μικρό", "preferences_quality_option_small": "Μικρό",
"preferences_quality_option_dash": "DASH (προσαρμοστική ποιότητα)", "preferences_quality_option_dash": "DASH (προσαρμόσιμη ποιότητα)",
"preferences_quality_dash_option_4320p": "4320p", "preferences_quality_dash_option_4320p": "4320p",
"preferences_quality_dash_option_720p": "720p", "preferences_quality_dash_option_720p": "720p",
"invidious": "Invidious", "invidious": "Invidious",
@ -450,5 +450,5 @@
"search_filters_type_option_show": "Μπάρα προόδου διαβάσματος", "search_filters_type_option_show": "Μπάρα προόδου διαβάσματος",
"preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: ", "preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: ",
"search_filters_title": "Φίλτρο", "search_filters_title": "Φίλτρο",
"search_message_no_results": "Δεν" "search_message_no_results": "Δε βρέθηκαν αποτελέσματα."
} }

View File

@ -188,6 +188,9 @@
"Engagement: ": "Engagement: ", "Engagement: ": "Engagement: ",
"Whitelisted regions: ": "Whitelisted regions: ", "Whitelisted regions: ": "Whitelisted regions: ",
"Blacklisted regions: ": "Blacklisted regions: ", "Blacklisted regions: ": "Blacklisted regions: ",
"Music in this video": "Music in this video",
"Artist: ": "Artist: ",
"Album: ": "Album: ",
"Shared `x`": "Shared `x`", "Shared `x`": "Shared `x`",
"Premieres in `x`": "Premieres in `x`", "Premieres in `x`": "Premieres in `x`",
"Premieres `x`": "Premieres `x`", "Premieres `x`": "Premieres `x`",
@ -451,7 +454,7 @@
"footer_documentation": "Documentation", "footer_documentation": "Documentation",
"footer_source_code": "Source code", "footer_source_code": "Source code",
"footer_original_source_code": "Original source code", "footer_original_source_code": "Original source code",
"footer_modfied_source_code": "Modified Source code", "footer_modfied_source_code": "Modified source code",
"adminprefs_modified_source_code_url_label": "URL to modified source code repository", "adminprefs_modified_source_code_url_label": "URL to modified source code repository",
"none": "none", "none": "none",
"videoinfo_started_streaming_x_ago": "Started streaming `x` ago", "videoinfo_started_streaming_x_ago": "Started streaming `x` ago",

View File

@ -325,7 +325,7 @@
"`x` marked it with a ❤": "`x` markis ĝin per ❤", "`x` marked it with a ❤": "`x` markis ĝin per ❤",
"Audio mode": "Aŭda reĝimo", "Audio mode": "Aŭda reĝimo",
"Video mode": "Videa reĝimo", "Video mode": "Videa reĝimo",
"channel_tab_videos_label": "Filmetoj", "channel_tab_videos_label": "Videoj",
"Playlists": "Ludlistoj", "Playlists": "Ludlistoj",
"channel_tab_community_label": "Komunumo", "channel_tab_community_label": "Komunumo",
"search_filters_sort_option_relevance": "rilateco", "search_filters_sort_option_relevance": "rilateco",
@ -472,5 +472,12 @@
"generic_subscribers_count_plural": "{{count}} abonantoj", "generic_subscribers_count_plural": "{{count}} abonantoj",
"generic_count_months": "{{count}} monato", "generic_count_months": "{{count}} monato",
"generic_count_months_plural": "{{count}} monatoj", "generic_count_months_plural": "{{count}} monatoj",
"preferences_save_player_pos_label": "Konservi ludadan pozicion: " "preferences_save_player_pos_label": "Konservi ludadan pozicion: ",
"channel_tab_streams_label": "Tujelsendoj",
"channel_tab_playlists_label": "Ludlistoj",
"channel_tab_channels_label": "Kanaloj",
"channel_tab_shorts_label": "Mallongaj",
"Music in this video": "Muziko en ĉi tiu video",
"Artist: ": "Artisto: ",
"Album: ": "Albumo: "
} }

View File

@ -52,21 +52,21 @@
"preferences_video_loop_label": "Repetir siempre: ", "preferences_video_loop_label": "Repetir siempre: ",
"preferences_autoplay_label": "Reproducción automática: ", "preferences_autoplay_label": "Reproducción automática: ",
"preferences_continue_label": "Reproducir siguiente por defecto: ", "preferences_continue_label": "Reproducir siguiente por defecto: ",
"preferences_continue_autoplay_label": "Reproducir automáticamente el vídeo siguiente: ", "preferences_continue_autoplay_label": "Reproducir automáticamente el video siguiente: ",
"preferences_listen_label": "Activar el sonido por defecto: ", "preferences_listen_label": "Activar el sonido por defecto: ",
"preferences_local_label": "¿Usar un proxy para los vídeos? ", "preferences_local_label": "¿Usar un proxy para los videos? ",
"preferences_speed_label": "Velocidad por defecto: ", "preferences_speed_label": "Velocidad por defecto: ",
"preferences_quality_label": "Calidad de vídeo preferida: ", "preferences_quality_label": "Calidad de video preferida: ",
"preferences_volume_label": "Volumen del reproductor: ", "preferences_volume_label": "Volumen del reproductor: ",
"preferences_comments_label": "Comentarios por defecto: ", "preferences_comments_label": "Comentarios por defecto: ",
"youtube": "YouTube", "youtube": "YouTube",
"reddit": "Reddit", "reddit": "Reddit",
"preferences_captions_label": "Subtítulos por defecto: ", "preferences_captions_label": "Subtítulos por defecto: ",
"Fallback captions: ": "Subtítulos alternativos: ", "Fallback captions: ": "Subtítulos alternativos: ",
"preferences_related_videos_label": "¿Mostrar vídeos relacionados? ", "preferences_related_videos_label": "¿Mostrar videos relacionados? ",
"preferences_annotations_label": "¿Mostrar anotaciones por defecto? ", "preferences_annotations_label": "¿Mostrar anotaciones por defecto? ",
"preferences_extend_desc_label": "Extender automáticamente la descripción del vídeo: ", "preferences_extend_desc_label": "Extender automáticamente la descripción del video: ",
"preferences_vr_mode_label": "Vídeos interactivos de 360 grados (necesita WebGL): ", "preferences_vr_mode_label": "Videos interactivos de 360 grados (necesita WebGL): ",
"preferences_category_visual": "Preferencias visuales", "preferences_category_visual": "Preferencias visuales",
"preferences_player_style_label": "Estilo de reproductor: ", "preferences_player_style_label": "Estilo de reproductor: ",
"Dark mode: ": "Modo oscuro: ", "Dark mode: ": "Modo oscuro: ",
@ -79,16 +79,16 @@
"preferences_category_subscription": "Preferencias de la suscripción", "preferences_category_subscription": "Preferencias de la suscripción",
"preferences_annotations_subscribed_label": "¿Mostrar anotaciones por defecto para los canales suscritos? ", "preferences_annotations_subscribed_label": "¿Mostrar anotaciones por defecto para los canales suscritos? ",
"Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ", "Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ",
"preferences_max_results_label": "Número de vídeos mostrados en la fuente: ", "preferences_max_results_label": "Número de videos mostrados en la fuente: ",
"preferences_sort_label": "Ordenar los vídeos por: ", "preferences_sort_label": "Ordenar los videos por: ",
"published": "fecha de publicación", "published": "fecha de publicación",
"published - reverse": "fecha de publicación: orden inverso", "published - reverse": "fecha de publicación: orden inverso",
"alphabetically": "alfabéticamente", "alphabetically": "alfabéticamente",
"alphabetically - reverse": "alfabéticamente: orden inverso", "alphabetically - reverse": "alfabéticamente: orden inverso",
"channel name": "nombre del canal", "channel name": "nombre del canal",
"channel name - reverse": "nombre del canal: orden inverso", "channel name - reverse": "nombre del canal: orden inverso",
"Only show latest video from channel: ": "Mostrar solo el último vídeo del canal: ", "Only show latest video from channel: ": "Mostrar solo el último video del canal: ",
"Only show latest unwatched video from channel: ": "Mostrar solo el último vídeo sin ver del canal: ", "Only show latest unwatched video from channel: ": "Mostrar solo el último video sin ver del canal: ",
"preferences_unseen_only_label": "Mostrar solo los no vistos: ", "preferences_unseen_only_label": "Mostrar solo los no vistos: ",
"preferences_notifications_only_label": "Mostrar solo notificaciones (si hay alguna): ", "preferences_notifications_only_label": "Mostrar solo notificaciones (si hay alguna): ",
"Enable web notifications": "Habilitar notificaciones web", "Enable web notifications": "Habilitar notificaciones web",
@ -139,7 +139,7 @@
"Editing playlist `x`": "Editando la lista de reproducción 'x'", "Editing playlist `x`": "Editando la lista de reproducción 'x'",
"Show more": "Mostrar más", "Show more": "Mostrar más",
"Show less": "Mostrar menos", "Show less": "Mostrar menos",
"Watch on YouTube": "Ver el vídeo en YouTube", "Watch on YouTube": "Ver en YouTube",
"Switch Invidious Instance": "Cambiar Instancia de Invidious", "Switch Invidious Instance": "Cambiar Instancia de Invidious",
"Hide annotations": "Ocultar anotaciones", "Hide annotations": "Ocultar anotaciones",
"Show annotations": "Mostrar anotaciones", "Show annotations": "Mostrar anotaciones",
@ -153,7 +153,7 @@
"Shared `x`": "Compartido `x`", "Shared `x`": "Compartido `x`",
"Premieres in `x`": "Se estrena en `x`", "Premieres in `x`": "Se estrena en `x`",
"Premieres `x`": "Estrenos `x`", "Premieres `x`": "Estrenos `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "¡Hola! Parece que tiene JavaScript desactivado. Haga clic aquí para ver los comentarios, pero tenga en cuenta que pueden tardar un poco más en cargarse.", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "¡Hola! Parece que tienes JavaScript desactivado. Haz clic aquí para ver los comentarios, pero tengas en cuenta que pueden tardar un poco más en cargarse.",
"View YouTube comments": "Ver los comentarios de YouTube", "View YouTube comments": "Ver los comentarios de YouTube",
"View more comments on Reddit": "Ver más comentarios en Reddit", "View more comments on Reddit": "Ver más comentarios en Reddit",
"View `x` comments": { "View `x` comments": {
@ -164,7 +164,7 @@
"Hide replies": "Ocultar las respuestas", "Hide replies": "Ocultar las respuestas",
"Show replies": "Mostrar las respuestas", "Show replies": "Mostrar las respuestas",
"Incorrect password": "Contraseña incorrecta", "Incorrect password": "Contraseña incorrecta",
"Quota exceeded, try again in a few hours": "Cuota excedida, pruebe otra vez en unas horas", "Quota exceeded, try again in a few hours": "Cuota excedida, prueba otra vez en unas horas",
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "No se puede iniciar sesión, asegúrese de que la autentificación de dos factores (autentificador o SMS) esté habilitada.", "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "No se puede iniciar sesión, asegúrese de que la autentificación de dos factores (autentificador o SMS) esté habilitada.",
"Invalid TFA code": "Código TFA no válido", "Invalid TFA code": "Código TFA no válido",
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Error de inicio de sesion. Puede deberse a que la autentificación de dos factores no está habilitada en su cuenta.", "Login failed. This may be because two-factor authentication is not turned on for your account.": "Error de inicio de sesion. Puede deberse a que la autentificación de dos factores no está habilitada en su cuenta.",
@ -176,7 +176,7 @@
"Wrong username or password": "Nombre o contraseña incorrecto", "Wrong username or password": "Nombre o contraseña incorrecto",
"Please sign in using 'Log in with Google'": "Inicie sesión con «Iniciar sesión con Google»", "Please sign in using 'Log in with Google'": "Inicie sesión con «Iniciar sesión con Google»",
"Password cannot be empty": "La contraseña no puede estar en blanco", "Password cannot be empty": "La contraseña no puede estar en blanco",
"Password cannot be longer than 55 characters": "La contraseña no puede tener más de 55 caracteres", "Password cannot be longer than 55 characters": "La contraseña no debe tener más de 55 caracteres",
"Please log in": "Inicie sesión, por favor", "Please log in": "Inicie sesión, por favor",
"Invidious Private Feed for `x`": "Fuente privada de Invidious para `x`", "Invidious Private Feed for `x`": "Fuente privada de Invidious para `x`",
"channel:`x`": "canal: `x`", "channel:`x`": "canal: `x`",
@ -198,7 +198,7 @@
"No such user": "Usuario no existe", "No such user": "Usuario no existe",
"Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo", "Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo",
"English": "Inglés", "English": "Inglés",
"English (auto-generated)": "Inglés (generados automáticamente)", "English (auto-generated)": "Inglés (generado automáticamente)",
"Afrikaans": "Afrikáans", "Afrikaans": "Afrikáans",
"Albanian": "Albanés", "Albanian": "Albanés",
"Amharic": "Amárico", "Amharic": "Amárico",
@ -324,50 +324,51 @@
"permalink": "enlace permanente", "permalink": "enlace permanente",
"`x` marked it with a ❤": "`x` lo ha marcado con un ❤", "`x` marked it with a ❤": "`x` lo ha marcado con un ❤",
"Audio mode": "Modo de audio", "Audio mode": "Modo de audio",
"Video mode": "Modo de vídeo", "Video mode": "Modo de video",
"channel_tab_videos_label": "Vídeos", "channel_tab_videos_label": "Videos",
"Playlists": "Listas de reproducción", "Playlists": "Listas de reproducción",
"channel_tab_community_label": "Comunidad", "channel_tab_community_label": "Comunidad",
"search_filters_sort_option_relevance": "relevancia", "search_filters_sort_option_relevance": "Relevancia",
"search_filters_sort_option_rating": "valoración", "search_filters_sort_option_rating": "Valoración",
"search_filters_sort_option_date": "fecha", "search_filters_sort_option_date": "Fecha de subida",
"search_filters_sort_option_views": "visualizaciones", "search_filters_sort_option_views": "Visualizaciones",
"search_filters_type_label": "content_type", "search_filters_type_label": "tipo de contenido",
"search_filters_duration_label": "duración", "search_filters_duration_label": "duración",
"search_filters_features_label": "funcionalidades", "search_filters_features_label": "funcionalidades",
"search_filters_sort_label": "ordenar", "search_filters_sort_label": "ordenar",
"search_filters_date_option_hour": "hora", "search_filters_date_option_hour": "Última hora",
"search_filters_date_option_today": "hoy", "search_filters_date_option_today": "Hoy",
"search_filters_date_option_week": "semana", "search_filters_date_option_week": "Esta semana",
"search_filters_date_option_month": "mes", "search_filters_date_option_month": "Este mes",
"search_filters_date_option_year": "año", "search_filters_date_option_year": "Este año",
"search_filters_type_option_video": "deo", "search_filters_type_option_video": "Video",
"search_filters_type_option_channel": "canal", "search_filters_type_option_channel": "Canal",
"search_filters_type_option_playlist": "lista de reproducción", "search_filters_type_option_playlist": "Lista de reproducción",
"search_filters_type_option_movie": "película", "search_filters_type_option_movie": "Película",
"search_filters_type_option_show": "programa", "search_filters_type_option_show": "Programa",
"search_filters_features_option_hd": "hd", "search_filters_features_option_hd": "HD",
"search_filters_features_option_subtitles": "subtítulos", "search_filters_features_option_subtitles": "Subtítulos",
"search_filters_features_option_c_commons": "creative_commons", "search_filters_features_option_c_commons": "Creative Commons",
"search_filters_features_option_three_d": "3d", "search_filters_features_option_three_d": "3D",
"search_filters_features_option_live": "directo", "search_filters_features_option_live": "En directo",
"search_filters_features_option_four_k": "4k", "search_filters_features_option_four_k": "4K",
"search_filters_features_option_location": "ubicación", "search_filters_features_option_location": "Ubicación",
"search_filters_features_option_hdr": "hdr", "search_filters_features_option_hdr": "HDR",
"Current version: ": "Versión actual: ", "Current version: ": "Versión actual: ",
"next_steps_error_message": "Después de lo cual debes intentar: ", "next_steps_error_message": "Después de lo cual debes intentar: ",
"next_steps_error_message_refresh": "Recargar la página", "next_steps_error_message_refresh": "Recargar la página",
"next_steps_error_message_go_to_youtube": "Ir a YouTube", "next_steps_error_message_go_to_youtube": "Ir a YouTube",
"search_filters_duration_option_short": "Corto (< 4 minutos)", "search_filters_duration_option_short": "Menos de 4 minutos",
"search_filters_duration_option_long": "Largo (> 20 minutos)", "search_filters_duration_option_medium": "De 4 a 20 minutos",
"search_filters_duration_option_long": "Más de 20 minutos",
"footer_documentation": "Documentación", "footer_documentation": "Documentación",
"footer_original_source_code": "Código fuente original", "footer_original_source_code": "Código fuente original",
"adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", "adminprefs_modified_source_code_url_label": "Enlace al repositorio de código fuente modificado",
"footer_source_code": "Código fuente", "footer_source_code": "Código fuente",
"footer_modfied_source_code": "Código fuente modificado", "footer_modfied_source_code": "Código fuente modificado",
"footer_donate_page": "Donar", "footer_donate_page": "Donar",
"preferences_region_label": "País del contenido: ", "preferences_region_label": "País del contenido: ",
"preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", "preferences_quality_dash_label": "Calidad de video DASH preferida: ",
"preferences_quality_option_hd720": "HD720", "preferences_quality_option_hd720": "HD720",
"preferences_quality_option_medium": "Intermedia", "preferences_quality_option_medium": "Intermedia",
"preferences_quality_dash_option_auto": "Automática", "preferences_quality_dash_option_auto": "Automática",
@ -376,7 +377,7 @@
"download_subtitles": "Subtítulos- `x` (.vtt)", "download_subtitles": "Subtítulos- `x` (.vtt)",
"user_created_playlists": "`x` listas de reproducción creadas", "user_created_playlists": "`x` listas de reproducción creadas",
"user_saved_playlists": "`x` listas de reproducción guardadas", "user_saved_playlists": "`x` listas de reproducción guardadas",
"Video unavailable": "Vídeo no disponible", "Video unavailable": "Video no disponible",
"videoinfo_youTube_embed_link": "Insertar", "videoinfo_youTube_embed_link": "Insertar",
"preferences_quality_dash_option_2160p": "2160p", "preferences_quality_dash_option_2160p": "2160p",
"preferences_quality_dash_option_4320p": "4320p", "preferences_quality_dash_option_4320p": "4320p",
@ -413,8 +414,8 @@
"generic_count_weeks_plural": "{{count}} semanas", "generic_count_weeks_plural": "{{count}} semanas",
"generic_playlists_count": "{{count}} lista de reproducción", "generic_playlists_count": "{{count}} lista de reproducción",
"generic_playlists_count_plural": "{{count}} listas de reproducción", "generic_playlists_count_plural": "{{count}} listas de reproducción",
"generic_videos_count": "{{count}} vídeo", "generic_videos_count": "{{count}} video",
"generic_videos_count_plural": "{{count}} vídeos", "generic_videos_count_plural": "{{count}} videos",
"generic_count_months": "{{count}} mes", "generic_count_months": "{{count}} mes",
"generic_count_months_plural": "{{count}} meses", "generic_count_months_plural": "{{count}} meses",
"comments_points_count": "{{count}} punto", "comments_points_count": "{{count}} punto",
@ -433,7 +434,7 @@
"crash_page_search_issue": "buscado <a href=\"`x`\">problemas existentes en GitHub</a>", "crash_page_search_issue": "buscado <a href=\"`x`\">problemas existentes en GitHub</a>",
"crash_page_you_found_a_bug": "¡Parece que has encontrado un error en Invidious!", "crash_page_you_found_a_bug": "¡Parece que has encontrado un error en Invidious!",
"crash_page_refresh": "probado a <a href=\"`x`\">recargar la página</a>", "crash_page_refresh": "probado a <a href=\"`x`\">recargar la página</a>",
"crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, <a href=\"`x`\">abre una nueva incidencia en GitHub</a> (preferiblemente en inglés) e incluye el siguiente texto en tu mensaje (NO traduzcas este texto):", "crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, <a href=\"`x`\">abre una nueva incidencia en GitHub</a> (preferiblemente en inglés) e incluye verbatim el siguiente texto en tu mensaje:",
"English (United States)": "Inglés (Estados Unidos)", "English (United States)": "Inglés (Estados Unidos)",
"Cantonese (Hong Kong)": "Cantonés (Hong Kong)", "Cantonese (Hong Kong)": "Cantonés (Hong Kong)",
"Dutch (auto-generated)": "Neerlandés (generados automáticamente)", "Dutch (auto-generated)": "Neerlandés (generados automáticamente)",
@ -461,16 +462,22 @@
"search_message_no_results": "No se han encontrado resultados.", "search_message_no_results": "No se han encontrado resultados.",
"search_message_change_filters_or_query": "Pruebe ampliar la consulta de búsqueda y/o a cambiar los filtros.", "search_message_change_filters_or_query": "Pruebe ampliar la consulta de búsqueda y/o a cambiar los filtros.",
"search_filters_title": "Filtros", "search_filters_title": "Filtros",
"search_filters_date_label": "Fecha de subida", "search_filters_date_label": "fecha de subida",
"search_filters_date_option_none": "Cualquier fecha", "search_filters_date_option_none": "Cualquier fecha",
"search_filters_type_option_all": "Cualquier tipo", "search_filters_type_option_all": "Cualquier tipo",
"search_filters_duration_option_none": "Cualquier duración", "search_filters_duration_option_none": "Cualquier duración",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"search_filters_apply_button": "Aplicar filtros seleccionados", "search_filters_apply_button": "Aplicar filtros",
"tokens_count": "{{count}} ficha", "tokens_count": "{{count}} ficha",
"tokens_count_plural": "{{count}} fichas", "tokens_count_plural": "{{count}} fichas",
"search_message_use_another_instance": " También puede <a href=\"`x`\">buscar en otra instancia</a>.", "search_message_use_another_instance": " También puede <a href=\"`x`\">buscar en otra instancia</a>.",
"search_filters_duration_option_medium": "Medio (4 - 20 minutes)",
"Popular enabled: ": "¿Habilitar la sección popular? ", "Popular enabled: ": "¿Habilitar la sección popular? ",
"error_video_not_in_playlist": "El vídeo solicitado no existe en esta lista de reproducción. <a href=\"`x`\">Haga clic aquí para acceder a la página de inicio de la lista de reproducción.</a>" "error_video_not_in_playlist": "El video que solicitaste no existe en esta lista de reproducción. <a href=\"`x`\">Haz clic aquí para acceder a la página de inicio de la lista de reproducción.</a>",
"channel_tab_streams_label": "Directos",
"channel_tab_channels_label": "Canales",
"channel_tab_shorts_label": "Cortos",
"channel_tab_playlists_label": "Listas de reproducción",
"Music in this video": "Música en este video",
"Artist: ": "Artista: ",
"Album: ": "Álbum: "
} }

View File

@ -408,9 +408,9 @@
"preferences_region_label": "کشور محتوا: ", "preferences_region_label": "کشور محتوا: ",
"footer_documentation": "مستندات", "footer_documentation": "مستندات",
"footer_original_source_code": "کد منبع اصلی", "footer_original_source_code": "کد منبع اصلی",
"search_filters_duration_option_long": "بلند (> 20 دقیقه)", "search_filters_duration_option_long": "بلند (> ۲۰ دقیقه)",
"adminprefs_modified_source_code_url_label": "URL مخزن کد منبع ویریش شده", "adminprefs_modified_source_code_url_label": "URL مخزن کد منبع ویریش شده",
"search_filters_duration_option_short": "کوتاه (< 4 دقیقه)", "search_filters_duration_option_short": "کوتاه (< ۴ دقیقه)",
"search_filters_title": "پالایه", "search_filters_title": "پالایه",
"Chinese (Hong Kong)": "چینی (هنگ‌کنگ)", "Chinese (Hong Kong)": "چینی (هنگ‌کنگ)",
"Dutch (auto-generated)": "هلندی (تولید خودکار)", "Dutch (auto-generated)": "هلندی (تولید خودکار)",
@ -424,5 +424,26 @@
"search_message_no_results": "نتیجه‌ای یافت نشد.", "search_message_no_results": "نتیجه‌ای یافت نشد.",
"search_message_change_filters_or_query": "سعی کنید جست‌و‌جوی خود را وسیع‌تر کنید و/یا فیلترها را تغییر دهید.", "search_message_change_filters_or_query": "سعی کنید جست‌و‌جوی خود را وسیع‌تر کنید و/یا فیلترها را تغییر دهید.",
"Chinese (China)": "چینی (چین)", "Chinese (China)": "چینی (چین)",
"German (auto-generated)": "آلمانی (تولید خودکار)" "German (auto-generated)": "آلمانی (تولید خودکار)",
"Japanese (auto-generated)": "ژاپنی (تولید خودکار)",
"Korean (auto-generated)": "کره‌ای (تولید خودکار)",
"Portuguese (Brazil)": "پرتغالی (برزیل)",
"search_filters_apply_button": "اعمال فیلترهای انتخاب شده",
"Italian (auto-generated)": "ایتالیایی (تولید خودکار)",
"Vietnamese (auto-generated)": "ویتنامی (تولید خودکار)",
"search_filters_type_option_all": "هر نوعی",
"search_filters_duration_option_none": "هر مدت زمانی",
"search_filters_date_label": "تاریخ بارگذاری",
"search_filters_date_option_none": "هر تاریخی",
"user_created_playlists": "`x` فهرست پخش ایجاد شد",
"Interlingue": "سرخپوستی",
"Russian (auto-generated)": "روسی (تولید خودکار)",
"Spanish (auto-generated)": "اسپانیایی (تولید خودکار)",
"search_filters_duration_option_medium": "متوسط (۴ تا ۲۰ دقیقه)",
"Portuguese (auto-generated)": "پرتغالی (تولید خودکار)",
"Cantonese (Hong Kong)": "کانتونی (هنگ کنگ)",
"Spanish (Spain)": "اسپانیایی (اسپانیا)",
"Turkish (auto-generated)": "ترکی (تولید خودکار)",
"search_filters_features_option_vr180": "VR180",
"Spanish (Mexico)": "اسپانیایی (مکزیک)"
} }

View File

@ -472,5 +472,9 @@
"search_filters_date_label": "Date d'ajout", "search_filters_date_label": "Date d'ajout",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"search_filters_duration_option_none": "Toutes les durées", "search_filters_duration_option_none": "Toutes les durées",
"error_video_not_in_playlist": "La vidéo demandée n'existe pas dans cette liste de lecture. <a href=\"`x`\">Cliquez ici pour retourner à la liste de lecture.</a>" "error_video_not_in_playlist": "La vidéo demandée n'existe pas dans cette liste de lecture. <a href=\"`x`\">Cliquez ici pour retourner à la liste de lecture.</a>",
"channel_tab_shorts_label": "Clips",
"channel_tab_streams_label": "En direct",
"channel_tab_playlists_label": "Listes de lecture",
"channel_tab_channels_label": "Chaînes"
} }

View File

@ -470,5 +470,14 @@
"crash_page_switch_instance": "<a href=\"`x`\">किसी दूसरे उदाहरण का इस्तेमाल करें</a>", "crash_page_switch_instance": "<a href=\"`x`\">किसी दूसरे उदाहरण का इस्तेमाल करें</a>",
"crash_page_read_the_faq": "<a href=\"`x`\">अक्सर पूछे जाने वाले प्रश्न (FAQ)</a> पढ़ें", "crash_page_read_the_faq": "<a href=\"`x`\">अक्सर पूछे जाने वाले प्रश्न (FAQ)</a> पढ़ें",
"crash_page_refresh": "<a href=\"`x`\">पृष्ठ को एक बार साफ़ करें</a>", "crash_page_refresh": "<a href=\"`x`\">पृष्ठ को एक बार साफ़ करें</a>",
"crash_page_search_issue": "<a href=\"`x`\">GitHub पर मौजूदा मुद्दे</a> ढूँढ़ें" "crash_page_search_issue": "<a href=\"`x`\">GitHub पर मौजूदा मुद्दे</a> ढूँढ़ें",
"Popular enabled: ": "लोकप्रिय सक्षम: ",
"Artist: ": "कलाकार: ",
"Music in this video": "इस वीडियो में संगीत",
"Album: ": "एल्बम: ",
"error_video_not_in_playlist": "अनुरोधित वीडियो इस प्लेलिस्ट में मौजूद नहीं है। <a href=\"`x`\">प्लेलिस्ट के मुखपृष्ठ पर जाने के लिए यहाँ क्लिक करें।</a>",
"channel_tab_shorts_label": "शॉर्ट्स",
"channel_tab_streams_label": "लाइवस्ट्रीम्स",
"channel_tab_playlists_label": "प्लेलिस्ट्स",
"channel_tab_channels_label": "चैनल्स"
} }

View File

@ -7,8 +7,8 @@
"View playlist on YouTube": "Prikaži zbirku na YouTubeu", "View playlist on YouTube": "Prikaži zbirku na YouTubeu",
"newest": "najnovije", "newest": "najnovije",
"oldest": "najstarije", "oldest": "najstarije",
"popular": "popularni", "popular": "popularne",
"last": "zadnji", "last": "zadnje",
"Next page": "Sljedeća stranica", "Next page": "Sljedeća stranica",
"Previous page": "Prethodna stranica", "Previous page": "Prethodna stranica",
"Clear watch history?": "Izbrisati povijest gledanja?", "Clear watch history?": "Izbrisati povijest gledanja?",
@ -43,9 +43,9 @@
"Time (h:mm:ss):": "Vrijeme (h:mm:ss):", "Time (h:mm:ss):": "Vrijeme (h:mm:ss):",
"Text CAPTCHA": "Tekstualni CAPTCHA", "Text CAPTCHA": "Tekstualni CAPTCHA",
"Image CAPTCHA": "Slikovni CAPTCHA", "Image CAPTCHA": "Slikovni CAPTCHA",
"Sign In": "Prijava", "Sign In": "Prijavi se",
"Register": "Registriraj se", "Register": "Registriraj se",
"E-mail": "E-mail", "E-mail": "E-mail adresa",
"Google verification code": "Googleov potvrdni kod", "Google verification code": "Googleov potvrdni kod",
"Preferences": "Postavke", "Preferences": "Postavke",
"preferences_category_player": "Postavke playera", "preferences_category_player": "Postavke playera",
@ -359,13 +359,13 @@
"next_steps_error_message_refresh": "Aktualiziraj stranicu", "next_steps_error_message_refresh": "Aktualiziraj stranicu",
"next_steps_error_message_go_to_youtube": "Idi na YouTube", "next_steps_error_message_go_to_youtube": "Idi na YouTube",
"footer_donate_page": "Doniraj", "footer_donate_page": "Doniraj",
"adminprefs_modified_source_code_url_label": "URL do repozitorija izmijenjenog izvornog koda", "adminprefs_modified_source_code_url_label": "URL do repozitorija prilagođenog izvornog koda",
"search_filters_duration_option_short": "Kratko (< 4 minute)", "search_filters_duration_option_short": "Kratko (< 4 minute)",
"search_filters_duration_option_long": "Dugo (> 20 minute)", "search_filters_duration_option_long": "Dugo (> 20 minute)",
"footer_source_code": "Izvorni kod", "footer_source_code": "Izvorni kod",
"footer_modfied_source_code": "Izmijenjeni izvorni kod", "footer_modfied_source_code": "Prilagođen izvorni kod",
"footer_documentation": "Dokumentacija", "footer_documentation": "Dokumentacija",
"footer_original_source_code": "Izvoran izvorni kod", "footer_original_source_code": "Prvobitan izvorni kod",
"preferences_region_label": "Zemlja sadržaja: ", "preferences_region_label": "Zemlja sadržaja: ",
"preferences_quality_dash_label": "Preferirana DASH videokvaliteta: ", "preferences_quality_dash_label": "Preferirana DASH videokvaliteta: ",
"preferences_quality_option_dash": "DASH (adaptativna kvaliteta)", "preferences_quality_option_dash": "DASH (adaptativna kvaliteta)",
@ -488,5 +488,12 @@
"search_filters_apply_button": "Primijeni odabrane filtre", "search_filters_apply_button": "Primijeni odabrane filtre",
"search_filters_type_option_all": "Bilo koja vrsta", "search_filters_type_option_all": "Bilo koja vrsta",
"Popular enabled: ": "Popularni aktivirani: ", "Popular enabled: ": "Popularni aktivirani: ",
"error_video_not_in_playlist": "Traženi video ne postoji u ovoj zbirci. <a href=\"`x`\">Pritisni ovdje za početnu stranicu zbirke.</a>" "error_video_not_in_playlist": "Traženi video ne postoji u ovoj zbirci. <a href=\"`x`\">Pritisni ovdje za početnu stranicu zbirke.</a>",
"channel_tab_streams_label": "Prijenosi uživo",
"channel_tab_playlists_label": "Zbirke",
"channel_tab_channels_label": "Kanali",
"channel_tab_shorts_label": "Kratka videa",
"Music in this video": "Glazba u ovom videu",
"Album: ": "Album: ",
"Artist: ": "Izvođač: "
} }

View File

@ -346,7 +346,6 @@
"Video mode": "Modalità video", "Video mode": "Modalità video",
"channel_tab_videos_label": "Video", "channel_tab_videos_label": "Video",
"Playlists": "Playlist", "Playlists": "Playlist",
"channel_tab_community_label": "Comunità",
"search_filters_sort_option_relevance": "Pertinenza", "search_filters_sort_option_relevance": "Pertinenza",
"search_filters_sort_option_rating": "Valutazione", "search_filters_sort_option_rating": "Valutazione",
"search_filters_sort_option_date": "Data di caricamento", "search_filters_sort_option_date": "Data di caricamento",
@ -472,5 +471,13 @@
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"search_filters_apply_button": "Applica filtri selezionati", "search_filters_apply_button": "Applica filtri selezionati",
"crash_page_refresh": "provato a <a href=\"`x`\">ricaricare la pagina</a>", "crash_page_refresh": "provato a <a href=\"`x`\">ricaricare la pagina</a>",
"error_video_not_in_playlist": "Il video richiesto non esiste in questa playlist. <a href=\"`x`\">Fai clic qui per la pagina iniziale della playlist.</a>" "error_video_not_in_playlist": "Il video richiesto non esiste in questa playlist. <a href=\"`x`\">Fai clic qui per la pagina iniziale della playlist.</a>",
"channel_tab_shorts_label": "Short",
"channel_tab_playlists_label": "Playlist",
"channel_tab_channels_label": "Canali",
"channel_tab_streams_label": "Livestream",
"channel_tab_community_label": "Comunità",
"Music in this video": "Musica in questo video",
"Artist: ": "Artista: ",
"Album: ": "Album: "
} }

View File

@ -5,7 +5,7 @@
"generic_subscribers_count_0": "{{count}} 人の登録者", "generic_subscribers_count_0": "{{count}} 人の登録者",
"generic_subscriptions_count_0": "{{count}} 個の登録チャンネル", "generic_subscriptions_count_0": "{{count}} 個の登録チャンネル",
"LIVE": "ライブ", "LIVE": "ライブ",
"Shared `x` ago": "`x`前に共有", "Shared `x` ago": "`x`前に公開",
"Unsubscribe": "登録解除", "Unsubscribe": "登録解除",
"Subscribe": "登録", "Subscribe": "登録",
"View channel on YouTube": "YouTube でチャンネルを見る", "View channel on YouTube": "YouTube でチャンネルを見る",
@ -53,34 +53,34 @@
"E-mail": "メールアドレス", "E-mail": "メールアドレス",
"Google verification code": "Google 認証コード", "Google verification code": "Google 認証コード",
"Preferences": "設定", "Preferences": "設定",
"preferences_category_player": "プレイヤー設定", "preferences_category_player": "プレイヤー設定",
"preferences_video_loop_label": "常にループ: ", "preferences_video_loop_label": "常にループ: ",
"preferences_autoplay_label": "自動再生: ", "preferences_autoplay_label": "自動再生: ",
"preferences_continue_label": "デフォルトで次を再生: ", "preferences_continue_label": "の動画を再生: ",
"preferences_continue_autoplay_label": "次の動画を自動再生: ", "preferences_continue_autoplay_label": "次の動画を自動再生: ",
"preferences_listen_label": "デフォルトでオーディオモードを使用: ", "preferences_listen_label": "デフォルトで音声モードを使用: ",
"preferences_local_label": "動画をプロキシーに通す: ", "preferences_local_label": "動画視聴にプロキシーを経由: ",
"preferences_speed_label": "デフォルトの再生速度: ", "preferences_speed_label": "標準の再生速度: ",
"preferences_quality_label": "優先する画質: ", "preferences_quality_label": "優先する画質: ",
"preferences_volume_label": "プレイヤーの音量: ", "preferences_volume_label": "プレイヤーの音量: ",
"preferences_comments_label": "デフォルトのコメント: ", "preferences_comments_label": "デフォルトのコメント: ",
"youtube": "YouTube", "youtube": "YouTube",
"reddit": "Reddit", "reddit": "Reddit",
"preferences_captions_label": "デフォルトの字幕: ", "preferences_captions_label": "優先する字幕: ",
"Fallback captions: ": "フォールバック時の字幕: ", "Fallback captions: ": "フォールバック時の字幕: ",
"preferences_related_videos_label": "関連動画を表示: ", "preferences_related_videos_label": "関連動画を表示: ",
"preferences_annotations_label": "デフォルトでアノテーションを表示: ", "preferences_annotations_label": "デフォルトでアノテーションを表示: ",
"preferences_extend_desc_label": "動画の説明文を自動的に拡張: ", "preferences_extend_desc_label": "動画の説明文を自動的に拡張: ",
"preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ", "preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ",
"preferences_category_visual": "外観設定", "preferences_category_visual": "外観設定",
"preferences_player_style_label": "プレイヤースタイル: ", "preferences_player_style_label": "プレイヤースタイル: ",
"Dark mode: ": "ダークモード: ", "Dark mode: ": "ダークモード: ",
"preferences_dark_mode_label": "テーマ: ", "preferences_dark_mode_label": "テーマ: ",
"dark": "ダーク", "dark": "ダーク",
"light": "ライト", "light": "ライト",
"preferences_thin_mode_label": "最小モード: ", "preferences_thin_mode_label": "最小モード: ",
"preferences_category_misc": "設定", "preferences_category_misc": "ほかの設定",
"preferences_automatic_instance_redirect_label": "自動的なインスタンスの移転redirect.invidious.ioにフォールバック ", "preferences_automatic_instance_redirect_label": "インスタンスの自動転送 (redirect.invidious.ioにフォールバック): ",
"preferences_category_subscription": "登録チャンネル設定", "preferences_category_subscription": "登録チャンネル設定",
"preferences_annotations_subscribed_label": "デフォルトで登録チャンネルのアノテーションを表示しますか? ", "preferences_annotations_subscribed_label": "デフォルトで登録チャンネルのアノテーションを表示しますか? ",
"Redirect homepage to feed: ": "ホームからフィードにリダイレクト: ", "Redirect homepage to feed: ": "ホームからフィードにリダイレクト: ",
@ -108,7 +108,7 @@
"Watch history": "再生履歴", "Watch history": "再生履歴",
"Delete account": "アカウントを削除", "Delete account": "アカウントを削除",
"preferences_category_admin": "管理者設定", "preferences_category_admin": "管理者設定",
"preferences_default_home_label": "デフォルトのホーム: ", "preferences_default_home_label": "ホームに表示するページ: ",
"preferences_feed_menu_label": "フィードメニュー: ", "preferences_feed_menu_label": "フィードメニュー: ",
"preferences_show_nick_label": "ニックネームを一番上に表示する: ", "preferences_show_nick_label": "ニックネームを一番上に表示する: ",
"Top enabled: ": "トップページを有効化: ", "Top enabled: ": "トップページを有効化: ",
@ -117,8 +117,8 @@
"Registration enabled: ": "登録を有効化: ", "Registration enabled: ": "登録を有効化: ",
"Report statistics: ": "統計を報告: ", "Report statistics: ": "統計を報告: ",
"Save preferences": "設定を保存", "Save preferences": "設定を保存",
"Subscription manager": "登録チャンネルマネージャー", "Subscription manager": "登録チャンネルの管理",
"Token manager": "トークンマネージャー", "Token manager": "トークンの管理",
"Token": "トークン", "Token": "トークン",
"tokens_count_0": "{{count}} 個のトークン", "tokens_count_0": "{{count}} 個のトークン",
"Import/export": "インポート/エクスポート", "Import/export": "インポート/エクスポート",
@ -128,7 +128,7 @@
"subscriptions_unseen_notifs_count_0": "{{count}} 個の未読通知", "subscriptions_unseen_notifs_count_0": "{{count}} 個の未読通知",
"search": "検索", "search": "検索",
"Log out": "ログアウト", "Log out": "ログアウト",
"Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開されています。", "Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開",
"Source available here.": "ソースはここで閲覧可能です。", "Source available here.": "ソースはここで閲覧可能です。",
"View JavaScript license information.": "JavaScript ライセンス情報", "View JavaScript license information.": "JavaScript ライセンス情報",
"View privacy policy.": "プライバシーポリシー", "View privacy policy.": "プライバシーポリシー",
@ -136,28 +136,28 @@
"Public": "公開", "Public": "公開",
"Unlisted": "限定公開", "Unlisted": "限定公開",
"Private": "非公開", "Private": "非公開",
"View all playlists": "再生リストをすべて見る", "View all playlists": "すべての再生リストを表示",
"Updated `x` ago": "`x`前に更新", "Updated `x` ago": "`x`前に更新",
"Delete playlist `x`?": "再生リスト `x` を削除しますか?", "Delete playlist `x`?": "再生リスト `x` を削除しますか?",
"Delete playlist": "再生リストを削除", "Delete playlist": "再生リストを削除",
"Create playlist": "再生リストを作成", "Create playlist": "再生リストを作成",
"Title": "タイトル", "Title": "タイトル",
"Playlist privacy": "再生リストのプライバシー", "Playlist privacy": "再生リストの公開設定",
"Editing playlist `x`": "再生リスト `x` を編集中", "Editing playlist `x`": "再生リスト `x` を編集中",
"Show more": "表示を増やす", "Show more": "もっと見る",
"Show less": "表示を減らす", "Show less": "表示を少なく",
"Watch on YouTube": "YouTube で視聴", "Watch on YouTube": "YouTube で視聴",
"Switch Invidious Instance": "Invidiousインスタンスの変更", "Switch Invidious Instance": "Invidious インスタンスの変更",
"Hide annotations": "アノテーションを隠す", "Hide annotations": "アノテーションを隠す",
"Show annotations": "アノテーションを表示", "Show annotations": "アノテーションを表示",
"Genre: ": "ジャンル: ", "Genre: ": "ジャンル: ",
"License: ": "ライセンス: ", "License: ": "ライセンス: ",
"Family friendly? ": "家族向け: ", "Family friendly? ": "家族向け: ",
"Wilson score: ": "ウィルソンスコア: ", "Wilson score: ": "ウィルソン得点区間: ",
"Engagement: ": "エンゲージメント: ", "Engagement: ": "エンゲージメント: ",
"Whitelisted regions: ": "ホワイトリストの地域: ", "Whitelisted regions: ": "ホワイトリストの地域: ",
"Blacklisted regions: ": "ブラックリストの地域: ", "Blacklisted regions: ": "ブラックリストの地域: ",
"Shared `x`": "`x`に共有", "Shared `x`": "公開日 `x`",
"Premieres in `x`": "`x`後にプレミア公開", "Premieres in `x`": "`x`後にプレミア公開",
"Premieres `x`": "`x`にプレミア公開", "Premieres `x`": "`x`にプレミア公開",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "やあ!君は JavaScript を無効にしているのかな?ここをクリックしてコメントを見れるけど、読み込みには少し時間がかかることがあるのを覚えておいてね。", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "やあ!君は JavaScript を無効にしているのかな?ここをクリックしてコメントを見れるけど、読み込みには少し時間がかかることがあるのを覚えておいてね。",
@ -181,31 +181,31 @@
"User ID is a required field": "ユーザー ID は必須項目です", "User ID is a required field": "ユーザー ID は必須項目です",
"Password is a required field": "パスワードは必須項目です", "Password is a required field": "パスワードは必須項目です",
"Wrong username or password": "ユーザー名またはパスワードが間違っています", "Wrong username or password": "ユーザー名またはパスワードが間違っています",
"Please sign in using 'Log in with Google'": "'Google でログイン' を使用してログインしてください", "Please sign in using 'Log in with Google'": "「Google でログイン」を使用してログインしてください",
"Password cannot be empty": "パスワードを空にすることはできません", "Password cannot be empty": "パスワードは空にできません",
"Password cannot be longer than 55 characters": "パスワードは55文字より長くできません", "Password cannot be longer than 55 characters": "パスワードは55文字より長くできません",
"Please log in": "ログインしてください", "Please log in": "ログインしてください",
"Invidious Private Feed for `x`": "`x` の Invidious プライベートフィード", "Invidious Private Feed for `x`": "`x` 個人の Invidious によるフィード",
"channel:`x`": "チャンネル:`x`", "channel:`x`": "チャンネル:`x`",
"Deleted or invalid channel": "削除済みまたは無効なチャンネルです", "Deleted or invalid channel": "削除済みまたは無効なチャンネルです",
"This channel does not exist.": "このチャンネルは存在しません。", "This channel does not exist.": "このチャンネルは存在しません。",
"Could not get channel info.": "チャンネル情報を取得できませんでした。", "Could not get channel info.": "チャンネル情報を取得できませんでした。",
"Could not fetch comments": "コメントを取得できませんでした", "Could not fetch comments": "コメントを取得できませんでした",
"comments_view_x_replies_0": "{{count}} 件の返信を見る", "comments_view_x_replies_0": "{{count}}件の返信を表示",
"`x` ago": "`x`前", "`x` ago": "`x`前",
"Load more": "もっと読み込む", "Load more": "もっと見る",
"comments_points_count_0": "{{count}} ポイント", "comments_points_count_0": "{{count}}",
"Could not create mix.": "ミックスを作成できませんでした。", "Could not create mix.": "ミックスを作成できませんでした。",
"Empty playlist": "空の再生リスト", "Empty playlist": "空の再生リスト",
"Not a playlist.": "再生リストではありません。", "Not a playlist.": "再生リストではありません。",
"Playlist does not exist.": "再生リストが存在しません。", "Playlist does not exist.": "再生リストが存在しません。",
"Could not pull trending pages.": "急上昇ページを取得できませんでした。", "Could not pull trending pages.": "急上昇ページを取得できませんでした。",
"Hidden field \"challenge\" is a required field": "非表示項目 \"challenge\" は必須項目です", "Hidden field \"challenge\" is a required field": "非表示項目 challenge は必須項目です",
"Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です", "Hidden field \"token\" is a required field": "非表示項目 token は必須項目です",
"Erroneous challenge": "チャレンジが間違っています", "Erroneous challenge": "チャレンジが間違っています",
"Erroneous token": "トークンが間違っています", "Erroneous token": "トークンが間違っています",
"No such user": "ユーザーが存在しません", "No such user": "ユーザーが存在しません",
"Token is expired, please try again": "トークンが期限切れです。再度試しください", "Token is expired, please try again": "トークンが期限切れです。再度試しください",
"English": "英語", "English": "英語",
"English (auto-generated)": "英語 (自動生成)", "English (auto-generated)": "英語 (自動生成)",
"Afrikaans": "アフリカーンス語", "Afrikaans": "アフリカーンス語",
@ -313,7 +313,7 @@
"Yoruba": "ヨルバ語", "Yoruba": "ヨルバ語",
"Zulu": "ズール語", "Zulu": "ズール語",
"generic_count_years_0": "{{count}}年", "generic_count_years_0": "{{count}}年",
"generic_count_months_0": "{{count}}月", "generic_count_months_0": "{{count}}月",
"generic_count_weeks_0": "{{count}}週", "generic_count_weeks_0": "{{count}}週",
"generic_count_days_0": "{{count}}日", "generic_count_days_0": "{{count}}日",
"generic_count_hours_0": "{{count}}時間", "generic_count_hours_0": "{{count}}時間",
@ -338,21 +338,21 @@
"(edited)": "(編集済み)", "(edited)": "(編集済み)",
"YouTube comment permalink": "YouTube コメントのパーマリンク", "YouTube comment permalink": "YouTube コメントのパーマリンク",
"permalink": "パーマリンク", "permalink": "パーマリンク",
"`x` marked it with a ❤": "`x` が❤を込めてマークしました", "`x` marked it with a ❤": "`x` が❤を送りました",
"Audio mode": "オーディオモード", "Audio mode": "音声モード",
"Video mode": "ビデオモード", "Video mode": "動画モード",
"channel_tab_videos_label": "動画", "channel_tab_videos_label": "動画",
"Playlists": "プレイリスト", "Playlists": "再生リスト",
"channel_tab_community_label": "コミュニティ", "channel_tab_community_label": "コミュニティ",
"search_filters_sort_option_relevance": "関連", "search_filters_sort_option_relevance": "関連",
"search_filters_sort_option_rating": "評価", "search_filters_sort_option_rating": "評価",
"search_filters_sort_option_date": "時刻", "search_filters_sort_option_date": "アップロード日",
"search_filters_sort_option_views": "再生回数", "search_filters_sort_option_views": "再生回数",
"search_filters_type_label": "コンテンツの種類", "search_filters_type_label": "種類",
"search_filters_duration_label": "再生時間", "search_filters_duration_label": "再生時間",
"search_filters_features_label": "機能", "search_filters_features_label": "特徴",
"search_filters_sort_label": "順番", "search_filters_sort_label": "順番",
"search_filters_date_option_hour": "1時間前", "search_filters_date_option_hour": "1時間以内",
"search_filters_date_option_today": "今日", "search_filters_date_option_today": "今日",
"search_filters_date_option_week": "今週", "search_filters_date_option_week": "今週",
"search_filters_date_option_month": "今月", "search_filters_date_option_month": "今月",
@ -366,7 +366,7 @@
"search_filters_features_option_subtitles": "字幕", "search_filters_features_option_subtitles": "字幕",
"search_filters_features_option_c_commons": "クリエイティブ・コモンズ", "search_filters_features_option_c_commons": "クリエイティブ・コモンズ",
"search_filters_features_option_three_d": "3D", "search_filters_features_option_three_d": "3D",
"search_filters_features_option_live": "生配信", "search_filters_features_option_live": "ライブ",
"search_filters_features_option_four_k": "4K", "search_filters_features_option_four_k": "4K",
"search_filters_features_option_location": "場所", "search_filters_features_option_location": "場所",
"search_filters_features_option_hdr": "HDR", "search_filters_features_option_hdr": "HDR",
@ -377,9 +377,9 @@
"search_filters_duration_option_short": "4 分未満", "search_filters_duration_option_short": "4 分未満",
"footer_documentation": "文書", "footer_documentation": "文書",
"footer_source_code": "ソースコード", "footer_source_code": "ソースコード",
"footer_original_source_code": "ソースコード(元)", "footer_original_source_code": "元のソースコード",
"footer_modfied_source_code": "ソースコード(編集)", "footer_modfied_source_code": "改変して使用",
"adminprefs_modified_source_code_url_label": "編集したソースコードのレポジトリーURL", "adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL",
"search_filters_duration_option_long": "20 分以上", "search_filters_duration_option_long": "20 分以上",
"preferences_region_label": "地域: ", "preferences_region_label": "地域: ",
"footer_donate_page": "寄付する", "footer_donate_page": "寄付する",
@ -406,10 +406,10 @@
"preferences_quality_option_dash": "DASH (適応品質)", "preferences_quality_option_dash": "DASH (適応品質)",
"preferences_quality_dash_option_worst": "最悪", "preferences_quality_dash_option_worst": "最悪",
"preferences_quality_dash_option_best": "最高", "preferences_quality_dash_option_best": "最高",
"videoinfo_started_streaming_x_ago": "`x`前に配信を開始", "videoinfo_started_streaming_x_ago": "`x`前に配信を開始",
"videoinfo_watch_on_youTube": "YouTube上で見る", "videoinfo_watch_on_youTube": "YouTube上で見る",
"user_created_playlists": "`x`が作成したプレイリスト", "user_created_playlists": "`x`個の作成した再生リスト",
"Video unavailable": "ビデオは利用できません", "Video unavailable": "動画は利用できません",
"Chinese": "中国語", "Chinese": "中国語",
"Chinese (Taiwan)": "中国語 (台湾)", "Chinese (Taiwan)": "中国語 (台湾)",
"Korean (auto-generated)": "韓国語 (自動生成)", "Korean (auto-generated)": "韓国語 (自動生成)",
@ -434,24 +434,34 @@
"Vietnamese (auto-generated)": "ベトナム語 (自動生成)", "Vietnamese (auto-generated)": "ベトナム語 (自動生成)",
"search_filters_title": "フィルタ", "search_filters_title": "フィルタ",
"search_filters_features_option_three_sixty": "360°", "search_filters_features_option_three_sixty": "360°",
"search_message_change_filters_or_query": "別のキーワードを試してみるか、検索フィルタを削除してください", "search_message_change_filters_or_query": "別の検索語句を試したり、検索フィルタを変更してください。",
"search_message_no_results": "一致する検索結果はありませんでした", "search_message_no_results": "一致する検索結果はありません",
"English (United States)": "英語 (アメリカ)", "English (United States)": "英語 (アメリカ)",
"search_filters_date_label": "アップロード日", "search_filters_date_label": "アップロード日",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"crash_page_switch_instance": "<a href=\"`x`\">別のインスタンスを使用</a>しようとしました", "crash_page_switch_instance": "<a href=\"`x`\">別のインスタンスを使用</a>を試す",
"crash_page_read_the_faq": "<a href=\"`x`\">よくある質問 (FAQ)</a> を読む", "crash_page_read_the_faq": "<a href=\"`x`\">よくある質問 (FAQ)</a> を読む",
"Popular enabled: ": "人気動画を有効化 ", "Popular enabled: ": "人気動画を有効化 ",
"search_message_use_another_instance": " <a href=\"`x`\">別のインスタンスで検索</a>することもできます。", "search_message_use_another_instance": " <a href=\"`x`\">別のインスタンス検索</a>できます。",
"search_filters_apply_button": "選択したフィルターを適用", "search_filters_apply_button": "選択したフィルターを適用",
"user_saved_playlists": "`x` 個の保存済みプレイリスト", "user_saved_playlists": "`x` 個の保存した再生リスト",
"crash_page_you_found_a_bug": "Invidious でバグを見つけたようです。", "crash_page_you_found_a_bug": "Invidious でバグを見つけたようです。",
"crash_page_refresh": "<a href=\"`x`\">ページを更新</a>しようとしました", "crash_page_refresh": "<a href=\"`x`\">ページを更新</a>を試す",
"preferences_watch_history_label": "視聴履歴を有効化 ", "preferences_watch_history_label": "再生履歴を有効化 ",
"search_filters_date_option_none": "任意の日付", "search_filters_date_option_none": "すべて",
"search_filters_type_option_all": "いかなるタイプ", "search_filters_type_option_all": "すべての種類",
"search_filters_duration_option_none": "任意の期間", "search_filters_duration_option_none": "すべての長さ",
"search_filters_duration_option_medium": "ミディアム (4 20 分)", "search_filters_duration_option_medium": "4 20 分",
"preferences_save_player_pos_label": "再生位置を保存: ", "preferences_save_player_pos_label": "再生位置を保存: ",
"crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。" "crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。",
"crash_page_report_issue": "上記が助けにならないなら、<a href=\"`x`\">GitHub</a> に新しい issue を作成し(英語が好ましい)、メッセージに次のテキストを含めてください(テキストは翻訳しない)。",
"crash_page_search_issue": "<a href=\"`x`\">GitHub の既存の問題 (issue)</a> を検索",
"channel_tab_streams_label": "ライブ",
"channel_tab_playlists_label": "再生リスト",
"error_video_not_in_playlist": "要求された動画はこの再生リスト内に存在しません。<a href=\"`x`\">再生リストのホームへ。</a>",
"channel_tab_shorts_label": "ショート",
"channel_tab_channels_label": "チャンネル",
"Music in this video": "この動画の音楽",
"Artist: ": "アーティスト: ",
"Album: ": "アルバム: "
} }

View File

@ -11,7 +11,7 @@
"preferences_dark_mode_label": "테마: ", "preferences_dark_mode_label": "테마: ",
"Dark mode: ": "다크 모드: ", "Dark mode: ": "다크 모드: ",
"preferences_player_style_label": "플레이어 스타일: ", "preferences_player_style_label": "플레이어 스타일: ",
"preferences_category_visual": "시각 설정", "preferences_category_visual": "환경 설정",
"preferences_vr_mode_label": "VR 영상 활성화(WebGL 필요): ", "preferences_vr_mode_label": "VR 영상 활성화(WebGL 필요): ",
"preferences_extend_desc_label": "자동으로 비디오 설명을 확장: ", "preferences_extend_desc_label": "자동으로 비디오 설명을 확장: ",
"preferences_annotations_label": "기본으로 주석 표시: ", "preferences_annotations_label": "기본으로 주석 표시: ",
@ -150,7 +150,7 @@
"Subscription manager": "구독 관리자", "Subscription manager": "구독 관리자",
"Save preferences": "설정 저장", "Save preferences": "설정 저장",
"Report statistics: ": "통계 보고: ", "Report statistics: ": "통계 보고: ",
"Registration enabled: ": "등록 활성화: ", "Registration enabled: ": "회원가입 활성화: ",
"Login enabled: ": "로그인 활성화: ", "Login enabled: ": "로그인 활성화: ",
"CAPTCHA enabled: ": "캡차 활성화: ", "CAPTCHA enabled: ": "캡차 활성화: ",
"Top enabled: ": "Top 활성화: ", "Top enabled: ": "Top 활성화: ",
@ -187,8 +187,8 @@
"Polish": "폴란드어", "Polish": "폴란드어",
"Persian": "페르시아어", "Persian": "페르시아어",
"Pashto": "파슈토어", "Pashto": "파슈토어",
"Nyanja": "체와어", "Nyanja": "냔자어",
"Norwegian Bokmål": "보크몰", "Norwegian Bokmål": "노르웨이 부크몰어",
"Nepali": "네팔어", "Nepali": "네팔어",
"Mongolian": "몽골어", "Mongolian": "몽골어",
"Marathi": "마라티어", "Marathi": "마라티어",
@ -442,7 +442,7 @@
"preferences_save_player_pos_label": "이어서 보기: ", "preferences_save_player_pos_label": "이어서 보기: ",
"none": "없음", "none": "없음",
"videoinfo_started_streaming_x_ago": "`x` 전에 스트리밍을 시작했습니다", "videoinfo_started_streaming_x_ago": "`x` 전에 스트리밍을 시작했습니다",
"crash_page_you_found_a_bug": "Invidious에서 버그를 찾은 것 같습니다!", "crash_page_you_found_a_bug": "인비디어스에서 버그를 찾은 것 같습니다!",
"download_subtitles": "자막 - `x`(.vtt)", "download_subtitles": "자막 - `x`(.vtt)",
"user_saved_playlists": "`x`개의 저장된 재생목록", "user_saved_playlists": "`x`개의 저장된 재생목록",
"crash_page_before_reporting": "버그를 보고하기 전에 다음 사항이 있는지 확인합니다:", "crash_page_before_reporting": "버그를 보고하기 전에 다음 사항이 있는지 확인합니다:",
@ -456,5 +456,9 @@
"crash_page_report_issue": "위의 방법 중 어느 것도 도움이 되지 않았다면, <a href=\"`x`\">깃허브에서 새 이슈를 열고</a>(가능하면 영어로) 메시지에 다음 텍스트를 포함하세요(해당 텍스트를 번역하지 마십시오):", "crash_page_report_issue": "위의 방법 중 어느 것도 도움이 되지 않았다면, <a href=\"`x`\">깃허브에서 새 이슈를 열고</a>(가능하면 영어로) 메시지에 다음 텍스트를 포함하세요(해당 텍스트를 번역하지 마십시오):",
"videoinfo_youTube_embed_link": "임베드", "videoinfo_youTube_embed_link": "임베드",
"videoinfo_invidious_embed_link": "임베드 링크", "videoinfo_invidious_embed_link": "임베드 링크",
"error_video_not_in_playlist": "요청한 동영상이 이 재생목록에 없습니다. <a href=\"`x`\">재생목록 목록을 보려면 여기를 클릭하십시오.</a>" "error_video_not_in_playlist": "요청한 동영상이 이 재생목록에 없습니다. <a href=\"`x`\">재생목록 목록을 보려면 여기를 클릭하십시오.</a>",
"channel_tab_shorts_label": "쇼츠",
"channel_tab_streams_label": "실시간 스트리밍",
"channel_tab_channels_label": "채널",
"channel_tab_playlists_label": "재생목록"
} }

View File

@ -67,7 +67,7 @@
"preferences_annotations_label": "Domyślnie pokazuj adnotacje: ", "preferences_annotations_label": "Domyślnie pokazuj adnotacje: ",
"preferences_extend_desc_label": "Automatycznie rozwijaj opisy filmów: ", "preferences_extend_desc_label": "Automatycznie rozwijaj opisy filmów: ",
"preferences_vr_mode_label": "Interaktywne filmy 360 stopni (wymaga WebGL): ", "preferences_vr_mode_label": "Interaktywne filmy 360 stopni (wymaga WebGL): ",
"preferences_category_visual": "Preferencje Wizualne", "preferences_category_visual": "Preferencje wizualne",
"preferences_player_style_label": "Styl odtwarzacza: ", "preferences_player_style_label": "Styl odtwarzacza: ",
"Dark mode: ": "Ciemny motyw: ", "Dark mode: ": "Ciemny motyw: ",
"preferences_dark_mode_label": "Motyw: ", "preferences_dark_mode_label": "Motyw: ",
@ -324,7 +324,7 @@
"`x` marked it with a ❤": "`x` oznaczonych ❤", "`x` marked it with a ❤": "`x` oznaczonych ❤",
"Audio mode": "Tryb audio", "Audio mode": "Tryb audio",
"Video mode": "Tryb wideo", "Video mode": "Tryb wideo",
"channel_tab_videos_label": "Filmy", "channel_tab_videos_label": "Wideo",
"Playlists": "Playlisty", "Playlists": "Playlisty",
"channel_tab_community_label": "Społeczność", "channel_tab_community_label": "Społeczność",
"search_filters_sort_option_relevance": "Trafność", "search_filters_sort_option_relevance": "Trafność",
@ -443,7 +443,7 @@
"user_saved_playlists": "`x` zapisanych playlist", "user_saved_playlists": "`x` zapisanych playlist",
"Video unavailable": "Film niedostępny", "Video unavailable": "Film niedostępny",
"preferences_save_player_pos_label": "Zapisz pozycję odtwarzania: ", "preferences_save_player_pos_label": "Zapisz pozycję odtwarzania: ",
"preferences_region_label": "Region zawartości: ", "preferences_region_label": "Kraj treści: ",
"Released under the AGPLv3 on Github.": "Wydany na licencji AGPLv3 na GitHub.", "Released under the AGPLv3 on Github.": "Wydany na licencji AGPLv3 na GitHub.",
"search_filters_duration_option_short": "Krótka (< 4 minut)", "search_filters_duration_option_short": "Krótka (< 4 minut)",
"search_filters_duration_option_long": "Długa (> 20 minut)", "search_filters_duration_option_long": "Długa (> 20 minut)",
@ -481,12 +481,19 @@
"search_message_no_results": "Nie znaleziono wyników.", "search_message_no_results": "Nie znaleziono wyników.",
"preferences_watch_history_label": "Włącz historię oglądania: ", "preferences_watch_history_label": "Włącz historię oglądania: ",
"search_filters_apply_button": "Zastosuj wybrane filtry", "search_filters_apply_button": "Zastosuj wybrane filtry",
"search_message_change_filters_or_query": "Spróbuj poszerzyć zapytanie i/lub zmienić filtry.", "search_message_change_filters_or_query": "Spróbuj poszerzyć zapytanie wyszukiwania i/lub zmienić filtry.",
"search_filters_date_label": "Data przesłania", "search_filters_date_label": "Data przesłania",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"search_filters_date_option_none": "Dowolna data", "search_filters_date_option_none": "Dowolna data",
"search_message_use_another_instance": " Możesz także <a href=\"`x`\">wyszukać w innej instancji</a>.", "search_message_use_another_instance": " Możesz także <a href=\"`x`\">wyszukać w innej instancji</a>.",
"search_filters_type_option_all": "Dowolny typ", "search_filters_type_option_all": "Dowolny typ",
"search_filters_duration_option_none": "Dowolna długość", "search_filters_duration_option_none": "Dowolna długość",
"search_filters_duration_option_medium": "Średnia (4-20 minut)" "search_filters_duration_option_medium": "Średnia (4-20 minut)",
"channel_tab_streams_label": "Na żywo",
"channel_tab_channels_label": "Kanały",
"channel_tab_playlists_label": "Playlisty",
"channel_tab_shorts_label": "Shorts",
"Music in this video": "Muzyka w tym filmie",
"Artist: ": "Wykonawca: ",
"Album: ": "Album: "
} }

View File

@ -381,7 +381,7 @@
"footer_documentation": "Documentação", "footer_documentation": "Documentação",
"footer_source_code": "Código fonte", "footer_source_code": "Código fonte",
"footer_original_source_code": "Código fonte original", "footer_original_source_code": "Código fonte original",
"footer_modfied_source_code": "Código Fonte Modificado", "footer_modfied_source_code": "Código-fonte modificado",
"preferences_quality_dash_label": "Qualidade de vídeo do painel preferida: ", "preferences_quality_dash_label": "Qualidade de vídeo do painel preferida: ",
"preferences_region_label": "País do conteúdo: ", "preferences_region_label": "País do conteúdo: ",
"preferences_quality_dash_option_4320p": "4320p", "preferences_quality_dash_option_4320p": "4320p",
@ -472,5 +472,12 @@
"search_filters_duration_option_medium": "Médio (4 - 20 minutos)", "search_filters_duration_option_medium": "Médio (4 - 20 minutos)",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"Popular enabled: ": "Popular habilitado: ", "Popular enabled: ": "Popular habilitado: ",
"error_video_not_in_playlist": "O vídeo solicitado não existe nesta playlist. <a href=\"`x`\">Clique aqui para acessar a página inicial da playlist.</a>" "error_video_not_in_playlist": "O vídeo solicitado não existe nesta playlist. <a href=\"`x`\">Clique aqui para acessar a página inicial da playlist.</a>",
"channel_tab_channels_label": "Canais",
"channel_tab_playlists_label": "Listas de reprodução",
"channel_tab_shorts_label": "Curtos",
"channel_tab_streams_label": "Ao Vivo",
"Music in this video": "Música neste vídeo",
"Artist: ": "Artista: ",
"Album: ": "Álbum: "
} }

View File

@ -472,5 +472,12 @@
"search_message_change_filters_or_query": "Tente alargar os termos genéricos da pesquisa e/ou alterar os filtros.", "search_message_change_filters_or_query": "Tente alargar os termos genéricos da pesquisa e/ou alterar os filtros.",
"crash_page_refresh": "tentou <a href=\"`x`\">recarregar a página</a>", "crash_page_refresh": "tentou <a href=\"`x`\">recarregar a página</a>",
"crash_page_switch_instance": "tentou <a href=\"`x`\">usar outra instância</a>", "crash_page_switch_instance": "tentou <a href=\"`x`\">usar outra instância</a>",
"error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. <a href=\"`x`\">Clique aqui para a página inicial da lista de reprodução.</a>" "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. <a href=\"`x`\">Clique aqui para a página inicial da lista de reprodução.</a>",
"Artist: ": "Artista: ",
"Album: ": "Álbum: ",
"channel_tab_streams_label": "Diretos",
"channel_tab_playlists_label": "Listas de reprodução",
"channel_tab_channels_label": "Canais",
"Music in this video": "Música neste vídeo",
"channel_tab_shorts_label": "Curtos"
} }

View File

@ -472,5 +472,12 @@
"search_filters_type_option_all": "Qualquer tipo", "search_filters_type_option_all": "Qualquer tipo",
"search_filters_duration_option_none": "Qualquer duração", "search_filters_duration_option_none": "Qualquer duração",
"Popular enabled: ": "Página \"popular\" ativada: ", "Popular enabled: ": "Página \"popular\" ativada: ",
"error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. <a href=\"`x`\">Clique aqui para a página inicial da lista de reprodução.</a>" "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. <a href=\"`x`\">Clique aqui para a página inicial da lista de reprodução.</a>",
"channel_tab_playlists_label": "Listas de reprodução",
"channel_tab_channels_label": "Canais",
"channel_tab_shorts_label": "Curtos",
"channel_tab_streams_label": "Diretos",
"Music in this video": "Música neste vídeo",
"Artist: ": "Artista: ",
"Album: ": "Álbum: "
} }

View File

@ -69,11 +69,11 @@
"preferences_vr_mode_label": "Интерактивные 360-градусные видео (необходим WebGL): ", "preferences_vr_mode_label": "Интерактивные 360-градусные видео (необходим WebGL): ",
"preferences_category_visual": "Настройки сайта", "preferences_category_visual": "Настройки сайта",
"preferences_player_style_label": "Стиль проигрывателя: ", "preferences_player_style_label": "Стиль проигрывателя: ",
"Dark mode: ": "Тёмное оформление: ", "Dark mode: ": "Темное оформление: ",
"preferences_dark_mode_label": "Тема: ", "preferences_dark_mode_label": "Тема: ",
"dark": ёмная", "dark": емная",
"light": "светлая", "light": "светлая",
"preferences_thin_mode_label": "Облегчённое оформление: ", "preferences_thin_mode_label": "Облегченное оформление: ",
"preferences_category_misc": "Прочие настройки", "preferences_category_misc": "Прочие настройки",
"preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ", "preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ",
"preferences_category_subscription": "Настройки подписок", "preferences_category_subscription": "Настройки подписок",
@ -88,7 +88,7 @@
"channel name": "по названию канала", "channel name": "по названию канала",
"channel name - reverse": "по названию канала в обратном порядке", "channel name - reverse": "по названию канала в обратном порядке",
"Only show latest video from channel: ": "Показывать только последние видео с каналов: ", "Only show latest video from channel: ": "Показывать только последние видео с каналов: ",
"Only show latest unwatched video from channel: ": "Показывать только непросмотренные видео с каналов: ", "Only show latest unwatched video from channel: ": "Показывать только последние непросмотренные видео с канала: ",
"preferences_unseen_only_label": "Показывать только непросмотренные видео: ", "preferences_unseen_only_label": "Показывать только непросмотренные видео: ",
"preferences_notifications_only_label": "Показывать только оповещения, если они есть: ", "preferences_notifications_only_label": "Показывать только оповещения, если они есть: ",
"Enable web notifications": "Включить уведомления в браузере", "Enable web notifications": "Включить уведомления в браузере",
@ -147,13 +147,13 @@
"License: ": "Лицензия: ", "License: ": "Лицензия: ",
"Family friendly? ": "Семейный просмотр: ", "Family friendly? ": "Семейный просмотр: ",
"Wilson score: ": "Оценка Уилсона: ", "Wilson score: ": "Оценка Уилсона: ",
"Engagement: ": "Вовлечённость: ", "Engagement: ": "Вовлеченность: ",
"Whitelisted regions: ": "Доступно в регионах: ", "Whitelisted regions: ": "Доступно в регионах: ",
"Blacklisted regions: ": "Недоступно в регионах: ", "Blacklisted regions: ": "Недоступно в регионах: ",
"Shared `x`": "Опубликовано `x`", "Shared `x`": "Опубликовано `x`",
"Premieres in `x`": "Премьера через `x`", "Premieres in `x`": "Премьера через `x`",
"Premieres `x`": "Премьера `x`", "Premieres `x`": "Премьера `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключён JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключен JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.",
"View YouTube comments": "Показать комментарии с YouTube", "View YouTube comments": "Показать комментарии с YouTube",
"View more comments on Reddit": "Посмотреть больше комментариев на Reddit", "View more comments on Reddit": "Посмотреть больше комментариев на Reddit",
"View `x` comments": { "View `x` comments": {
@ -180,23 +180,23 @@
"Please log in": "Пожалуйста, войдите", "Please log in": "Пожалуйста, войдите",
"Invidious Private Feed for `x`": "Приватная лента Invidious для `x`", "Invidious Private Feed for `x`": "Приватная лента Invidious для `x`",
"channel:`x`": "канал: `x`", "channel:`x`": "канал: `x`",
"Deleted or invalid channel": "Канал удалён или не найден", "Deleted or invalid channel": "Канал удален или не найден",
"This channel does not exist.": "Такого канала не существует.", "This channel does not exist.": "Такого канала не существует.",
"Could not get channel info.": "Не удаётся получить информацию об этом канале.", "Could not get channel info.": "Не удается получить информацию об этом канале.",
"Could not fetch comments": "Не удаётся загрузить комментарии", "Could not fetch comments": "Не удается загрузить комментарии",
"`x` ago": "`x` назад", "`x` ago": "`x` назад",
"Load more": "Загрузить ещё", "Load more": "Загрузить еще",
"Could not create mix.": "Не удалось создать микс.", "Could not create mix.": "Не удалось создать микс.",
"Empty playlist": "Плейлист пуст", "Empty playlist": "Плейлист пуст",
"Not a playlist.": "Некорректный плейлист.", "Not a playlist.": "Это не плейлист.",
"Playlist does not exist.": "Плейлист не существует.", "Playlist does not exist.": "Плейлист не существует.",
"Could not pull trending pages.": "Не удаётся загрузить страницы «в тренде».", "Could not pull trending pages.": "Не удается загрузить страницы «в тренде».",
"Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»", "Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»",
"Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»", "Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»",
"Erroneous challenge": "Неправильный ответ в «challenge»", "Erroneous challenge": "Неправильный ответ в «challenge»",
"Erroneous token": "Неправильный токен", "Erroneous token": "Неправильный токен",
"No such user": "Пользователь не найден", "No such user": "Пользователь не найден",
"Token is expired, please try again": "Срок действия токена истёк, попробуйте позже", "Token is expired, please try again": "Срок действия токена истек, попробуйте позже",
"English": "Английский", "English": "Английский",
"English (auto-generated)": "Английский (созданы автоматически)", "English (auto-generated)": "Английский (созданы автоматически)",
"Afrikaans": "Африкаанс", "Afrikaans": "Африкаанс",
@ -379,7 +379,7 @@
"Turkish (auto-generated)": "Турецкий (созданы автоматически)", "Turkish (auto-generated)": "Турецкий (созданы автоматически)",
"Vietnamese (auto-generated)": "Вьетнамский (созданы автоматически)", "Vietnamese (auto-generated)": "Вьетнамский (созданы автоматически)",
"footer_documentation": "Документация", "footer_documentation": "Документация",
"adminprefs_modified_source_code_url_label": "Ссылка на нашу ветку репозитория", "adminprefs_modified_source_code_url_label": "URL-адрес репозитория измененного исходного кода",
"none": "ничего", "none": "ничего",
"videoinfo_watch_on_youTube": "Смотреть на YouTube", "videoinfo_watch_on_youTube": "Смотреть на YouTube",
"videoinfo_youTube_embed_link": "Версия для встраивания", "videoinfo_youTube_embed_link": "Версия для встраивания",
@ -453,8 +453,8 @@
"Portuguese (Brazil)": "Португальский (Бразилия)", "Portuguese (Brazil)": "Португальский (Бразилия)",
"footer_source_code": "Исходный код", "footer_source_code": "Исходный код",
"footer_original_source_code": "Оригинальный исходный код", "footer_original_source_code": "Оригинальный исходный код",
"footer_modfied_source_code": "Изменённый исходный код", "footer_modfied_source_code": "Измененный исходный код",
"user_saved_playlists": "`x` сохранённых плейлистов", "user_saved_playlists": "`x` сохраненных плейлистов",
"crash_page_search_issue": "поискали <a href=\"`x`\">похожую проблему на GitHub</a>", "crash_page_search_issue": "поискали <a href=\"`x`\">похожую проблему на GitHub</a>",
"comments_points_count_0": "{{count}} плюс", "comments_points_count_0": "{{count}} плюс",
"comments_points_count_1": "{{count}} плюса", "comments_points_count_1": "{{count}} плюса",
@ -488,5 +488,12 @@
"search_filters_duration_option_medium": "Средние (4 - 20 минут)", "search_filters_duration_option_medium": "Средние (4 - 20 минут)",
"search_filters_apply_button": "Применить фильтры", "search_filters_apply_button": "Применить фильтры",
"Popular enabled: ": "Популярное включено: ", "Popular enabled: ": "Популярное включено: ",
"error_video_not_in_playlist": "Запрошенного видео нет в этом плейлисте. <a href=\"`x`\">Нажмите тут, чтобы вернуться к странице плейлиста.</a>" "error_video_not_in_playlist": "Запрошенного видео нет в этом плейлисте. <a href=\"`x`\">Нажмите тут, чтобы вернуться к странице плейлиста.</a>",
"channel_tab_playlists_label": "Плейлисты",
"channel_tab_channels_label": "Каналы",
"channel_tab_streams_label": "Живое вещание",
"channel_tab_shorts_label": "Shorts",
"Music in this video": "Музыка в этом видео",
"Artist: ": "Исполнитель: ",
"Album: ": "Альбом: "
} }

View File

@ -206,7 +206,7 @@
"generic_count_years_2": "{{count}} leti", "generic_count_years_2": "{{count}} leti",
"generic_count_years_3": "{{count}} leti", "generic_count_years_3": "{{count}} leti",
"generic_count_days_0": "{{count}} dnevom", "generic_count_days_0": "{{count}} dnevom",
"generic_count_days_1": "{{count}} dnevi", "generic_count_days_1": "{{count}} dnevoma",
"generic_count_days_2": "{{count}} dnevi", "generic_count_days_2": "{{count}} dnevi",
"generic_count_days_3": "{{count}} dnevi", "generic_count_days_3": "{{count}} dnevi",
"generic_count_hours_0": "{{count}} uro", "generic_count_hours_0": "{{count}} uro",
@ -246,10 +246,10 @@
"generic_videos_count_1": "{{count}} videa", "generic_videos_count_1": "{{count}} videa",
"generic_videos_count_2": "{{count}} videi", "generic_videos_count_2": "{{count}} videi",
"generic_videos_count_3": "{{count}} videov", "generic_videos_count_3": "{{count}} videov",
"generic_views_count_0": "{{count}} ogled", "generic_views_count_0": "Ogledov: {{count}}",
"generic_views_count_1": "{{count}} ogleda", "generic_views_count_1": "Ogledov: {{count}}",
"generic_views_count_2": "{{count}} ogledi", "generic_views_count_2": "Ogledov: {{count}}",
"generic_views_count_3": "{{count}} ogledov", "generic_views_count_3": "Ogledov: {{count}}",
"generic_playlists_count_0": "{{count}} seznam predvajanja", "generic_playlists_count_0": "{{count}} seznam predvajanja",
"generic_playlists_count_1": "{{count}} seznama predvajanja", "generic_playlists_count_1": "{{count}} seznama predvajanja",
"generic_playlists_count_2": "{{count}} seznami predvajanja", "generic_playlists_count_2": "{{count}} seznami predvajanja",
@ -495,7 +495,7 @@
"footer_modfied_source_code": "Spremenjena izvorna koda", "footer_modfied_source_code": "Spremenjena izvorna koda",
"user_created_playlists": "`x` ustvarjenih seznamov predvajanja", "user_created_playlists": "`x` ustvarjenih seznamov predvajanja",
"adminprefs_modified_source_code_url_label": "URL do shrambe spremenjene izvorne kode", "adminprefs_modified_source_code_url_label": "URL do shrambe spremenjene izvorne kode",
"videoinfo_youTube_embed_link": "Vdelati", "videoinfo_youTube_embed_link": "Vdelaj",
"videoinfo_invidious_embed_link": "Povezava za vdelavo", "videoinfo_invidious_embed_link": "Povezava za vdelavo",
"crash_page_switch_instance": "poskušal/a <a href=\"`x`\">uporabiti drugo instanco</a>", "crash_page_switch_instance": "poskušal/a <a href=\"`x`\">uporabiti drugo instanco</a>",
"download_subtitles": "Podnapisi - `x` (.vtt)", "download_subtitles": "Podnapisi - `x` (.vtt)",
@ -504,5 +504,12 @@
"crash_page_search_issue": "preiskal/a <a href=\"`x`\">obstoječe težave na GitHubu</a>", "crash_page_search_issue": "preiskal/a <a href=\"`x`\">obstoječe težave na GitHubu</a>",
"crash_page_report_issue": "Če nič od navedenega ni pomagalo, prosim <a href=\"`x`\">odpri novo težavo v GitHubu</a> (po možnosti v angleščini) in v svoje sporočilo vključi naslednje besedilo (tega besedila NE prevajaj):", "crash_page_report_issue": "Če nič od navedenega ni pomagalo, prosim <a href=\"`x`\">odpri novo težavo v GitHubu</a> (po možnosti v angleščini) in v svoje sporočilo vključi naslednje besedilo (tega besedila NE prevajaj):",
"Popular enabled: ": "Priljubljeni omogočeni: ", "Popular enabled: ": "Priljubljeni omogočeni: ",
"error_video_not_in_playlist": "Zahtevani videoposnetek ne obstaja na tem seznamu predvajanja. <a href=\"`x`\">Klikni tukaj za domačo stran seznama predvajanja.</a>" "error_video_not_in_playlist": "Zahtevani videoposnetek ne obstaja na tem seznamu predvajanja. <a href=\"`x`\">Klikni tukaj za domačo stran seznama predvajanja.</a>",
"channel_tab_playlists_label": "Seznami predvajanja",
"channel_tab_shorts_label": "Kratki videoposnetki",
"channel_tab_channels_label": "Kanali",
"channel_tab_streams_label": "Prenosi v živo",
"Artist: ": "Umetnik/ca: ",
"Music in this video": "Glasba v tem videoposnetku",
"Album: ": "Album: "
} }

View File

@ -286,7 +286,7 @@
"search_filters_type_option_show": "Shfaqe", "search_filters_type_option_show": "Shfaqe",
"search_filters_duration_option_short": "E shkurtër (< 4 minuta)", "search_filters_duration_option_short": "E shkurtër (< 4 minuta)",
"search_filters_features_option_purchased": "Të blera", "search_filters_features_option_purchased": "Të blera",
"footer_modfied_source_code": "Kod Burim i ndryshuar", "footer_modfied_source_code": "Kod burim i ndryshuar",
"adminprefs_modified_source_code_url_label": "URL e depos së ndryshuar të kodit burim", "adminprefs_modified_source_code_url_label": "URL e depos së ndryshuar të kodit burim",
"none": "asnjë", "none": "asnjë",
"videoinfo_started_streaming_x_ago": "Filloi transmetimin `x` më parë", "videoinfo_started_streaming_x_ago": "Filloi transmetimin `x` më parë",
@ -463,5 +463,12 @@
"search_filters_duration_option_none": "Çfarëdo kohëzgjatjeje", "search_filters_duration_option_none": "Çfarëdo kohëzgjatjeje",
"search_filters_duration_option_medium": "Mesatare (4 - 20 minuta)", "search_filters_duration_option_medium": "Mesatare (4 - 20 minuta)",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"search_filters_apply_button": "Apliko filtrat e përzgjedhur" "search_filters_apply_button": "Apliko filtrat e përzgjedhur",
"channel_tab_playlists_label": "Luajlista",
"Artist: ": "Artist: ",
"Album: ": "Album: ",
"channel_tab_channels_label": "Kanale",
"Music in this video": "Muzikë në këtë video",
"channel_tab_shorts_label": "Të shkurtra",
"channel_tab_streams_label": "Transmetime të drejtpërdrejta"
} }

View File

@ -363,7 +363,7 @@
"footer_documentation": "Belgelendirme", "footer_documentation": "Belgelendirme",
"footer_source_code": "Kaynak Kodları", "footer_source_code": "Kaynak Kodları",
"footer_original_source_code": "Orijinal Kaynak Kodları", "footer_original_source_code": "Orijinal Kaynak Kodları",
"footer_modfied_source_code": "Değiştirilmiş Kaynak Kodları", "footer_modfied_source_code": "Değiştirilmiş kaynak kodları",
"adminprefs_modified_source_code_url_label": "Değiştirilmiş Kaynak Kodları Deposunun URL'si", "adminprefs_modified_source_code_url_label": "Değiştirilmiş Kaynak Kodları Deposunun URL'si",
"footer_donate_page": "Bağış Yap", "footer_donate_page": "Bağış Yap",
"preferences_region_label": "İçerik Ülkesi: ", "preferences_region_label": "İçerik Ülkesi: ",
@ -397,8 +397,8 @@
"videoinfo_watch_on_youTube": "YouTube'da İzle", "videoinfo_watch_on_youTube": "YouTube'da İzle",
"download_subtitles": "Alt Yazılar - `x` (.vtt)", "download_subtitles": "Alt Yazılar - `x` (.vtt)",
"preferences_save_player_pos_label": "Oynatma Konumunu Kaydet: ", "preferences_save_player_pos_label": "Oynatma Konumunu Kaydet: ",
"generic_views_count": "{{count}} Görüntüleme", "generic_views_count": "{{count}} Görüntülenme",
"generic_views_count_plural": "{{count}} Görüntüleme", "generic_views_count_plural": "{{count}} Görüntülenme",
"generic_subscribers_count": "{{count}} Abone", "generic_subscribers_count": "{{count}} Abone",
"generic_subscribers_count_plural": "{{count}} Abone", "generic_subscribers_count_plural": "{{count}} Abone",
"generic_subscriptions_count": "{{count}} Abonelik", "generic_subscriptions_count": "{{count}} Abonelik",
@ -472,5 +472,12 @@
"search_filters_title": "Filtreler", "search_filters_title": "Filtreler",
"search_message_change_filters_or_query": "Arama sorgunuzu genişletmeyi ve/veya filtreleri değiştirmeyi deneyin.", "search_message_change_filters_or_query": "Arama sorgunuzu genişletmeyi ve/veya filtreleri değiştirmeyi deneyin.",
"Popular enabled: ": "Popüler Etkin: ", "Popular enabled: ": "Popüler Etkin: ",
"error_video_not_in_playlist": "İstenen video bu oynatma listesinde yok. <a href=\"`x`\">Oynatma listesi ana sayfası için buraya tıklayın.</a>" "error_video_not_in_playlist": "İstenen video bu oynatma listesinde yok. <a href=\"`x`\">Oynatma listesi ana sayfası için buraya tıklayın.</a>",
"channel_tab_channels_label": "Kanallar",
"channel_tab_shorts_label": "Kısa Çekimler",
"channel_tab_streams_label": "Canlı Yayınlar",
"channel_tab_playlists_label": "Oynatma Listeleri",
"Album: ": "Albüm: ",
"Music in this video": "Bu videodaki müzik",
"Artist: ": "Sanatçı: "
} }

View File

@ -54,7 +54,7 @@
"preferences_continue_label": "Завжди вмикати наступне відео: ", "preferences_continue_label": "Завжди вмикати наступне відео: ",
"preferences_continue_autoplay_label": "Автовідтворення наступного відео: ", "preferences_continue_autoplay_label": "Автовідтворення наступного відео: ",
"preferences_listen_label": "Режим «тільки звук» як усталений: ", "preferences_listen_label": "Режим «тільки звук» як усталений: ",
"preferences_local_label": "Програвати відео через проксі? ", "preferences_local_label": "Відтворення відео через проксі: ",
"preferences_speed_label": "Усталена швидкість відео: ", "preferences_speed_label": "Усталена швидкість відео: ",
"preferences_quality_label": "Пріорітетна якість відео: ", "preferences_quality_label": "Пріорітетна якість відео: ",
"preferences_volume_label": "Гучність відео: ", "preferences_volume_label": "Гучність відео: ",
@ -63,13 +63,13 @@
"reddit": "Reddit", "reddit": "Reddit",
"preferences_captions_label": "Основна мова субтитрів: ", "preferences_captions_label": "Основна мова субтитрів: ",
"Fallback captions: ": "Запасна мова субтитрів: ", "Fallback captions: ": "Запасна мова субтитрів: ",
"preferences_related_videos_label": "Показувати схожі відео? ", "preferences_related_videos_label": "Показувати схожі відео: ",
"preferences_annotations_label": "Завжди показувати анотації? ", "preferences_annotations_label": "Завжди показувати анотації: ",
"preferences_category_visual": "Налаштування сайту", "preferences_category_visual": "Налаштування сайту",
"preferences_player_style_label": "Стиль програвача: ", "preferences_player_style_label": "Стиль програвача: ",
"Dark mode: ": "Темне оформлення: ", "Dark mode: ": "Темний режим: ",
"preferences_dark_mode_label": "Тема: ", "preferences_dark_mode_label": "Тема: ",
"dark": "темна", "dark": "Темна",
"light": "Світла", "light": "Світла",
"preferences_thin_mode_label": "Полегшене оформлення: ", "preferences_thin_mode_label": "Полегшене оформлення: ",
"preferences_category_subscription": "Налаштування підписок", "preferences_category_subscription": "Налаштування підписок",
@ -101,11 +101,11 @@
"preferences_category_admin": "Адміністраторські налаштування", "preferences_category_admin": "Адміністраторські налаштування",
"preferences_default_home_label": "Усталена домашня сторінка: ", "preferences_default_home_label": "Усталена домашня сторінка: ",
"preferences_feed_menu_label": "Меню потоку з відео: ", "preferences_feed_menu_label": "Меню потоку з відео: ",
"Top enabled: ": "Увімкнути топ відео? ", "Top enabled: ": "Увімкнути топ відео: ",
"CAPTCHA enabled: ": "Увімкнути капчу? ", "CAPTCHA enabled: ": "Увімкнути CAPTCHA: ",
"Login enabled: ": "Увімкнути авторизацію? ", "Login enabled: ": "Увімкнути вхід: ",
"Registration enabled: ": "Увімкнути реєстрацію? ", "Registration enabled: ": "Увімкнути реєстрацію: ",
"Report statistics: ": "Повідомляти статистику? ", "Report statistics: ": "Повідомляти статистику: ",
"Save preferences": "Зберегти налаштування", "Save preferences": "Зберегти налаштування",
"Subscription manager": "Менеджер підписок", "Subscription manager": "Менеджер підписок",
"Token manager": "Менеджер токенів", "Token manager": "Менеджер токенів",
@ -125,7 +125,7 @@
"Private": "Особистий", "Private": "Особистий",
"View all playlists": "Переглянути всі списки відтворення", "View all playlists": "Переглянути всі списки відтворення",
"Updated `x` ago": "Оновлено `x` тому", "Updated `x` ago": "Оновлено `x` тому",
"Delete playlist `x`?": "Видалити список відтворення \"x\"?", "Delete playlist `x`?": "Видалити список відтворення `x`?",
"Delete playlist": "Видалити список відтворення", "Delete playlist": "Видалити список відтворення",
"Create playlist": "Створити список відтворення", "Create playlist": "Створити список відтворення",
"Title": "Заголовок", "Title": "Заголовок",
@ -386,12 +386,12 @@
"Spanish (Mexico)": "Іспанська (Мексика)", "Spanish (Mexico)": "Іспанська (Мексика)",
"Spanish (Spain)": "Іспанська (Іспанія)", "Spanish (Spain)": "Іспанська (Іспанія)",
"next_steps_error_message_go_to_youtube": "Перейти до YouTube", "next_steps_error_message_go_to_youtube": "Перейти до YouTube",
"footer_donate_page": ожертвувати", "footer_donate_page": ідтримати",
"footer_documentation": "Документація", "footer_documentation": "Документація",
"footer_source_code": "Вихідний код", "footer_source_code": "Джерельний код",
"footer_original_source_code": "Оригінал вихідного коду", "footer_original_source_code": "Оригінал джерельного коду",
"footer_modfied_source_code": "Змінений вихідний код", "footer_modfied_source_code": "Змінений джерельний код",
"adminprefs_modified_source_code_url_label": "URL-адреса репозиторію зміненого вихідного коду", "adminprefs_modified_source_code_url_label": "URL-адреса репозиторію зміненого джерельного коду",
"none": "нема", "none": "нема",
"videoinfo_started_streaming_x_ago": "Трансляцію розпочато `x` тому", "videoinfo_started_streaming_x_ago": "Трансляцію розпочато `x` тому",
"crash_page_you_found_a_bug": "Схоже, ви знайшли ваду в Invidious!", "crash_page_you_found_a_bug": "Схоже, ви знайшли ваду в Invidious!",
@ -408,7 +408,7 @@
"next_steps_error_message": "Після чого спробуйте: ", "next_steps_error_message": "Після чого спробуйте: ",
"next_steps_error_message_refresh": "Оновити сторінку", "next_steps_error_message_refresh": "Оновити сторінку",
"Search": "Пошук", "Search": "Пошук",
"preferences_extend_desc_label": "Автоматично розширювати опис відео: ", "preferences_extend_desc_label": "Автоматично розгортати опис відео: ",
"preferences_category_misc": "Різноманітні параметри", "preferences_category_misc": "Різноманітні параметри",
"Show less": "Коротше", "Show less": "Коротше",
"preferences_quality_option_small": "Низька", "preferences_quality_option_small": "Низька",
@ -488,5 +488,12 @@
"search_filters_sort_option_rating": "Рейтингові", "search_filters_sort_option_rating": "Рейтингові",
"search_filters_sort_option_views": "Популярні", "search_filters_sort_option_views": "Популярні",
"Popular enabled: ": "Популярне ввімкнено: ", "Popular enabled: ": "Популярне ввімкнено: ",
"error_video_not_in_playlist": "Запитуваного відео в цьому списку відтворення не існує. <a href=\"`x`\">Клацніть тут, щоб переглянути домашню сторінку списку відтворення.</a>" "error_video_not_in_playlist": "Запитуваного відео в цьому списку відтворення не існує. <a href=\"`x`\">Клацніть тут, щоб переглянути домашню сторінку списку відтворення.</a>",
"channel_tab_shorts_label": "Shorts",
"channel_tab_streams_label": "Прямі трансляції",
"channel_tab_playlists_label": "Добірки",
"channel_tab_channels_label": "Канали",
"Music in this video": "Музика в цьому відео",
"Artist: ": "Виконавець: ",
"Album: ": "Альбом: "
} }

View File

@ -456,5 +456,12 @@
"search_filters_type_option_all": "任意类型", "search_filters_type_option_all": "任意类型",
"search_filters_features_option_vr180": "VR180", "search_filters_features_option_vr180": "VR180",
"Popular enabled: ": "已启用流行度: ", "Popular enabled: ": "已启用流行度: ",
"error_video_not_in_playlist": "此播放列表中不存在请求的视频。 <a href=\"`x`\">单击析出查看播放列表主页。</a>" "error_video_not_in_playlist": "此播放列表中不存在请求的视频。 <a href=\"`x`\">单击析出查看播放列表主页。</a>",
"Music in this video": "此视频中的音乐",
"channel_tab_playlists_label": "播放列表",
"Artist: ": "艺术家: ",
"channel_tab_streams_label": "直播",
"Album: ": "专辑: ",
"channel_tab_shorts_label": "短视频",
"channel_tab_channels_label": "频道"
} }

View File

@ -456,5 +456,12 @@
"search_filters_type_option_all": "任何類型", "search_filters_type_option_all": "任何類型",
"search_filters_date_option_none": "任何日期", "search_filters_date_option_none": "任何日期",
"Popular enabled: ": "已啟用人氣: ", "Popular enabled: ": "已啟用人氣: ",
"error_video_not_in_playlist": "此播放清單不存在請求的影片。<a href=\"`x`\">點擊此處檢視播放清單首頁。</a>" "error_video_not_in_playlist": "此播放清單不存在請求的影片。<a href=\"`x`\">點擊此處檢視播放清單首頁。</a>",
"channel_tab_shorts_label": "短片",
"channel_tab_playlists_label": "播放清單",
"channel_tab_channels_label": "頻道",
"channel_tab_streams_label": "直播",
"Artist: ": "藝術家: ",
"Album: ": "專輯: ",
"Music in this video": "此影片中的音樂"
} }

View File

@ -129,7 +129,7 @@ dependencies_to_install.each do |dep|
dep = "videojs.markers" if dep == "videojs-markers" dep = "videojs.markers" if dep == "videojs-markers"
if File.exists?("#{download_path}/package/dist/#{dep}.css") if File.exists?("#{download_path}/package/dist/#{dep}.css")
if minified && File.exists?("#{tmp_dir_path}/#{dep}/package/dist/#{dep}.min.css") if minified && File.exists?("#{download_path}/package/dist/#{dep}.min.css")
`mv #{download_path}/package/dist/#{dep}.min.css #{dest_path}/#{dep}.css` `mv #{download_path}/package/dist/#{dep}.min.css #{dest_path}/#{dep}.css`
else else
`mv #{download_path}/package/dist/#{dep}.css #{dest_path}/#{dep}.css` `mv #{download_path}/package/dist/#{dep}.css #{dest_path}/#{dep}.css`

View File

@ -69,7 +69,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
next if !post next if !post
content_html = post["contentText"]?.try { |t| parse_content(t) } || "" content_html = post["contentText"]?.try { |t| parse_content(t) } || ""
author = post["authorText"]?.try &.["simpleText"]? || "" author = post["authorText"]["runs"]?.try &.[0]?.try &.["text"]? || ""
json.object do json.object do
json.field "author", author json.field "author", author
@ -189,6 +189,32 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
# when .has_key?("pollRenderer") # when .has_key?("pollRenderer")
# attachment = attachment["pollRenderer"] # attachment = attachment["pollRenderer"]
# json.field "type", "poll" # json.field "type", "poll"
when .has_key?("postMultiImageRenderer")
attachment = attachment["postMultiImageRenderer"]
json.field "type", "multiImage"
json.field "images" do
json.array do
attachment["images"].as_a.each do |image|
json.array do
thumbnail = image["backstageImageRenderer"]["image"]["thumbnails"][0].as_h
width = thumbnail["width"].as_i
height = thumbnail["height"].as_i
aspect_ratio = (width.to_f / height.to_f)
url = thumbnail["url"].as_s.gsub(/=w\d+-h\d+(-p)?(-nd)?(-df)?(-rwa)?/, "=s640")
qualities = {320, 560, 640, 1280, 2000}
qualities.each do |quality|
json.object do
json.field "url", url.gsub(/=s\d+/, "=s#{quality}")
json.field "width", quality
json.field "height", (quality / aspect_ratio).ceil.to_i
end
end
end
end
end
end
else else
json.field "type", "unknown" json.field "type", "unknown"
json.field "error", "Unrecognized attachment type." json.field "error", "Unrecognized attachment type."

View File

@ -181,6 +181,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b
json.field "content", html_to_content(content_html) json.field "content", html_to_content(content_html)
json.field "contentHtml", content_html json.field "contentHtml", content_html
json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil)
json.field "published", published.to_unix json.field "published", published.to_unix
json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale))
@ -670,6 +672,7 @@ def content_to_comment_html(content, video_id : String? = "")
end end
text = "<b>#{text}</b>" if run["bold"]? text = "<b>#{text}</b>" if run["bold"]?
text = "<s>#{text}</s>" if run["strikethrough"]?
text = "<i>#{text}</i>" if run["italics"]? text = "<i>#{text}</i>" if run["italics"]?
text text

View File

@ -20,7 +20,7 @@ module JSONFilter
/^\(|\(\(|\/\(/ /^\(|\(\(|\/\(/
end end
def self.parse_fields(fields_text : String) : Nil def self.parse_fields(fields_text : String, &) : Nil
if fields_text.empty? if fields_text.empty?
raise FieldsParser::ParseError.new "Fields is empty" raise FieldsParser::ParseError.new "Fields is empty"
end end
@ -42,7 +42,7 @@ module JSONFilter
parse_nest_groups(fields_text) { |nest_list| yield nest_list } parse_nest_groups(fields_text) { |nest_list| yield nest_list }
end end
def self.parse_single_nests(fields_text : String) : Nil def self.parse_single_nests(fields_text : String, &) : Nil
single_nests = remove_nest_groups(fields_text) single_nests = remove_nest_groups(fields_text)
if !single_nests.empty? if !single_nests.empty?
@ -60,7 +60,7 @@ module JSONFilter
end end
end end
def self.parse_nest_groups(fields_text : String) : Nil def self.parse_nest_groups(fields_text : String, &) : Nil
nest_stack = [] of NamedTuple(group_name: String, closing_bracket_index: Int64) nest_stack = [] of NamedTuple(group_name: String, closing_bracket_index: Int64)
bracket_pairs = get_bracket_pairs(fields_text, true) bracket_pairs = get_bracket_pairs(fields_text, true)

View File

@ -74,6 +74,7 @@ struct SearchVideo
json.field "author", self.author json.field "author", self.author
json.field "authorId", self.ucid json.field "authorId", self.ucid
json.field "authorUrl", "/channel/#{self.ucid}" json.field "authorUrl", "/channel/#{self.ucid}"
json.field "authorVerified", self.author_verified
json.field "videoThumbnails" do json.field "videoThumbnails" do
Invidious::JSONify::APIv1.thumbnails(json, self.id) Invidious::JSONify::APIv1.thumbnails(json, self.id)

View File

@ -162,7 +162,7 @@ def number_with_separator(number)
end end
def short_text_to_number(short_text : String) : Int64 def short_text_to_number(short_text : String) : Int64
matches = /(?<number>\d+(\.\d+)?)\s?(?<suffix>[mMkKbB])?/.match(short_text) matches = /(?<number>\d+(\.\d+)?)\s?(?<suffix>[mMkKbB]?)/.match(short_text)
number = matches.try &.["number"].to_f || 0.0 number = matches.try &.["number"].to_f || 0.0
case matches.try &.["suffix"].downcase case matches.try &.["suffix"].downcase
@ -259,7 +259,7 @@ def get_referer(env, fallback = "/", unroll = true)
end end
referer = referer.request_target referer = referer.request_target
referer = "/" + referer.gsub(/[^\/?@&%=\-_.0-9a-zA-Z]/, "").lstrip("/\\") referer = "/" + referer.gsub(/[^\/?@&%=\-_.:,0-9a-zA-Z]/, "").lstrip("/\\")
if referer == env.request.path if referer == env.request.path
referer = fallback referer = fallback

View File

@ -203,7 +203,7 @@ module Invidious::Routes::Account
referer = get_referer(env) referer = get_referer(env)
if !user if !user
return env.redirect referer return env.redirect "/login?referer=#{URI.encode_path_segment(env.request.resource)}"
end end
user = user.as(User) user = user.as(User)
@ -262,6 +262,7 @@ module Invidious::Routes::Account
end end
query["token"] = access_token query["token"] = access_token
query["username"] = URI.encode_path_segment(user.email)
url.query = query.to_s url.query = query.to_s
env.redirect url.to_s env.redirect url.to_s

View File

@ -31,6 +31,88 @@ module Invidious::Routes::API::V1::Authenticated
env.response.status_code = 204 env.response.status_code = 204
end end
def self.export_invidious(env)
env.response.content_type = "application/json"
user = env.get("user").as(User)
return Invidious::User::Export.to_invidious(user)
end
def self.import_invidious(env)
user = env.get("user").as(User)
begin
if body = env.request.body
body = env.request.body.not_nil!.gets_to_end
else
body = "{}"
end
Invidious::User::Import.from_invidious(user, body)
rescue
end
env.response.status_code = 204
end
def self.get_history(env)
env.response.content_type = "application/json"
user = env.get("user").as(User)
page = env.params.query["page"]?.try &.to_i?.try &.clamp(0, Int32::MAX)
page ||= 1
max_results = env.params.query["max_results"]?.try &.to_i?.try &.clamp(0, MAX_ITEMS_PER_PAGE)
max_results ||= user.preferences.max_results
max_results ||= CONFIG.default_user_preferences.max_results
start_index = (page - 1) * max_results
if user.watched[start_index]?
watched = user.watched.reverse[start_index, max_results]
end
watched ||= [] of String
return watched.to_json
end
def self.mark_watched(env)
user = env.get("user").as(User)
if !user.preferences.watch_history
return error_json(409, "Watch history is disabled in preferences.")
end
id = env.params.url["id"]
if !id.match(/^[a-zA-Z0-9_-]{11}$/)
return error_json(400, "Invalid video id.")
end
Invidious::Database::Users.mark_watched(user, id)
env.response.status_code = 204
end
def self.mark_unwatched(env)
user = env.get("user").as(User)
if !user.preferences.watch_history
return error_json(409, "Watch history is disabled in preferences.")
end
id = env.params.url["id"]
if !id.match(/^[a-zA-Z0-9_-]{11}$/)
return error_json(400, "Invalid video id.")
end
Invidious::Database::Users.mark_unwatched(user, id)
env.response.status_code = 204
end
def self.clear_history(env)
user = env.get("user").as(User)
Invidious::Database::Users.clear_watch_history(user)
env.response.status_code = 204
end
def self.feed(env) def self.feed(env)
env.response.content_type = "application/json" env.response.content_type = "application/json"

View File

@ -89,6 +89,8 @@ module Invidious::Routes::API::V1::Channels
json.field "descriptionHtml", channel.description_html json.field "descriptionHtml", channel.description_html
json.field "allowedRegions", channel.allowed_regions json.field "allowedRegions", channel.allowed_regions
json.field "tabs", channel.tabs
json.field "authorVerified", channel.verified
json.field "latestVideos" do json.field "latestVideos" do
json.array do json.array do

View File

@ -150,4 +150,31 @@ module Invidious::Routes::API::V1::Misc
response response
end end
# resolve channel and clip urls, return the UCID
def self.resolve_url(env)
env.response.content_type = "application/json"
url = env.params.query["url"]?
return error_json(400, "Missing URL to resolve") if !url
begin
resolved_url = YoutubeAPI.resolve_url(url.as(String))
endpoint = resolved_url["endpoint"]
pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || ""
if resolved_ucid = endpoint.dig?("watchEndpoint", "videoId")
elsif resolved_ucid = endpoint.dig?("browseEndpoint", "browseId")
elsif pageType == "WEB_PAGE_TYPE_UNKNOWN"
return error_json(400, "Unknown url")
end
rescue ex
return error_json(500, ex)
end
JSON.build do |json|
json.object do
json.field "ucid", resolved_ucid.try &.as_s || ""
json.field "pageType", pageType
end
end
end
end end

View File

@ -93,6 +93,10 @@ module Invidious::Routes::API::V1::Videos
# as well as some other markup that makes it cumbersome, so we try to fix that here # as well as some other markup that makes it cumbersome, so we try to fix that here
if caption.name.includes? "auto-generated" if caption.name.includes? "auto-generated"
caption_xml = YT_POOL.client &.get(url).body caption_xml = YT_POOL.client &.get(url).body
if caption_xml.starts_with?("<?xml")
webvtt = caption.timedtext_to_vtt(caption_xml, tlang)
else
caption_xml = XML.parse(caption_xml) caption_xml = XML.parse(caption_xml)
webvtt = String.build do |str| webvtt = String.build do |str|
@ -134,15 +138,21 @@ module Invidious::Routes::API::V1::Videos
END_CUE END_CUE
end end
end end
end
else else
# Some captions have "align:[start/end]" and "position:[num]%" # Some captions have "align:[start/end]" and "position:[num]%"
# attributes. Those are causing issues with VideoJS, which is unable # attributes. Those are causing issues with VideoJS, which is unable
# to properly align the captions on the video, so we remove them. # to properly align the captions on the video, so we remove them.
# #
# See: https://github.com/iv-org/invidious/issues/2391 # See: https://github.com/iv-org/invidious/issues/2391
webvtt = YT_POOL.client &.get("#{url}&format=vtt").body
if webvtt.starts_with?("<?xml")
webvtt = caption.timedtext_to_vtt(webvtt)
else
webvtt = YT_POOL.client &.get("#{url}&format=vtt").body webvtt = YT_POOL.client &.get("#{url}&format=vtt").body
.gsub(/([0-9:.]{12} --> [0-9:.]{12}).+/, "\\1") .gsub(/([0-9:.]{12} --> [0-9:.]{12}).+/, "\\1")
end end
end
if title = env.params.query["title"]? if title = env.params.query["title"]?
# https://blog.fastmail.com/2011/06/24/download-non-english-filenames/ # https://blog.fastmail.com/2011/06/24/download-non-english-filenames/

View File

@ -6,14 +6,14 @@ module Invidious::Routes::Login
user = env.get? "user" user = env.get? "user"
return env.redirect "/feed/subscriptions" if user referer = get_referer(env, "/feed/subscriptions")
return env.redirect referer if user
if !CONFIG.login_enabled if !CONFIG.login_enabled
return error_template(400, "Login has been disabled by administrator.") return error_template(400, "Login has been disabled by administrator.")
end end
referer = get_referer(env, "/feed/subscriptions")
email = nil email = nil
password = nil password = nil
captcha = nil captcha = nil

View File

@ -104,33 +104,8 @@ module Invidious::Routes::Subscriptions
if format == "json" if format == "json"
env.response.content_type = "application/json" env.response.content_type = "application/json"
env.response.headers["content-disposition"] = "attachment" env.response.headers["content-disposition"] = "attachment"
playlists = Invidious::Database::Playlists.select_like_iv(user.email)
return JSON.build do |json| return Invidious::User::Export.to_invidious(user)
json.object do
json.field "subscriptions", user.subscriptions
json.field "watch_history", user.watched
json.field "preferences", user.preferences
json.field "playlists" do
json.array do
playlists.each do |playlist|
json.object do
json.field "title", playlist.title
json.field "description", html_to_content(playlist.description_html)
json.field "privacy", playlist.privacy.to_s
json.field "videos" do
json.array do
Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id|
json.string video_id
end
end
end
end
end
end
end
end
end
else else
env.response.content_type = "application/xml" env.response.content_type = "application/xml"
env.response.headers["content-disposition"] = "attachment" env.response.headers["content-disposition"] = "attachment"

View File

@ -132,6 +132,8 @@ module Invidious::Routing
get "/c/:user#{path}", Routes::Channels, :brand_redirect get "/c/:user#{path}", Routes::Channels, :brand_redirect
# /user/linustechtips | Not always the same as /c/ # /user/linustechtips | Not always the same as /c/
get "/user/:user#{path}", Routes::Channels, :brand_redirect get "/user/:user#{path}", Routes::Channels, :brand_redirect
# /@LinusTechTips | Handle
get "/@:user#{path}", Routes::Channels, :brand_redirect
# /attribution_link?a=anything&u=/channel/UCZYTClx2T1of7BRZ86-8fow # /attribution_link?a=anything&u=/channel/UCZYTClx2T1of7BRZ86-8fow
get "/attribution_link#{path}", Routes::Channels, :brand_redirect get "/attribution_link#{path}", Routes::Channels, :brand_redirect
# /profile?user=linustechtips # /profile?user=linustechtips
@ -252,6 +254,14 @@ module Invidious::Routing
get "/api/v1/auth/preferences", {{namespace}}::Authenticated, :get_preferences get "/api/v1/auth/preferences", {{namespace}}::Authenticated, :get_preferences
post "/api/v1/auth/preferences", {{namespace}}::Authenticated, :set_preferences post "/api/v1/auth/preferences", {{namespace}}::Authenticated, :set_preferences
get "/api/v1/auth/export/invidious", {{namespace}}::Authenticated, :export_invidious
post "/api/v1/auth/import/invidious", {{namespace}}::Authenticated, :import_invidious
get "/api/v1/auth/history", {{namespace}}::Authenticated, :get_history
post "/api/v1/auth/history/:id", {{namespace}}::Authenticated, :mark_watched
delete "/api/v1/auth/history/:id", {{namespace}}::Authenticated, :mark_unwatched
delete "/api/v1/auth/history", {{namespace}}::Authenticated, :clear_history
get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed
get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions
@ -279,6 +289,7 @@ module Invidious::Routing
get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist
get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist
get "/api/v1/mixes/:rdid", {{namespace}}::Misc, :mixes get "/api/v1/mixes/:rdid", {{namespace}}::Misc, :mixes
get "/api/v1/resolveurl", {{namespace}}::Misc, :resolve_url
{% end %} {% end %}
end end
end end

View File

@ -4,11 +4,12 @@ def fetch_trending(trending_type, region, locale)
plid = nil plid = nil
if trending_type == "Music" case trending_type.try &.downcase
when "music"
params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D" params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D"
elsif trending_type == "Gaming" when "gaming"
params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D" params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D"
elsif trending_type == "Movies" when "movies"
params = "4gIKGgh0cmFpbGVycw%3D%3D" params = "4gIKGgh0cmFpbGVycw%3D%3D"
else # Default else # Default
params = "" params = ""

View File

@ -0,0 +1,35 @@
struct Invidious::User
module Export
extend self
def to_invidious(user : User)
playlists = Invidious::Database::Playlists.select_like_iv(user.email)
return JSON.build do |json|
json.object do
json.field "subscriptions", user.subscriptions
json.field "watch_history", user.watched
json.field "preferences", user.preferences
json.field "playlists" do
json.array do
playlists.each do |playlist|
json.object do
json.field "title", playlist.title
json.field "description", html_to_content(playlist.description_html)
json.field "privacy", playlist.privacy.to_s
json.field "videos" do
json.array do
Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: CONFIG.playlist_length_limit).each do |video_id|
json.string video_id
end
end
end
end
end
end
end
end
end
end
end # module
end

View File

@ -247,6 +247,12 @@ struct Video
info["reason"]?.try &.as_s info["reason"]?.try &.as_s
end end
def music : Array(VideoMusic)
info["music"].as_a.map { |music_json|
VideoMusic.new(music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s)
}
end
# Macros defining getters/setters for various types of data # Macros defining getters/setters for various types of data
private macro getset_string(name) private macro getset_string(name)

View File

@ -31,6 +31,72 @@ module Invidious::Videos
return captions_list return captions_list
end end
def timedtext_to_vtt(timedtext : String, tlang = nil) : String
# In the future, we could just directly work with the url. This is more of a POC
cues = [] of XML::Node
tree = XML.parse(timedtext)
tree = tree.children.first
tree.children.each do |item|
if item.name == "body"
item.children.each do |cue|
if cue.name == "p" && !(cue.children.size == 1 && cue.children[0].content == "\n")
cues << cue
end
end
break
end
end
result = String.build do |result|
result << <<-END_VTT
WEBVTT
Kind: captions
Language: #{tlang || @language_code}
END_VTT
result << "\n\n"
cues.each_with_index do |node, i|
start_time = node["t"].to_f.milliseconds
duration = node["d"]?.try &.to_f.milliseconds
duration ||= start_time
if cues.size > i + 1
end_time = cues[i + 1]["t"].to_f.milliseconds
else
end_time = start_time + duration
end
# start_time
result << start_time.hours.to_s.rjust(2, '0')
result << ':' << start_time.minutes.to_s.rjust(2, '0')
result << ':' << start_time.seconds.to_s.rjust(2, '0')
result << '.' << start_time.milliseconds.to_s.rjust(3, '0')
result << " --> "
# end_time
result << end_time.hours.to_s.rjust(2, '0')
result << ':' << end_time.minutes.to_s.rjust(2, '0')
result << ':' << end_time.seconds.to_s.rjust(2, '0')
result << '.' << end_time.milliseconds.to_s.rjust(3, '0')
result << "\n"
node.children.each do |s|
result << s.content
end
result << "\n"
result << "\n"
end
end
return result
end
# List of all caption languages available on Youtube. # List of all caption languages available on Youtube.
LANGUAGES = { LANGUAGES = {
"", "",

View File

@ -0,0 +1,12 @@
require "json"
struct VideoMusic
include JSON::Serializable
property album : String
property artist : String
property license : String
def initialize(@album : String, @artist : String, @license : String)
end
end

View File

@ -311,6 +311,33 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
end end
end end
# Music section
music_list = [] of VideoMusic
music_desclist = player_response.dig?(
"engagementPanels", 1, "engagementPanelSectionListRenderer",
"content", "structuredDescriptionContentRenderer", "items", 2,
"videoDescriptionMusicSectionRenderer", "carouselLockups"
)
music_desclist.try &.as_a.each do |music_desc|
artist = nil
album = nil
music_license = nil
music_desc.dig?("carouselLockupRenderer", "infoRows").try &.as_a.each do |desc|
desc_title = extract_text(desc.dig?("infoRowRenderer", "title"))
if desc_title == "ARTIST"
artist = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata"))
elsif desc_title == "ALBUM"
album = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata"))
elsif desc_title == "LICENSES"
music_license = extract_text(desc.dig?("infoRowRenderer", "expandedMetadata"))
end
end
music_list << VideoMusic.new(album.to_s, artist.to_s, music_license.to_s)
end
# Author infos # Author infos
author = video_details["author"]?.try &.as_s author = video_details["author"]?.try &.as_s
@ -361,6 +388,8 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
"genre" => JSON::Any.new(genre.try &.as_s || ""), "genre" => JSON::Any.new(genre.try &.as_s || ""),
"genreUcid" => JSON::Any.new(genre_ucid.try &.as_s || ""), "genreUcid" => JSON::Any.new(genre_ucid.try &.as_s || ""),
"license" => JSON::Any.new(license.try &.as_s || ""), "license" => JSON::Any.new(license.try &.as_s || ""),
# Music section
"music" => JSON.parse(music_list.to_json),
# Author infos # Author infos
"author" => JSON::Any.new(author || ""), "author" => JSON::Any.new(author || ""),
"ucid" => JSON::Any.new(ucid || ""), "ucid" => JSON::Any.new(ucid || ""),

View File

@ -39,6 +39,8 @@
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>
<% if query %> <% if query %>
<%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%> <%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%>
<div class="pure-g h-box"> <div class="pure-g h-box">

View File

@ -49,6 +49,8 @@
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-md-4-5"></div> <div class="pure-u-1 pure-u-md-4-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">

View File

@ -1,3 +1,5 @@
<% item_watched = !item.is_a?(SearchChannel | SearchPlaylist | InvidiousPlaylist | Category) && env.get?("user").try &.as(User).watched.index(item.id) != nil %>
<div class="pure-u-1 pure-u-md-1-4"> <div class="pure-u-1 pure-u-md-1-4">
<div class="h-box"> <div class="h-box">
<% case item when %> <% case item when %>
@ -40,6 +42,11 @@
<% if item.length_seconds != 0 %> <% if item.length_seconds != 0 %>
<p class="length"><%= recode_length_seconds(item.length_seconds) %></p> <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
<% end %> <% end %>
<% if item_watched %>
<div class="watched-overlay"></div>
<div class="watched-indicator" data-length="<%= item.length_seconds %>" data-id="<%= item.id %>"></div>
<% end %>
</div> </div>
<% end %> <% end %>
<p dir="auto"><%= HTML.escape(item.title) %></p> <p dir="auto"><%= HTML.escape(item.title) %></p>
@ -67,6 +74,11 @@
<% elsif item.length_seconds != 0 %> <% elsif item.length_seconds != 0 %>
<p class="length"><%= recode_length_seconds(item.length_seconds) %></p> <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
<% end %> <% end %>
<% if item_watched %>
<div class="watched-overlay"></div>
<div class="watched-indicator" data-length="<%= item.length_seconds %>" data-id="<%= item.id %>"></div>
<% end %>
</div> </div>
<% end %> <% end %>
<p dir="auto"><%= HTML.escape(item.title) %></p> <p dir="auto"><%= HTML.escape(item.title) %></p>
@ -124,6 +136,11 @@
<% elsif item.length_seconds != 0 %> <% elsif item.length_seconds != 0 %>
<p class="length"><%= recode_length_seconds(item.length_seconds) %></p> <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
<% end %> <% end %>
<% if item_watched %>
<div class="watched-overlay"></div>
<div class="watched-indicator" data-length="<%= item.length_seconds %>" data-id="<%= item.id %>"></div>
<% end %>
</div> </div>
<% end %> <% end %>
<p dir="auto"><%= HTML.escape(item.title) %></p> <p dir="auto"><%= HTML.escape(item.title) %></p>

View File

@ -62,6 +62,8 @@
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %> <% if page > 1 %>

View File

@ -32,3 +32,5 @@
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>

View File

@ -16,3 +16,5 @@
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>

View File

@ -62,6 +62,8 @@
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %> <% if page > 1 %>

View File

@ -45,3 +45,5 @@
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>

View File

@ -24,6 +24,8 @@
<%- end -%> <%- end -%>
</div> </div>
<script src="/js/watched_indicator.js"></script>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<%- if page > 1 -%> <%- if page > 1 -%>

View File

@ -106,6 +106,8 @@
<% end %> <% end %>
</div> </div>
<script src="/js/watched_indicator.js"></script>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %> <% if page > 1 %>

View File

@ -37,6 +37,8 @@
</div> </div>
<%- end -%> <%- end -%>
<script src="/js/watched_indicator.js"></script>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<%- if query.page > 1 -%> <%- if query.page > 1 -%>

View File

@ -235,6 +235,28 @@ we're going to need to do it here in order to allow for translations.
<hr> <hr>
<% if !video.music.empty? %>
<input id="music-desc-expansion" type="checkbox"/>
<label for="music-desc-expansion">
<h3 id="music-description-title">
<%= translate(locale, "Music in this video") %>
<span class="icon ion-ios-arrow-up"></span>
<span class="icon ion-ios-arrow-down"></span>
</h3>
</label>
<div id="music-description-box">
<% video.music.each do |music| %>
<div class="music-item">
<p id="music-artist"><%= translate(locale, "Artist: ") %><%= music.artist %></p>
<p id="music-album"><%= translate(locale, "Album: ") %><%= music.album %></p>
<p id="music-license"><%= translate(locale, "License: ") %><%= music.license %></p>
</div>
<% end %>
</div>
<hr>
<% end %>
<div id="comments"> <div id="comments">
<% if nojs %> <% if nojs %>
<%= comment_html %> <%= comment_html %>

View File

@ -172,7 +172,17 @@ private module Parsers
# When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube.
# Always simpleText # Always simpleText
# TODO change default value to nil # TODO change default value to nil
subscriber_count = item_contents.dig?("subscriberCountText", "simpleText") subscriber_count = item_contents.dig?("subscriberCountText", "simpleText")
# Since youtube added channel handles, `VideoCountText` holds the number of
# subscribers and `subscriberCountText` holds the handle, except when the
# channel doesn't have a handle (e.g: some topic music channels).
# See https://github.com/iv-org/invidious/issues/3394#issuecomment-1321261688
if !subscriber_count || !subscriber_count.as_s.includes? " subscriber"
subscriber_count = item_contents.dig?("videoCountText", "simpleText")
end
subscriber_count = subscriber_count
.try { |s| short_text_to_number(s.as_s.split(" ")[0]).to_i32 } || 0 .try { |s| short_text_to_number(s.as_s.split(" ")[0]).to_i32 } || 0
# Auto-generated channels doesn't have videoCountText # Auto-generated channels doesn't have videoCountText
@ -682,7 +692,11 @@ module HelperExtractors
# Returns a 0 when it's unable to do so # Returns a 0 when it's unable to do so
def self.get_video_count(container : JSON::Any) : Int32 def self.get_video_count(container : JSON::Any) : Int32
if box = container["videoCountText"]? if box = container["videoCountText"]?
return extract_text(box).try &.gsub(/\D/, "").to_i || 0 if (extracted_text = extract_text(box)) && !extracted_text.includes? " subscriber"
return extracted_text.gsub(/\D/, "").to_i
else
return 0
end
elsif box = container["videoCount"]? elsif box = container["videoCount"]?
return box.as_s.to_i return box.as_s.to_i
else else