Merge branch 'master' of github.com:iv-org/invidious
This commit is contained in:
commit
0242a5ee34
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
|
@ -23,4 +23,4 @@ jobs:
|
|||
stale-pr-label: "stale"
|
||||
ascending: true
|
||||
# Never mark feature requests/enhancements as stale
|
||||
exempt-issue-labels: "feature-request,enhancement"
|
||||
exempt-issue-labels: "feature-request,enhancement,exempt-stale"
|
||||
|
|
|
@ -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.
|
||||
- [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)
|
||||
- [Playlet](https://github.com/iBicha/playlet): Unofficial Youtube client for Roku TV
|
||||
- [Clipious](https://github.com/lamarios/clipious): Unofficial Invidious client for Android
|
||||
|
||||
|
||||
## Liability
|
||||
|
|
|
@ -145,6 +145,24 @@ img.thumbnail {
|
|||
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 {
|
||||
z-index: 100;
|
||||
position: absolute;
|
||||
|
@ -497,7 +515,7 @@ hr {
|
|||
|
||||
#descexpansionbutton ~ div {
|
||||
overflow: hidden;
|
||||
height: 8.3em;
|
||||
max-height: 8.3em;
|
||||
}
|
||||
|
||||
#descexpansionbutton:checked ~ div {
|
||||
|
@ -565,3 +583,7 @@ p,
|
|||
|
||||
/* Wider settings name to less word wrap */
|
||||
.pure-form-aligned .pure-control-group label { width: 19em; }
|
||||
|
||||
.channel-emoji {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
|
24
assets/js/watched_indicator.js
Normal file
24
assets/js/watched_indicator.js
Normal 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
1
locales/af.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -540,5 +540,8 @@
|
|||
"channel_tab_shorts_label": "الفيديوهات القصيرة",
|
||||
"channel_tab_streams_label": "البث المباشر",
|
||||
"channel_tab_playlists_label": "قوائم التشغيل",
|
||||
"channel_tab_channels_label": "القنوات"
|
||||
"channel_tab_channels_label": "القنوات",
|
||||
"Music in this video": "الموسيقى في هذا الفيديو",
|
||||
"Album: ": "الألبوم: ",
|
||||
"Artist: ": "الفنان: "
|
||||
}
|
||||
|
|
|
@ -492,5 +492,8 @@
|
|||
"channel_tab_shorts_label": "Shorts",
|
||||
"channel_tab_playlists_label": "Playlisty",
|
||||
"channel_tab_channels_label": "Kanály",
|
||||
"channel_tab_streams_label": "Živé přenosy"
|
||||
"channel_tab_streams_label": "Živé přenosy",
|
||||
"Music in this video": "Hudba v tomto videu",
|
||||
"Artist: ": "Umělec: ",
|
||||
"Album: ": "Album: "
|
||||
}
|
||||
|
|
|
@ -472,5 +472,12 @@
|
|||
"search_filters_duration_option_none": "Beliebige Länge",
|
||||
"search_filters_date_label": "Upload-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"
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@
|
|||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Μεσαία",
|
||||
"preferences_quality_option_small": "Μικρό",
|
||||
"preferences_quality_option_dash": "DASH (προσαρμοστική ποιότητα)",
|
||||
"preferences_quality_option_dash": "DASH (προσαρμόσιμη ποιότητα)",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"invidious": "Invidious",
|
||||
|
@ -450,5 +450,5 @@
|
|||
"search_filters_type_option_show": "Μπάρα προόδου διαβάσματος",
|
||||
"preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: ",
|
||||
"search_filters_title": "Φίλτρο",
|
||||
"search_message_no_results": "Δεν"
|
||||
"search_message_no_results": "Δε βρέθηκαν αποτελέσματα."
|
||||
}
|
||||
|
|
|
@ -190,6 +190,7 @@
|
|||
"Blacklisted regions: ": "Blacklisted regions: ",
|
||||
"Music in this video": "Music in this video",
|
||||
"Artist: ": "Artist: ",
|
||||
"Song: ": "Song: ",
|
||||
"Album: ": "Album: ",
|
||||
"Shared `x`": "Shared `x`",
|
||||
"Premieres in `x`": "Premieres in `x`",
|
||||
|
@ -405,6 +406,7 @@
|
|||
"YouTube comment permalink": "YouTube comment permalink",
|
||||
"permalink": "permalink",
|
||||
"`x` marked it with a ❤": "`x` marked it with a ❤",
|
||||
"Channel Sponsor": "Channel Sponsor",
|
||||
"Audio mode": "Audio mode",
|
||||
"Video mode": "Video mode",
|
||||
"Playlists": "Playlists",
|
||||
|
@ -454,7 +456,7 @@
|
|||
"footer_documentation": "Documentation",
|
||||
"footer_source_code": "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",
|
||||
"none": "none",
|
||||
"videoinfo_started_streaming_x_ago": "Started streaming `x` ago",
|
||||
|
|
|
@ -476,5 +476,8 @@
|
|||
"channel_tab_streams_label": "Tujelsendoj",
|
||||
"channel_tab_playlists_label": "Ludlistoj",
|
||||
"channel_tab_channels_label": "Kanaloj",
|
||||
"channel_tab_shorts_label": "Mallongaj"
|
||||
"channel_tab_shorts_label": "Mallongaj",
|
||||
"Music in this video": "Muziko en ĉi tiu video",
|
||||
"Artist: ": "Artisto: ",
|
||||
"Album: ": "Albumo: "
|
||||
}
|
||||
|
|
109
locales/es.json
109
locales/es.json
|
@ -52,21 +52,21 @@
|
|||
"preferences_video_loop_label": "Repetir siempre: ",
|
||||
"preferences_autoplay_label": "Reproducción automática: ",
|
||||
"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_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_quality_label": "Calidad de vídeo preferida: ",
|
||||
"preferences_quality_label": "Calidad de video preferida: ",
|
||||
"preferences_volume_label": "Volumen del reproductor: ",
|
||||
"preferences_comments_label": "Comentarios por defecto: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "Subtítulos por defecto: ",
|
||||
"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_extend_desc_label": "Extender automáticamente la descripción del vídeo: ",
|
||||
"preferences_vr_mode_label": "Vídeos interactivos de 360 grados (necesita WebGL): ",
|
||||
"preferences_extend_desc_label": "Extender automáticamente la descripción del video: ",
|
||||
"preferences_vr_mode_label": "Videos interactivos de 360 grados (necesita WebGL): ",
|
||||
"preferences_category_visual": "Preferencias visuales",
|
||||
"preferences_player_style_label": "Estilo de reproductor: ",
|
||||
"Dark mode: ": "Modo oscuro: ",
|
||||
|
@ -79,16 +79,16 @@
|
|||
"preferences_category_subscription": "Preferencias de la suscripción",
|
||||
"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: ",
|
||||
"preferences_max_results_label": "Número de vídeos mostrados en la fuente: ",
|
||||
"preferences_sort_label": "Ordenar los vídeos por: ",
|
||||
"preferences_max_results_label": "Número de videos mostrados en la fuente: ",
|
||||
"preferences_sort_label": "Ordenar los videos por: ",
|
||||
"published": "fecha de publicación",
|
||||
"published - reverse": "fecha de publicación: orden inverso",
|
||||
"alphabetically": "alfabéticamente",
|
||||
"alphabetically - reverse": "alfabéticamente: orden inverso",
|
||||
"channel name": "nombre del canal",
|
||||
"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 unwatched video from channel: ": "Mostrar solo el último vídeo sin ver 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 video sin ver del canal: ",
|
||||
"preferences_unseen_only_label": "Mostrar solo los no vistos: ",
|
||||
"preferences_notifications_only_label": "Mostrar solo notificaciones (si hay alguna): ",
|
||||
"Enable web notifications": "Habilitar notificaciones web",
|
||||
|
@ -139,7 +139,7 @@
|
|||
"Editing playlist `x`": "Editando la lista de reproducción 'x'",
|
||||
"Show more": "Mostrar más",
|
||||
"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",
|
||||
"Hide annotations": "Ocultar anotaciones",
|
||||
"Show annotations": "Mostrar anotaciones",
|
||||
|
@ -153,7 +153,7 @@
|
|||
"Shared `x`": "Compartido `x`",
|
||||
"Premieres in `x`": "Se estrena en `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 more comments on Reddit": "Ver más comentarios en Reddit",
|
||||
"View `x` comments": {
|
||||
|
@ -164,7 +164,7 @@
|
|||
"Hide replies": "Ocultar las respuestas",
|
||||
"Show replies": "Mostrar las respuestas",
|
||||
"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.",
|
||||
"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.",
|
||||
|
@ -176,7 +176,7 @@
|
|||
"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»",
|
||||
"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",
|
||||
"Invidious Private Feed for `x`": "Fuente privada de Invidious para `x`",
|
||||
"channel:`x`": "canal: `x`",
|
||||
|
@ -198,7 +198,7 @@
|
|||
"No such user": "Usuario no existe",
|
||||
"Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo",
|
||||
"English": "Inglés",
|
||||
"English (auto-generated)": "Inglés (generados automáticamente)",
|
||||
"English (auto-generated)": "Inglés (generado automáticamente)",
|
||||
"Afrikaans": "Afrikáans",
|
||||
"Albanian": "Albanés",
|
||||
"Amharic": "Amárico",
|
||||
|
@ -324,50 +324,51 @@
|
|||
"permalink": "enlace permanente",
|
||||
"`x` marked it with a ❤": "`x` lo ha marcado con un ❤",
|
||||
"Audio mode": "Modo de audio",
|
||||
"Video mode": "Modo de vídeo",
|
||||
"channel_tab_videos_label": "Vídeos",
|
||||
"Video mode": "Modo de video",
|
||||
"channel_tab_videos_label": "Videos",
|
||||
"Playlists": "Listas de reproducción",
|
||||
"channel_tab_community_label": "Comunidad",
|
||||
"search_filters_sort_option_relevance": "relevancia",
|
||||
"search_filters_sort_option_rating": "valoración",
|
||||
"search_filters_sort_option_date": "fecha",
|
||||
"search_filters_sort_option_views": "visualizaciones",
|
||||
"search_filters_type_label": "content_type",
|
||||
"search_filters_sort_option_relevance": "Relevancia",
|
||||
"search_filters_sort_option_rating": "Valoración",
|
||||
"search_filters_sort_option_date": "Fecha de subida",
|
||||
"search_filters_sort_option_views": "Visualizaciones",
|
||||
"search_filters_type_label": "tipo de contenido",
|
||||
"search_filters_duration_label": "duración",
|
||||
"search_filters_features_label": "funcionalidades",
|
||||
"search_filters_sort_label": "ordenar",
|
||||
"search_filters_date_option_hour": "hora",
|
||||
"search_filters_date_option_today": "hoy",
|
||||
"search_filters_date_option_week": "semana",
|
||||
"search_filters_date_option_month": "mes",
|
||||
"search_filters_date_option_year": "año",
|
||||
"search_filters_type_option_video": "vídeo",
|
||||
"search_filters_type_option_channel": "canal",
|
||||
"search_filters_type_option_playlist": "lista de reproducción",
|
||||
"search_filters_type_option_movie": "película",
|
||||
"search_filters_type_option_show": "programa",
|
||||
"search_filters_features_option_hd": "hd",
|
||||
"search_filters_features_option_subtitles": "subtítulos",
|
||||
"search_filters_features_option_c_commons": "creative_commons",
|
||||
"search_filters_features_option_three_d": "3d",
|
||||
"search_filters_features_option_live": "directo",
|
||||
"search_filters_features_option_four_k": "4k",
|
||||
"search_filters_features_option_location": "ubicación",
|
||||
"search_filters_features_option_hdr": "hdr",
|
||||
"search_filters_date_option_hour": "Última hora",
|
||||
"search_filters_date_option_today": "Hoy",
|
||||
"search_filters_date_option_week": "Esta semana",
|
||||
"search_filters_date_option_month": "Este mes",
|
||||
"search_filters_date_option_year": "Este año",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Canal",
|
||||
"search_filters_type_option_playlist": "Lista de reproducción",
|
||||
"search_filters_type_option_movie": "Película",
|
||||
"search_filters_type_option_show": "Programa",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Subtítulos",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "En directo",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Ubicación",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Versión actual: ",
|
||||
"next_steps_error_message": "Después de lo cual debes intentar: ",
|
||||
"next_steps_error_message_refresh": "Recargar la página",
|
||||
"next_steps_error_message_go_to_youtube": "Ir a YouTube",
|
||||
"search_filters_duration_option_short": "Corto (< 4 minutos)",
|
||||
"search_filters_duration_option_long": "Largo (> 20 minutos)",
|
||||
"search_filters_duration_option_short": "Menos de 4 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_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_modfied_source_code": "Código fuente modificado",
|
||||
"footer_donate_page": "Donar",
|
||||
"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_medium": "Intermedia",
|
||||
"preferences_quality_dash_option_auto": "Automática",
|
||||
|
@ -376,7 +377,7 @@
|
|||
"download_subtitles": "Subtítulos- `x` (.vtt)",
|
||||
"user_created_playlists": "`x` listas de reproducción creadas",
|
||||
"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",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
|
@ -413,8 +414,8 @@
|
|||
"generic_count_weeks_plural": "{{count}} semanas",
|
||||
"generic_playlists_count": "{{count}} lista de reproducción",
|
||||
"generic_playlists_count_plural": "{{count}} listas de reproducción",
|
||||
"generic_videos_count": "{{count}} vídeo",
|
||||
"generic_videos_count_plural": "{{count}} vídeos",
|
||||
"generic_videos_count": "{{count}} video",
|
||||
"generic_videos_count_plural": "{{count}} videos",
|
||||
"generic_count_months": "{{count}} mes",
|
||||
"generic_count_months_plural": "{{count}} meses",
|
||||
"comments_points_count": "{{count}} punto",
|
||||
|
@ -433,7 +434,7 @@
|
|||
"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_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)",
|
||||
"Cantonese (Hong Kong)": "Cantonés (Hong Kong)",
|
||||
"Dutch (auto-generated)": "Neerlandés (generados automáticamente)",
|
||||
|
@ -461,20 +462,22 @@
|
|||
"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_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_type_option_all": "Cualquier tipo",
|
||||
"search_filters_duration_option_none": "Cualquier duración",
|
||||
"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_plural": "{{count}} fichas",
|
||||
"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? ",
|
||||
"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"
|
||||
"channel_tab_playlists_label": "Listas de reproducción",
|
||||
"Music in this video": "Música en este video",
|
||||
"Artist: ": "Artista: ",
|
||||
"Album: ": "Álbum: "
|
||||
}
|
||||
|
|
|
@ -408,9 +408,9 @@
|
|||
"preferences_region_label": "کشور محتوا: ",
|
||||
"footer_documentation": "مستندات",
|
||||
"footer_original_source_code": "کد منبع اصلی",
|
||||
"search_filters_duration_option_long": "بلند (> 20 دقیقه)",
|
||||
"search_filters_duration_option_long": "بلند (> ۲۰ دقیقه)",
|
||||
"adminprefs_modified_source_code_url_label": "URL مخزن کد منبع ویریش شده",
|
||||
"search_filters_duration_option_short": "کوتاه (< 4 دقیقه)",
|
||||
"search_filters_duration_option_short": "کوتاه (< ۴ دقیقه)",
|
||||
"search_filters_title": "پالایه",
|
||||
"Chinese (Hong Kong)": "چینی (هنگکنگ)",
|
||||
"Dutch (auto-generated)": "هلندی (تولید خودکار)",
|
||||
|
@ -424,5 +424,26 @@
|
|||
"search_message_no_results": "نتیجهای یافت نشد.",
|
||||
"search_message_change_filters_or_query": "سعی کنید جستوجوی خود را وسیعتر کنید و/یا فیلترها را تغییر دهید.",
|
||||
"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)": "اسپانیایی (مکزیک)"
|
||||
}
|
||||
|
|
|
@ -470,5 +470,14 @@
|
|||
"crash_page_switch_instance": "<a href=\"`x`\">किसी दूसरे उदाहरण का इस्तेमाल करें</a>",
|
||||
"crash_page_read_the_faq": "<a href=\"`x`\">अक्सर पूछे जाने वाले प्रश्न (FAQ)</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": "चैनल्स"
|
||||
}
|
||||
|
|
|
@ -359,13 +359,13 @@
|
|||
"next_steps_error_message_refresh": "Aktualiziraj stranicu",
|
||||
"next_steps_error_message_go_to_youtube": "Idi na YouTube",
|
||||
"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_long": "Dugo (> 20 minute)",
|
||||
"footer_source_code": "Izvorni kod",
|
||||
"footer_modfied_source_code": "Izmijenjeni izvorni kod",
|
||||
"footer_modfied_source_code": "Prilagođen izvorni kod",
|
||||
"footer_documentation": "Dokumentacija",
|
||||
"footer_original_source_code": "Izvoran izvorni kod",
|
||||
"footer_original_source_code": "Prvobitan izvorni kod",
|
||||
"preferences_region_label": "Zemlja sadržaja: ",
|
||||
"preferences_quality_dash_label": "Preferirana DASH videokvaliteta: ",
|
||||
"preferences_quality_option_dash": "DASH (adaptativna kvaliteta)",
|
||||
|
@ -492,5 +492,8 @@
|
|||
"channel_tab_streams_label": "Prijenosi uživo",
|
||||
"channel_tab_playlists_label": "Zbirke",
|
||||
"channel_tab_channels_label": "Kanali",
|
||||
"channel_tab_shorts_label": "Kratka videa"
|
||||
"channel_tab_shorts_label": "Kratka videa",
|
||||
"Music in this video": "Glazba u ovom videu",
|
||||
"Album: ": "Album: ",
|
||||
"Artist: ": "Izvođač: "
|
||||
}
|
||||
|
|
|
@ -476,5 +476,8 @@
|
|||
"channel_tab_playlists_label": "Playlist",
|
||||
"channel_tab_channels_label": "Canali",
|
||||
"channel_tab_streams_label": "Livestream",
|
||||
"channel_tab_community_label": "Comunità"
|
||||
"channel_tab_community_label": "Comunità",
|
||||
"Music in this video": "Musica in questo video",
|
||||
"Artist: ": "Artista: ",
|
||||
"Album: ": "Album: "
|
||||
}
|
||||
|
|
130
locales/ja.json
130
locales/ja.json
|
@ -5,7 +5,7 @@
|
|||
"generic_subscribers_count_0": "{{count}} 人の登録者",
|
||||
"generic_subscriptions_count_0": "{{count}} 個の登録チャンネル",
|
||||
"LIVE": "ライブ",
|
||||
"Shared `x` ago": "`x`前に共有",
|
||||
"Shared `x` ago": "`x`前に公開",
|
||||
"Unsubscribe": "登録解除",
|
||||
"Subscribe": "登録",
|
||||
"View channel on YouTube": "YouTube でチャンネルを見る",
|
||||
|
@ -53,34 +53,34 @@
|
|||
"E-mail": "メールアドレス",
|
||||
"Google verification code": "Google 認証コード",
|
||||
"Preferences": "設定",
|
||||
"preferences_category_player": "プレイヤー設定",
|
||||
"preferences_category_player": "プレイヤーの設定",
|
||||
"preferences_video_loop_label": "常にループ: ",
|
||||
"preferences_autoplay_label": "自動再生: ",
|
||||
"preferences_continue_label": "デフォルトで次を再生: ",
|
||||
"preferences_continue_label": "次の動画を再生: ",
|
||||
"preferences_continue_autoplay_label": "次の動画を自動再生: ",
|
||||
"preferences_listen_label": "デフォルトでオーディオモードを使用: ",
|
||||
"preferences_local_label": "動画をプロキシーに通す: ",
|
||||
"preferences_speed_label": "デフォルトの再生速度: ",
|
||||
"preferences_listen_label": "デフォルトで音声モードを使用: ",
|
||||
"preferences_local_label": "動画視聴にプロキシーを経由: ",
|
||||
"preferences_speed_label": "標準の再生速度: ",
|
||||
"preferences_quality_label": "優先する画質: ",
|
||||
"preferences_volume_label": "プレイヤーの音量: ",
|
||||
"preferences_comments_label": "デフォルトのコメント: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "デフォルトの字幕: ",
|
||||
"preferences_captions_label": "優先する字幕: ",
|
||||
"Fallback captions: ": "フォールバック時の字幕: ",
|
||||
"preferences_related_videos_label": "関連動画を表示: ",
|
||||
"preferences_annotations_label": "デフォルトでアノテーションを表示: ",
|
||||
"preferences_extend_desc_label": "動画の説明文を自動的に拡張: ",
|
||||
"preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ",
|
||||
"preferences_category_visual": "外観設定",
|
||||
"preferences_player_style_label": "プレイヤースタイル: ",
|
||||
"preferences_player_style_label": "プレイヤーのスタイル: ",
|
||||
"Dark mode: ": "ダークモード: ",
|
||||
"preferences_dark_mode_label": "テーマ: ",
|
||||
"dark": "ダーク",
|
||||
"light": "ライト",
|
||||
"preferences_thin_mode_label": "最小モード: ",
|
||||
"preferences_category_misc": "雑設定",
|
||||
"preferences_automatic_instance_redirect_label": "自動的なインスタンスの移転(redirect.invidious.ioにフォールバック): ",
|
||||
"preferences_category_misc": "ほかの設定",
|
||||
"preferences_automatic_instance_redirect_label": "インスタンスの自動転送 (redirect.invidious.ioにフォールバック): ",
|
||||
"preferences_category_subscription": "登録チャンネル設定",
|
||||
"preferences_annotations_subscribed_label": "デフォルトで登録チャンネルのアノテーションを表示しますか? ",
|
||||
"Redirect homepage to feed: ": "ホームからフィードにリダイレクト: ",
|
||||
|
@ -108,7 +108,7 @@
|
|||
"Watch history": "再生履歴",
|
||||
"Delete account": "アカウントを削除",
|
||||
"preferences_category_admin": "管理者設定",
|
||||
"preferences_default_home_label": "デフォルトのホーム: ",
|
||||
"preferences_default_home_label": "ホームに表示するページ: ",
|
||||
"preferences_feed_menu_label": "フィードメニュー: ",
|
||||
"preferences_show_nick_label": "ニックネームを一番上に表示する: ",
|
||||
"Top enabled: ": "トップページを有効化: ",
|
||||
|
@ -117,8 +117,8 @@
|
|||
"Registration enabled: ": "登録を有効化: ",
|
||||
"Report statistics: ": "統計を報告: ",
|
||||
"Save preferences": "設定を保存",
|
||||
"Subscription manager": "登録チャンネルマネージャー",
|
||||
"Token manager": "トークンマネージャー",
|
||||
"Subscription manager": "登録チャンネルの管理",
|
||||
"Token manager": "トークンの管理",
|
||||
"Token": "トークン",
|
||||
"tokens_count_0": "{{count}} 個のトークン",
|
||||
"Import/export": "インポート/エクスポート",
|
||||
|
@ -128,7 +128,7 @@
|
|||
"subscriptions_unseen_notifs_count_0": "{{count}} 個の未読通知",
|
||||
"search": "検索",
|
||||
"Log out": "ログアウト",
|
||||
"Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開されています。",
|
||||
"Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開",
|
||||
"Source available here.": "ソースはここで閲覧可能です。",
|
||||
"View JavaScript license information.": "JavaScript ライセンス情報",
|
||||
"View privacy policy.": "プライバシーポリシー",
|
||||
|
@ -136,28 +136,28 @@
|
|||
"Public": "公開",
|
||||
"Unlisted": "限定公開",
|
||||
"Private": "非公開",
|
||||
"View all playlists": "再生リストをすべて見る",
|
||||
"View all playlists": "すべての再生リストを表示",
|
||||
"Updated `x` ago": "`x`前に更新",
|
||||
"Delete playlist `x`?": "再生リスト `x` を削除しますか?",
|
||||
"Delete playlist": "再生リストを削除",
|
||||
"Create playlist": "再生リストを作成",
|
||||
"Title": "タイトル",
|
||||
"Playlist privacy": "再生リストのプライバシー",
|
||||
"Playlist privacy": "再生リストの公開設定",
|
||||
"Editing playlist `x`": "再生リスト `x` を編集中",
|
||||
"Show more": "表示を増やす",
|
||||
"Show less": "表示を減らす",
|
||||
"Show more": "もっと見る",
|
||||
"Show less": "表示を少なく",
|
||||
"Watch on YouTube": "YouTube で視聴",
|
||||
"Switch Invidious Instance": "Invidiousインスタンスの変更",
|
||||
"Switch Invidious Instance": "Invidious インスタンスの変更",
|
||||
"Hide annotations": "アノテーションを隠す",
|
||||
"Show annotations": "アノテーションを表示",
|
||||
"Genre: ": "ジャンル: ",
|
||||
"License: ": "ライセンス: ",
|
||||
"Family friendly? ": "家族向け: ",
|
||||
"Wilson score: ": "ウィルソンスコア: ",
|
||||
"Wilson score: ": "ウィルソン得点区間: ",
|
||||
"Engagement: ": "エンゲージメント: ",
|
||||
"Whitelisted regions: ": "ホワイトリストの地域: ",
|
||||
"Blacklisted regions: ": "ブラックリストの地域: ",
|
||||
"Shared `x`": "`x`に共有",
|
||||
"Shared `x`": "公開日 `x`",
|
||||
"Premieres in `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 を無効にしているのかな?ここをクリックしてコメントを見れるけど、読み込みには少し時間がかかることがあるのを覚えておいてね。",
|
||||
|
@ -181,31 +181,31 @@
|
|||
"User ID is a required field": "ユーザー ID は必須項目です",
|
||||
"Password is a required field": "パスワードは必須項目です",
|
||||
"Wrong username or password": "ユーザー名またはパスワードが間違っています",
|
||||
"Please sign in using 'Log in with Google'": "'Google でログイン' を使用してログインしてください",
|
||||
"Password cannot be empty": "パスワードを空にすることはできません",
|
||||
"Please sign in using 'Log in with Google'": "「Google でログイン」を使用してログインしてください",
|
||||
"Password cannot be empty": "パスワードは空にできません",
|
||||
"Password cannot be longer than 55 characters": "パスワードは55文字より長くできません",
|
||||
"Please log in": "ログインをしてください",
|
||||
"Invidious Private Feed for `x`": "`x` の Invidious プライベートフィード",
|
||||
"Please log in": "ログインしてください",
|
||||
"Invidious Private Feed for `x`": "`x` 個人の Invidious によるフィード",
|
||||
"channel:`x`": "チャンネル:`x`",
|
||||
"Deleted or invalid channel": "削除済みまたは無効なチャンネルです",
|
||||
"This channel does not exist.": "このチャンネルは存在しません。",
|
||||
"Could not get channel info.": "チャンネル情報を取得できませんでした。",
|
||||
"Could not fetch comments": "コメントを取得できませんでした",
|
||||
"comments_view_x_replies_0": "{{count}} 件の返信を見る",
|
||||
"comments_view_x_replies_0": "{{count}}件の返信を表示",
|
||||
"`x` ago": "`x`前",
|
||||
"Load more": "もっと読み込む",
|
||||
"comments_points_count_0": "{{count}} ポイント",
|
||||
"Load more": "もっと見る",
|
||||
"comments_points_count_0": "{{count}}点",
|
||||
"Could not create mix.": "ミックスを作成できませんでした。",
|
||||
"Empty playlist": "空の再生リスト",
|
||||
"Not a playlist.": "再生リストではありません。",
|
||||
"Playlist does not exist.": "再生リストが存在しません。",
|
||||
"Could not pull trending pages.": "急上昇ページを取得できませんでした。",
|
||||
"Hidden field \"challenge\" is a required field": "非表示項目 \"challenge\" は必須項目です",
|
||||
"Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です",
|
||||
"Hidden field \"challenge\" is a required field": "非表示項目 challenge は必須項目です",
|
||||
"Hidden field \"token\" is a required field": "非表示項目 token は必須項目です",
|
||||
"Erroneous challenge": "チャレンジが間違っています",
|
||||
"Erroneous token": "トークンが間違っています",
|
||||
"No such user": "ユーザーが存在しません",
|
||||
"Token is expired, please try again": "トークンが期限切れです。再度試してください",
|
||||
"Token is expired, please try again": "トークンが期限切れです。再度お試しください",
|
||||
"English": "英語",
|
||||
"English (auto-generated)": "英語 (自動生成)",
|
||||
"Afrikaans": "アフリカーンス語",
|
||||
|
@ -313,7 +313,7 @@
|
|||
"Yoruba": "ヨルバ語",
|
||||
"Zulu": "ズール語",
|
||||
"generic_count_years_0": "{{count}}年",
|
||||
"generic_count_months_0": "{{count}}ヶ月",
|
||||
"generic_count_months_0": "{{count}}か月",
|
||||
"generic_count_weeks_0": "{{count}}週",
|
||||
"generic_count_days_0": "{{count}}日",
|
||||
"generic_count_hours_0": "{{count}}時間",
|
||||
|
@ -338,21 +338,21 @@
|
|||
"(edited)": "(編集済み)",
|
||||
"YouTube comment permalink": "YouTube コメントのパーマリンク",
|
||||
"permalink": "パーマリンク",
|
||||
"`x` marked it with a ❤": "`x` が❤を込めてマークしました",
|
||||
"Audio mode": "オーディオモード",
|
||||
"Video mode": "ビデオモード",
|
||||
"`x` marked it with a ❤": "`x` が❤を送りました",
|
||||
"Audio mode": "音声モード",
|
||||
"Video mode": "動画モード",
|
||||
"channel_tab_videos_label": "動画",
|
||||
"Playlists": "プレイリスト",
|
||||
"Playlists": "再生リスト",
|
||||
"channel_tab_community_label": "コミュニティ",
|
||||
"search_filters_sort_option_relevance": "関連",
|
||||
"search_filters_sort_option_relevance": "関連度",
|
||||
"search_filters_sort_option_rating": "評価",
|
||||
"search_filters_sort_option_date": "時刻",
|
||||
"search_filters_sort_option_date": "アップロード日",
|
||||
"search_filters_sort_option_views": "再生回数",
|
||||
"search_filters_type_label": "コンテンツの種類",
|
||||
"search_filters_type_label": "種類",
|
||||
"search_filters_duration_label": "再生時間",
|
||||
"search_filters_features_label": "機能",
|
||||
"search_filters_features_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_week": "今週",
|
||||
"search_filters_date_option_month": "今月",
|
||||
|
@ -366,7 +366,7 @@
|
|||
"search_filters_features_option_subtitles": "字幕",
|
||||
"search_filters_features_option_c_commons": "クリエイティブ・コモンズ",
|
||||
"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_location": "場所",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
|
@ -377,9 +377,9 @@
|
|||
"search_filters_duration_option_short": "4 分未満",
|
||||
"footer_documentation": "文書",
|
||||
"footer_source_code": "ソースコード",
|
||||
"footer_original_source_code": "ソースコード(元)",
|
||||
"footer_modfied_source_code": "ソースコード(編集)",
|
||||
"adminprefs_modified_source_code_url_label": "編集したソースコードのレポジトリーURL",
|
||||
"footer_original_source_code": "元のソースコード",
|
||||
"footer_modfied_source_code": "改変して使用",
|
||||
"adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL",
|
||||
"search_filters_duration_option_long": "20 分以上",
|
||||
"preferences_region_label": "地域: ",
|
||||
"footer_donate_page": "寄付する",
|
||||
|
@ -406,10 +406,10 @@
|
|||
"preferences_quality_option_dash": "DASH (適応品質)",
|
||||
"preferences_quality_dash_option_worst": "最悪",
|
||||
"preferences_quality_dash_option_best": "最高",
|
||||
"videoinfo_started_streaming_x_ago": "`x`分前に配信を開始",
|
||||
"videoinfo_started_streaming_x_ago": "`x`前に配信を開始",
|
||||
"videoinfo_watch_on_youTube": "YouTube上で見る",
|
||||
"user_created_playlists": "`x`が作成したプレイリスト",
|
||||
"Video unavailable": "ビデオは利用できません",
|
||||
"user_created_playlists": "`x`個の作成した再生リスト",
|
||||
"Video unavailable": "動画は利用できません",
|
||||
"Chinese": "中国語",
|
||||
"Chinese (Taiwan)": "中国語 (台湾)",
|
||||
"Korean (auto-generated)": "韓国語 (自動生成)",
|
||||
|
@ -434,24 +434,34 @@
|
|||
"Vietnamese (auto-generated)": "ベトナム語 (自動生成)",
|
||||
"search_filters_title": "フィルタ",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_message_change_filters_or_query": "別のキーワードを試してみるか、検索フィルタを削除してください",
|
||||
"search_message_no_results": "一致する検索結果はありませんでした",
|
||||
"search_message_change_filters_or_query": "別の検索語句を試したり、検索フィルタを変更してください。",
|
||||
"search_message_no_results": "一致する検索結果はありません。",
|
||||
"English (United States)": "英語 (アメリカ)",
|
||||
"search_filters_date_label": "アップロード日",
|
||||
"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> を読む",
|
||||
"Popular enabled: ": "人気動画を有効化 ",
|
||||
"search_message_use_another_instance": " <a href=\"`x`\">別のインスタンスで検索</a>することもできます。",
|
||||
"search_message_use_another_instance": " <a href=\"`x`\">別のインスタンス上でも検索</a>できます。",
|
||||
"search_filters_apply_button": "選択したフィルターを適用",
|
||||
"user_saved_playlists": "`x` 個の保存済みプレイリスト",
|
||||
"user_saved_playlists": "`x` 個の保存した再生リスト",
|
||||
"crash_page_you_found_a_bug": "Invidious でバグを見つけたようです。",
|
||||
"crash_page_refresh": "<a href=\"`x`\">ページを更新</a>しようとしました",
|
||||
"preferences_watch_history_label": "視聴履歴を有効化 ",
|
||||
"search_filters_date_option_none": "任意の日付",
|
||||
"search_filters_type_option_all": "いかなるタイプ",
|
||||
"search_filters_duration_option_none": "任意の期間",
|
||||
"search_filters_duration_option_medium": "ミディアム (4 ~ 20 分)",
|
||||
"crash_page_refresh": "<a href=\"`x`\">ページを更新</a>を試す",
|
||||
"preferences_watch_history_label": "再生履歴を有効化 ",
|
||||
"search_filters_date_option_none": "すべて",
|
||||
"search_filters_type_option_all": "すべての種類",
|
||||
"search_filters_duration_option_none": "すべての長さ",
|
||||
"search_filters_duration_option_medium": "4 ~ 20 分",
|
||||
"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: ": "アルバム: "
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
"preferences_annotations_label": "Domyślnie pokazuj adnotacje: ",
|
||||
"preferences_extend_desc_label": "Automatycznie rozwijaj opisy filmów: ",
|
||||
"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: ",
|
||||
"Dark mode: ": "Ciemny motyw: ",
|
||||
"preferences_dark_mode_label": "Motyw: ",
|
||||
|
@ -443,7 +443,7 @@
|
|||
"user_saved_playlists": "`x` zapisanych playlist",
|
||||
"Video unavailable": "Film niedostępny",
|
||||
"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.",
|
||||
"search_filters_duration_option_short": "Krótka (< 4 minut)",
|
||||
"search_filters_duration_option_long": "Długa (> 20 minut)",
|
||||
|
@ -481,7 +481,7 @@
|
|||
"search_message_no_results": "Nie znaleziono wyników.",
|
||||
"preferences_watch_history_label": "Włącz historię oglądania: ",
|
||||
"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_features_option_vr180": "VR180",
|
||||
"search_filters_date_option_none": "Dowolna data",
|
||||
|
@ -492,5 +492,8 @@
|
|||
"channel_tab_streams_label": "Na żywo",
|
||||
"channel_tab_channels_label": "Kanały",
|
||||
"channel_tab_playlists_label": "Playlisty",
|
||||
"channel_tab_shorts_label": "Shorts"
|
||||
"channel_tab_shorts_label": "Shorts",
|
||||
"Music in this video": "Muzyka w tym filmie",
|
||||
"Artist: ": "Wykonawca: ",
|
||||
"Album: ": "Album: "
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@
|
|||
"footer_documentation": "Documentação",
|
||||
"footer_source_code": "Código fonte",
|
||||
"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_region_label": "País do conteúdo: ",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
|
@ -472,5 +472,12 @@
|
|||
"search_filters_duration_option_medium": "Médio (4 - 20 minutos)",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"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: "
|
||||
}
|
||||
|
|
|
@ -472,5 +472,12 @@
|
|||
"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_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"
|
||||
}
|
||||
|
|
|
@ -472,5 +472,12 @@
|
|||
"search_filters_type_option_all": "Qualquer tipo",
|
||||
"search_filters_duration_option_none": "Qualquer duração",
|
||||
"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: "
|
||||
}
|
||||
|
|
|
@ -69,11 +69,11 @@
|
|||
"preferences_vr_mode_label": "Интерактивные 360-градусные видео (необходим WebGL): ",
|
||||
"preferences_category_visual": "Настройки сайта",
|
||||
"preferences_player_style_label": "Стиль проигрывателя: ",
|
||||
"Dark mode: ": "Тёмное оформление: ",
|
||||
"Dark mode: ": "Темное оформление: ",
|
||||
"preferences_dark_mode_label": "Тема: ",
|
||||
"dark": "тёмная",
|
||||
"dark": "темная",
|
||||
"light": "светлая",
|
||||
"preferences_thin_mode_label": "Облегчённое оформление: ",
|
||||
"preferences_thin_mode_label": "Облегченное оформление: ",
|
||||
"preferences_category_misc": "Прочие настройки",
|
||||
"preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ",
|
||||
"preferences_category_subscription": "Настройки подписок",
|
||||
|
@ -88,7 +88,7 @@
|
|||
"channel name": "по названию канала",
|
||||
"channel name - reverse": "по названию канала в обратном порядке",
|
||||
"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_notifications_only_label": "Показывать только оповещения, если они есть: ",
|
||||
"Enable web notifications": "Включить уведомления в браузере",
|
||||
|
@ -147,13 +147,13 @@
|
|||
"License: ": "Лицензия: ",
|
||||
"Family friendly? ": "Семейный просмотр: ",
|
||||
"Wilson score: ": "Оценка Уилсона: ",
|
||||
"Engagement: ": "Вовлечённость: ",
|
||||
"Engagement: ": "Вовлеченность: ",
|
||||
"Whitelisted regions: ": "Доступно в регионах: ",
|
||||
"Blacklisted regions: ": "Недоступно в регионах: ",
|
||||
"Shared `x`": "Опубликовано `x`",
|
||||
"Premieres in `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 more comments on Reddit": "Посмотреть больше комментариев на Reddit",
|
||||
"View `x` comments": {
|
||||
|
@ -180,23 +180,23 @@
|
|||
"Please log in": "Пожалуйста, войдите",
|
||||
"Invidious Private Feed for `x`": "Приватная лента Invidious для `x`",
|
||||
"channel:`x`": "канал: `x`",
|
||||
"Deleted or invalid channel": "Канал удалён или не найден",
|
||||
"Deleted or invalid channel": "Канал удален или не найден",
|
||||
"This channel does not exist.": "Такого канала не существует.",
|
||||
"Could not get channel info.": "Не удаётся получить информацию об этом канале.",
|
||||
"Could not fetch comments": "Не удаётся загрузить комментарии",
|
||||
"Could not get channel info.": "Не удается получить информацию об этом канале.",
|
||||
"Could not fetch comments": "Не удается загрузить комментарии",
|
||||
"`x` ago": "`x` назад",
|
||||
"Load more": "Загрузить ещё",
|
||||
"Load more": "Загрузить еще",
|
||||
"Could not create mix.": "Не удалось создать микс.",
|
||||
"Empty playlist": "Плейлист пуст",
|
||||
"Not a playlist.": "Некорректный плейлист.",
|
||||
"Not a playlist.": "Это не плейлист.",
|
||||
"Playlist does not exist.": "Плейлист не существует.",
|
||||
"Could not pull trending pages.": "Не удаётся загрузить страницы «в тренде».",
|
||||
"Could not pull trending pages.": "Не удается загрузить страницы «в тренде».",
|
||||
"Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»",
|
||||
"Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»",
|
||||
"Erroneous challenge": "Неправильный ответ в «challenge»",
|
||||
"Erroneous token": "Неправильный токен",
|
||||
"No such user": "Пользователь не найден",
|
||||
"Token is expired, please try again": "Срок действия токена истёк, попробуйте позже",
|
||||
"Token is expired, please try again": "Срок действия токена истек, попробуйте позже",
|
||||
"English": "Английский",
|
||||
"English (auto-generated)": "Английский (созданы автоматически)",
|
||||
"Afrikaans": "Африкаанс",
|
||||
|
@ -379,7 +379,7 @@
|
|||
"Turkish (auto-generated)": "Турецкий (созданы автоматически)",
|
||||
"Vietnamese (auto-generated)": "Вьетнамский (созданы автоматически)",
|
||||
"footer_documentation": "Документация",
|
||||
"adminprefs_modified_source_code_url_label": "Ссылка на нашу ветку репозитория",
|
||||
"adminprefs_modified_source_code_url_label": "URL-адрес репозитория измененного исходного кода",
|
||||
"none": "ничего",
|
||||
"videoinfo_watch_on_youTube": "Смотреть на YouTube",
|
||||
"videoinfo_youTube_embed_link": "Версия для встраивания",
|
||||
|
@ -453,8 +453,8 @@
|
|||
"Portuguese (Brazil)": "Португальский (Бразилия)",
|
||||
"footer_source_code": "Исходный код",
|
||||
"footer_original_source_code": "Оригинальный исходный код",
|
||||
"footer_modfied_source_code": "Изменённый исходный код",
|
||||
"user_saved_playlists": "`x` сохранённых плейлистов",
|
||||
"footer_modfied_source_code": "Измененный исходный код",
|
||||
"user_saved_playlists": "`x` сохраненных плейлистов",
|
||||
"crash_page_search_issue": "поискали <a href=\"`x`\">похожую проблему на GitHub</a>",
|
||||
"comments_points_count_0": "{{count}} плюс",
|
||||
"comments_points_count_1": "{{count}} плюса",
|
||||
|
@ -488,5 +488,12 @@
|
|||
"search_filters_duration_option_medium": "Средние (4 - 20 минут)",
|
||||
"search_filters_apply_button": "Применить фильтры",
|
||||
"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: ": "Альбом: "
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@
|
|||
"generic_count_years_2": "{{count}} leti",
|
||||
"generic_count_years_3": "{{count}} leti",
|
||||
"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_3": "{{count}} dnevi",
|
||||
"generic_count_hours_0": "{{count}} uro",
|
||||
|
@ -246,10 +246,10 @@
|
|||
"generic_videos_count_1": "{{count}} videa",
|
||||
"generic_videos_count_2": "{{count}} videi",
|
||||
"generic_videos_count_3": "{{count}} videov",
|
||||
"generic_views_count_0": "{{count}} ogled",
|
||||
"generic_views_count_1": "{{count}} ogleda",
|
||||
"generic_views_count_2": "{{count}} ogledi",
|
||||
"generic_views_count_3": "{{count}} ogledov",
|
||||
"generic_views_count_0": "Ogledov: {{count}}",
|
||||
"generic_views_count_1": "Ogledov: {{count}}",
|
||||
"generic_views_count_2": "Ogledov: {{count}}",
|
||||
"generic_views_count_3": "Ogledov: {{count}}",
|
||||
"generic_playlists_count_0": "{{count}} seznam predvajanja",
|
||||
"generic_playlists_count_1": "{{count}} seznama predvajanja",
|
||||
"generic_playlists_count_2": "{{count}} seznami predvajanja",
|
||||
|
@ -495,7 +495,7 @@
|
|||
"footer_modfied_source_code": "Spremenjena izvorna koda",
|
||||
"user_created_playlists": "`x` ustvarjenih seznamov predvajanja",
|
||||
"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",
|
||||
"crash_page_switch_instance": "poskušal/a <a href=\"`x`\">uporabiti drugo instanco</a>",
|
||||
"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_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: ",
|
||||
"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: "
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@
|
|||
"search_filters_type_option_show": "Shfaqe",
|
||||
"search_filters_duration_option_short": "E shkurtër (< 4 minuta)",
|
||||
"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",
|
||||
"none": "asnjë",
|
||||
"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_medium": "Mesatare (4 - 20 minuta)",
|
||||
"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"
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@
|
|||
"footer_documentation": "Belgelendirme",
|
||||
"footer_source_code": "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",
|
||||
"footer_donate_page": "Bağış Yap",
|
||||
"preferences_region_label": "İçerik Ülkesi: ",
|
||||
|
@ -397,8 +397,8 @@
|
|||
"videoinfo_watch_on_youTube": "YouTube'da İzle",
|
||||
"download_subtitles": "Alt Yazılar - `x` (.vtt)",
|
||||
"preferences_save_player_pos_label": "Oynatma Konumunu Kaydet: ",
|
||||
"generic_views_count": "{{count}} Görüntüleme",
|
||||
"generic_views_count_plural": "{{count}} Görüntüleme",
|
||||
"generic_views_count": "{{count}} Görüntülenme",
|
||||
"generic_views_count_plural": "{{count}} Görüntülenme",
|
||||
"generic_subscribers_count": "{{count}} Abone",
|
||||
"generic_subscribers_count_plural": "{{count}} Abone",
|
||||
"generic_subscriptions_count": "{{count}} Abonelik",
|
||||
|
@ -476,5 +476,8 @@
|
|||
"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"
|
||||
"channel_tab_playlists_label": "Oynatma Listeleri",
|
||||
"Album: ": "Albüm: ",
|
||||
"Music in this video": "Bu videodaki müzik",
|
||||
"Artist: ": "Sanatçı: "
|
||||
}
|
||||
|
|
|
@ -492,5 +492,8 @@
|
|||
"channel_tab_shorts_label": "Shorts",
|
||||
"channel_tab_streams_label": "Прямі трансляції",
|
||||
"channel_tab_playlists_label": "Добірки",
|
||||
"channel_tab_channels_label": "Канали"
|
||||
"channel_tab_channels_label": "Канали",
|
||||
"Music in this video": "Музика в цьому відео",
|
||||
"Artist: ": "Виконавець: ",
|
||||
"Album: ": "Альбом: "
|
||||
}
|
||||
|
|
|
@ -456,5 +456,12 @@
|
|||
"search_filters_type_option_all": "任意类型",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"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": "频道"
|
||||
}
|
||||
|
|
|
@ -460,5 +460,8 @@
|
|||
"channel_tab_shorts_label": "短片",
|
||||
"channel_tab_playlists_label": "播放清單",
|
||||
"channel_tab_channels_label": "頻道",
|
||||
"channel_tab_streams_label": "直播"
|
||||
"channel_tab_streams_label": "直播",
|
||||
"Artist: ": "藝術家: ",
|
||||
"Album: ": "專輯: ",
|
||||
"Music in this video": "此影片中的音樂"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
private IMAGE_QUALITIES = {320, 560, 640, 1280, 2000}
|
||||
|
||||
# TODO: Add "sort_by"
|
||||
def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
||||
response = YT_POOL.client &.get("/channel/#{ucid}/community?gl=JP&hl=en")
|
||||
|
@ -75,10 +77,9 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
|||
json.field "author", author
|
||||
json.field "authorThumbnails" do
|
||||
json.array do
|
||||
qualities = {32, 48, 76, 100, 176, 512}
|
||||
author_thumbnail = post["authorThumbnail"]["thumbnails"].as_a[0]["url"].as_s
|
||||
|
||||
qualities.each do |quality|
|
||||
IMAGE_QUALITIES.each do |quality|
|
||||
json.object do
|
||||
json.field "url", author_thumbnail.gsub(/s\d+-/, "s#{quality}-")
|
||||
json.field "width", quality
|
||||
|
@ -108,6 +109,8 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
|||
like_count = post["actionButtons"]["commentActionButtonsRenderer"]["likeButton"]["toggleButtonRenderer"]["accessibilityData"]["accessibilityData"]["label"]
|
||||
.try &.as_s.gsub(/\D/, "").to_i? || 0
|
||||
|
||||
reply_count = short_text_to_number(post.dig?("actionButtons", "commentActionButtonsRenderer", "replyButton", "buttonRenderer", "text", "simpleText").try &.as_s || "0")
|
||||
|
||||
json.field "content", html_to_content(content_html)
|
||||
json.field "contentHtml", content_html
|
||||
|
||||
|
@ -115,6 +118,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
|||
json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale))
|
||||
|
||||
json.field "likeCount", like_count
|
||||
json.field "replyCount", reply_count
|
||||
json.field "commentId", post["postId"]? || post["commentId"]? || ""
|
||||
json.field "authorIsChannelOwner", post["authorEndpoint"]["browseEndpoint"]["browseId"] == ucid
|
||||
|
||||
|
@ -174,9 +178,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
|||
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|
|
||||
IMAGE_QUALITIES.each do |quality|
|
||||
json.object do
|
||||
json.field "url", url.gsub(/=s\d+/, "=s#{quality}")
|
||||
json.field "width", quality
|
||||
|
@ -185,10 +187,39 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
|||
end
|
||||
end
|
||||
end
|
||||
# TODO
|
||||
# when .has_key?("pollRenderer")
|
||||
# attachment = attachment["pollRenderer"]
|
||||
# json.field "type", "poll"
|
||||
when .has_key?("pollRenderer")
|
||||
attachment = attachment["pollRenderer"]
|
||||
json.field "type", "poll"
|
||||
json.field "totalVotes", short_text_to_number(attachment["totalVotes"]["simpleText"].as_s.split(" ")[0])
|
||||
json.field "choices" do
|
||||
json.array do
|
||||
attachment["choices"].as_a.each do |choice|
|
||||
json.object do
|
||||
json.field "text", choice.dig("text", "runs", 0, "text").as_s
|
||||
# A choice can have an image associated with it.
|
||||
# Ex post: https://www.youtube.com/post/UgkxD4XavXUD4NQiddJXXdohbwOwcVqrH9Re
|
||||
if choice["image"]?
|
||||
thumbnail = choice["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")
|
||||
json.field "image" do
|
||||
json.array do
|
||||
IMAGE_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
|
||||
end
|
||||
end
|
||||
end
|
||||
when .has_key?("postMultiImageRenderer")
|
||||
attachment = attachment["postMultiImageRenderer"]
|
||||
json.field "type", "multiImage"
|
||||
|
@ -202,9 +233,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
|
|||
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|
|
||||
IMAGE_QUALITIES.each do |quality|
|
||||
json.object do
|
||||
json.field "url", url.gsub(/=s\d+/, "=s#{quality}")
|
||||
json.field "width", quality
|
||||
|
|
|
@ -181,6 +181,12 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b
|
|||
json.field "content", html_to_content(content_html)
|
||||
json.field "contentHtml", content_html
|
||||
|
||||
json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil)
|
||||
json.field "isSponsor", (node_comment["sponsorCommentBadge"]? != nil)
|
||||
if node_comment["sponsorCommentBadge"]?
|
||||
# Sponsor icon thumbnails always have one object and there's only ever the url property in it
|
||||
json.field "sponsorIconUrl", node_comment.dig("sponsorCommentBadge", "sponsorCommentBadgeRenderer", "customBadge", "thumbnails", 0, "url").to_s
|
||||
end
|
||||
json.field "published", published.to_unix
|
||||
json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale))
|
||||
|
||||
|
@ -322,11 +328,21 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false)
|
|||
end
|
||||
|
||||
author_name = HTML.escape(child["author"].as_s)
|
||||
sponsor_icon = ""
|
||||
if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool
|
||||
author_name += " <i class=\"icon ion ion-md-checkmark-circle\"></i>"
|
||||
elsif child["verified"]?.try &.as_bool
|
||||
author_name += " <i class=\"icon ion ion-md-checkmark\"></i>"
|
||||
end
|
||||
|
||||
if child["isSponsor"]?.try &.as_bool
|
||||
sponsor_icon = String.build do |str|
|
||||
str << %(<img alt="" )
|
||||
str << %(src="/ggpht) << URI.parse(child["sponsorIconUrl"].as_s).request_target << "\" "
|
||||
str << %(title=") << translate(locale, "Channel Sponsor") << "\" "
|
||||
str << %(width="16" height="16" />)
|
||||
end
|
||||
end
|
||||
html << <<-END_HTML
|
||||
<div class="pure-g" style="width:100%">
|
||||
<div class="channel-profile pure-u-4-24 pure-u-md-2-24">
|
||||
|
@ -337,6 +353,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false)
|
|||
<b>
|
||||
<a class="#{child["authorIsChannelOwner"] == true ? "channel-owner" : ""}" href="#{child["authorUrl"]}">#{author_name}</a>
|
||||
</b>
|
||||
#{sponsor_icon}
|
||||
<p style="white-space:pre-wrap">#{child["contentHtml"]}</p>
|
||||
END_HTML
|
||||
|
||||
|
@ -670,8 +687,30 @@ def content_to_comment_html(content, video_id : String? = "")
|
|||
end
|
||||
|
||||
text = "<b>#{text}</b>" if run["bold"]?
|
||||
text = "<s>#{text}</s>" if run["strikethrough"]?
|
||||
text = "<i>#{text}</i>" if run["italics"]?
|
||||
|
||||
# check for custom emojis
|
||||
if run["emoji"]?
|
||||
if run["emoji"]["isCustomEmoji"]?.try &.as_bool
|
||||
if emojiImage = run.dig?("emoji", "image")
|
||||
emojiAlt = emojiImage.dig?("accessibility", "accessibilityData", "label").try &.as_s || text
|
||||
emojiThumb = emojiImage["thumbnails"][0]
|
||||
text = String.build do |str|
|
||||
str << %(<img alt=") << emojiAlt << "\" "
|
||||
str << %(src="/ggpht) << URI.parse(emojiThumb["url"].as_s).request_target << "\" "
|
||||
str << %(title=") << emojiAlt << "\" "
|
||||
str << %(width=") << emojiThumb["width"] << "\" "
|
||||
str << %(height=") << emojiThumb["height"] << "\" "
|
||||
str << %(class="channel-emoji"/>)
|
||||
end
|
||||
else
|
||||
# Hide deleted channel emoji
|
||||
text = ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
text
|
||||
end
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ struct SearchVideo
|
|||
json.field "author", self.author
|
||||
json.field "authorId", self.ucid
|
||||
json.field "authorUrl", "/channel/#{self.ucid}"
|
||||
json.field "authorVerified", self.author_verified
|
||||
|
||||
json.field "videoThumbnails" do
|
||||
Invidious::JSONify::APIv1.thumbnails(json, self.id)
|
||||
|
|
|
@ -197,6 +197,21 @@ module Invidious::JSONify::APIv1
|
|||
end
|
||||
end
|
||||
|
||||
if !video.music.empty?
|
||||
json.field "musicTracks" do
|
||||
json.array do
|
||||
video.music.each do |music|
|
||||
json.object do
|
||||
json.field "song", music.song
|
||||
json.field "artist", music.artist
|
||||
json.field "album", music.album
|
||||
json.field "license", music.license
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
json.field "recommendedVideos" do
|
||||
json.array do
|
||||
video.related_videos.each do |rv|
|
||||
|
|
|
@ -262,6 +262,7 @@ module Invidious::Routes::Account
|
|||
end
|
||||
|
||||
query["token"] = access_token
|
||||
query["username"] = URI.encode_path_segment(user.email)
|
||||
url.query = query.to_s
|
||||
|
||||
env.redirect url.to_s
|
||||
|
|
|
@ -31,6 +31,88 @@ module Invidious::Routes::API::V1::Authenticated
|
|||
env.response.status_code = 204
|
||||
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)
|
||||
env.response.content_type = "application/json"
|
||||
|
||||
|
|
|
@ -89,6 +89,8 @@ module Invidious::Routes::API::V1::Channels
|
|||
json.field "descriptionHtml", channel.description_html
|
||||
|
||||
json.field "allowedRegions", channel.allowed_regions
|
||||
json.field "tabs", channel.tabs
|
||||
json.field "authorVerified", channel.verified
|
||||
|
||||
json.field "latestVideos" do
|
||||
json.array do
|
||||
|
|
|
@ -150,4 +150,31 @@ module Invidious::Routes::API::V1::Misc
|
|||
|
||||
response
|
||||
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
|
||||
|
|
|
@ -104,33 +104,8 @@ module Invidious::Routes::Subscriptions
|
|||
if format == "json"
|
||||
env.response.content_type = "application/json"
|
||||
env.response.headers["content-disposition"] = "attachment"
|
||||
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: 500).each do |video_id|
|
||||
json.string video_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return Invidious::User::Export.to_invidious(user)
|
||||
else
|
||||
env.response.content_type = "application/xml"
|
||||
env.response.headers["content-disposition"] = "attachment"
|
||||
|
|
|
@ -254,6 +254,14 @@ module Invidious::Routing
|
|||
get "/api/v1/auth/preferences", {{namespace}}::Authenticated, :get_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/subscriptions", {{namespace}}::Authenticated, :get_subscriptions
|
||||
|
@ -281,6 +289,7 @@ module Invidious::Routing
|
|||
get "/api/v1/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/resolveurl", {{namespace}}::Misc, :resolve_url
|
||||
{% end %}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,11 +5,12 @@ def fetch_trending(trending_type, region, locale)
|
|||
|
||||
plid = nil
|
||||
|
||||
if trending_type == "Music"
|
||||
case trending_type.try &.downcase
|
||||
when "music"
|
||||
params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D"
|
||||
elsif trending_type == "Gaming"
|
||||
when "gaming"
|
||||
params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D"
|
||||
elsif trending_type == "Movies"
|
||||
when "movies"
|
||||
params = "4gIKGgh0cmFpbGVycw%3D%3D"
|
||||
else # Default
|
||||
params = ""
|
||||
|
|
35
src/invidious/user/exports.cr
Normal file
35
src/invidious/user/exports.cr
Normal 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
|
|
@ -249,7 +249,12 @@ struct Video
|
|||
|
||||
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)
|
||||
VideoMusic.new(
|
||||
music_json["song"].as_s,
|
||||
music_json["album"].as_s,
|
||||
music_json["artist"].as_s,
|
||||
music_json["license"].as_s
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -3,10 +3,11 @@ require "json"
|
|||
struct VideoMusic
|
||||
include JSON::Serializable
|
||||
|
||||
property song : String
|
||||
property album : String
|
||||
property artist : String
|
||||
property license : String
|
||||
|
||||
def initialize(@album : String, @artist : String, @license : String)
|
||||
def initialize(@song : String, @album : String, @artist : String, @license : String)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -325,17 +325,25 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||
album = nil
|
||||
music_license = nil
|
||||
|
||||
# Used when the video has multiple songs
|
||||
if song_title = music_desc.dig?("carouselLockupRenderer", "videoLockup", "compactVideoRenderer", "title")
|
||||
# "simpleText" for plain text / "runs" when song has a link
|
||||
song = song_title["simpleText"]? || song_title.dig("runs", 0, "text")
|
||||
end
|
||||
|
||||
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 == "SONG"
|
||||
song = 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)
|
||||
music_list << VideoMusic.new(song.to_s, album.to_s, artist.to_s, music_license.to_s)
|
||||
end
|
||||
|
||||
# Author infos
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<% if query %>
|
||||
<%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%>
|
||||
<div class="pure-g h-box">
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<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">
|
||||
|
|
|
@ -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="h-box">
|
||||
<% case item when %>
|
||||
|
@ -40,6 +42,11 @@
|
|||
<% if item.length_seconds != 0 %>
|
||||
<p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
|
||||
<% 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>
|
||||
<% end %>
|
||||
<p dir="auto"><%= HTML.escape(item.title) %></p>
|
||||
|
@ -67,6 +74,11 @@
|
|||
<% elsif item.length_seconds != 0 %>
|
||||
<p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
|
||||
<% 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>
|
||||
<% end %>
|
||||
<p dir="auto"><%= HTML.escape(item.title) %></p>
|
||||
|
@ -124,6 +136,11 @@
|
|||
<% elsif item.length_seconds != 0 %>
|
||||
<p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
|
||||
<% 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>
|
||||
<% end %>
|
||||
<p dir="auto"><%= HTML.escape(item.title) %></p>
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<div class="pure-u-1 pure-u-lg-1-5">
|
||||
<% if page > 1 %>
|
||||
|
|
|
@ -32,3 +32,5 @@
|
|||
<%= rendered "components/item" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
|
|
@ -16,3 +16,5 @@
|
|||
<%= rendered "components/item" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<div class="pure-u-1 pure-u-lg-1-5">
|
||||
<% if page > 1 %>
|
||||
|
|
|
@ -45,3 +45,5 @@
|
|||
<%= rendered "components/item" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
<%- end -%>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<div class="pure-u-1 pure-u-lg-1-5">
|
||||
<%- if page > 1 -%>
|
||||
|
|
|
@ -106,6 +106,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<div class="pure-u-1 pure-u-lg-1-5">
|
||||
<% if page > 1 %>
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
</div>
|
||||
<%- end -%>
|
||||
|
||||
<script src="/js/watched_indicator.js"></script>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<div class="pure-u-1 pure-u-lg-1-5">
|
||||
<%- if query.page > 1 -%>
|
||||
|
|
|
@ -248,9 +248,9 @@ we're going to need to do it here in order to allow for translations.
|
|||
<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>
|
||||
<p class="music-song"><%= translate(locale, "Song: ") %><%= music.song %></p>
|
||||
<p class="music-artist"><%= translate(locale, "Artist: ") %><%= music.artist %></p>
|
||||
<p class="music-album"><%= translate(locale, "Album: ") %><%= music.album %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue