summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/js/player.js7
-rw-r--r--locales/cs.json5
-rw-r--r--locales/fi.json3
-rw-r--r--locales/hr.json5
-rw-r--r--locales/id.json30
-rw-r--r--locales/it.json56
-rw-r--r--locales/ja.json7
-rw-r--r--locales/nb-NO.json13
-rw-r--r--locales/pt-BR.json3
-rw-r--r--locales/pt-PT.json46
-rw-r--r--locales/pt.json3
-rw-r--r--locales/ru.json13
-rw-r--r--locales/sl.json3
-rw-r--r--locales/tr.json3
-rw-r--r--locales/uk.json3
-rw-r--r--locales/zh-CN.json3
-rw-r--r--locales/zh-TW.json3
-rw-r--r--src/invidious/channels/about.cr7
-rw-r--r--src/invidious/channels/community.cr12
-rw-r--r--src/invidious/comments.cr4
-rw-r--r--src/invidious/exceptions.cr4
-rw-r--r--src/invidious/playlists.cr2
-rw-r--r--src/invidious/routes/api/manifest.cr2
-rw-r--r--src/invidious/routes/api/v1/authenticated.cr2
-rw-r--r--src/invidious/routes/api/v1/channels.cr6
-rw-r--r--src/invidious/routes/api/v1/videos.cr8
-rw-r--r--src/invidious/routes/channels.cr9
-rw-r--r--src/invidious/routes/embed.cr6
-rw-r--r--src/invidious/routes/feeds.cr2
-rw-r--r--src/invidious/routes/playlists.cr14
-rw-r--r--src/invidious/routes/video_playback.cr8
-rw-r--r--src/invidious/routes/watch.cr3
-rw-r--r--src/invidious/videos.cr6
-rw-r--r--src/invidious/yt_backend/extractors.cr2
-rw-r--r--src/invidious/yt_backend/extractors_utils.cr2
35 files changed, 255 insertions, 50 deletions
diff --git a/assets/js/player.js b/assets/js/player.js
index 7930a3d3..f7005280 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -676,7 +676,12 @@ if (player.share) player.share(shareOptions);
// show the preferred caption by default
if (player_data.preferred_caption_found) {
player.ready(function () {
- player.textTracks()[1].mode = 'showing';
+ if (!video_data.params.listen && video_data.params.quality === 'dash') {
+ // play.textTracks()[0] on DASH mode is showing some debug messages
+ player.textTracks()[1].mode = 'showing';
+ } else {
+ player.textTracks()[0].mode = 'showing';
+ }
});
}
diff --git a/locales/cs.json b/locales/cs.json
index d590b5b8..97f108d7 100644
--- a/locales/cs.json
+++ b/locales/cs.json
@@ -88,7 +88,7 @@
"Only show latest unwatched video from channel: ": "Zobrazit jen nejnovější nezhlédnuté video z daného kanálu: ",
"preferences_unseen_only_label": "Zobrazit jen již nezhlédnuté: ",
"preferences_notifications_only_label": "Zobrazit pouze upozornění (pokud nějaká jsou): ",
- "Enable web notifications": "Povolit webové upozornění",
+ "Enable web notifications": "Povolit webová upozornění",
"`x` uploaded a video": "`x` nahrál(a) video",
"`x` is live": "`x` je živě",
"preferences_category_data": "Nastavení dat",
@@ -486,5 +486,6 @@
"search_filters_features_option_purchased": "Zakoupeno",
"search_filters_sort_label": "Řadit dle",
"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: "
}
diff --git a/locales/fi.json b/locales/fi.json
index 2aa64ea7..cbb18825 100644
--- a/locales/fi.json
+++ b/locales/fi.json
@@ -470,5 +470,6 @@
"search_filters_duration_option_medium": "Keskipituinen (4 - 20 minuuttia)",
"search_message_use_another_instance": " Voit myös <a href=\"`x`\">hakea toisella instanssilla</a>.",
"search_filters_date_option_none": "Milloin tahansa",
- "search_filters_type_option_all": "Mikä tahansa tyyppi"
+ "search_filters_type_option_all": "Mikä tahansa tyyppi",
+ "Popular enabled: ": "Suosittu käytössä: "
}
diff --git a/locales/hr.json b/locales/hr.json
index 7eb065dc..54eef7f9 100644
--- a/locales/hr.json
+++ b/locales/hr.json
@@ -107,7 +107,7 @@
"preferences_feed_menu_label": "Izbornik za feedove: ",
"preferences_show_nick_label": "Prikaži nadimak na vrhu: ",
"Top enabled: ": "Najbolji aktivirani: ",
- "CAPTCHA enabled: ": "Aktivirani CAPTCHA: ",
+ "CAPTCHA enabled: ": "CAPTCHA aktiviran: ",
"Login enabled: ": "Prijava aktivirana: ",
"Registration enabled: ": "Registracija aktivirana: ",
"Report statistics: ": "Izvještaj o statistici: ",
@@ -486,5 +486,6 @@
"search_filters_duration_option_none": "Bilo koje duljine",
"search_filters_duration_option_medium": "Srednje (4 – 20 minuta)",
"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: "
}
diff --git a/locales/id.json b/locales/id.json
index c96495c3..d150cece 100644
--- a/locales/id.json
+++ b/locales/id.json
@@ -346,7 +346,7 @@
"Community": "Komunitas",
"search_filters_sort_option_relevance": "Relevansi",
"search_filters_sort_option_rating": "Penilaian",
- "search_filters_sort_option_date": "Tanggal unggah",
+ "search_filters_sort_option_date": "Tanggal Unggah",
"search_filters_sort_option_views": "Jumlah ditonton",
"search_filters_type_label": "Tipe",
"search_filters_duration_label": "Durasi",
@@ -421,5 +421,31 @@
"search_filters_title": "Saring",
"search_message_no_results": "Tidak ada hasil yang ditemukan.",
"search_message_change_filters_or_query": "Coba perbanyak kueri pencarian dan/atau ubah filter Anda.",
- "search_message_use_another_instance": " Anda juga bisa <a href=\"`x`\">mencari di peladen lain</a>."
+ "search_message_use_another_instance": " Anda juga bisa <a href=\"`x`\">mencari di peladen lain</a>.",
+ "Indonesian (auto-generated)": "Indonesia (dibuat secara otomatis)",
+ "Japanese (auto-generated)": "Jepang (dibuat secara otomatis)",
+ "Korean (auto-generated)": "Korea (dibuat secara otomatis)",
+ "Portuguese (Brazil)": "Portugis (Brasil)",
+ "Russian (auto-generated)": "Rusia (dibuat secara otomatis)",
+ "Spanish (Mexico)": "Spanyol (Meksiko)",
+ "Spanish (Spain)": "Spanyol (Spanyol)",
+ "Vietnamese (auto-generated)": "Vietnam (dibuat secara otomatis)",
+ "search_filters_features_option_vr180": "VR180",
+ "Spanish (auto-generated)": "Spanyol (dibuat secara otomatis)",
+ "Chinese": "Bahasa Cina",
+ "Chinese (Taiwan)": "Bahasa Cina (Taiwan)",
+ "Chinese (Hong Kong)": "Bahasa Cina (Hong Kong)",
+ "Chinese (China)": "Bahasa Cina (China)",
+ "French (auto-generated)": "Perancis (dibuat secara otomatis)",
+ "German (auto-generated)": "Jerman (dibuat secara otomatis)",
+ "Italian (auto-generated)": "Italia (dibuat secara otomatis)",
+ "Portuguese (auto-generated)": "Portugis (dibuat secara otomatis)",
+ "Turkish (auto-generated)": "Turki (dibuat secara otomatis)",
+ "search_filters_date_label": "Tanggal unggah",
+ "search_filters_type_option_all": "Segala jenis",
+ "search_filters_apply_button": "Terapkan saringan yang dipilih",
+ "Dutch (auto-generated)": "Belanda (dihasilkan secara otomatis)",
+ "search_filters_date_option_none": "Tanggal berapa pun",
+ "search_filters_duration_option_none": "Durasi berapa pun",
+ "search_filters_duration_option_medium": "Sedang (4 - 20 menit)"
}
diff --git a/locales/it.json b/locales/it.json
index 7ba5ff2d..ac83ac58 100644
--- a/locales/it.json
+++ b/locales/it.json
@@ -28,7 +28,7 @@
"Import and Export Data": "Importazione ed esportazione dati",
"Import": "Importa",
"Import Invidious data": "Importa dati Invidious in formato JSON",
- "Import YouTube subscriptions": "Importa le iscrizioni da YouTube",
+ "Import YouTube subscriptions": "Importa le iscrizioni da YouTube/OPML",
"Import FreeTube subscriptions (.db)": "Importa le iscrizioni da FreeTube (.db)",
"Import NewPipe subscriptions (.json)": "Importa le iscrizioni da NewPipe (.json)",
"Import NewPipe data (.zip)": "Importa i dati di NewPipe (.zip)",
@@ -340,7 +340,7 @@
"%A %B %-d, %Y": "%A %-d %B %Y",
"(edited)": "(modificato)",
"YouTube comment permalink": "Link permanente al commento di YouTube",
- "permalink": "permalink",
+ "permalink": "perma-collegamento",
"`x` marked it with a ❤": "`x` l'ha contrassegnato con un ❤",
"Audio mode": "Modalità audio",
"Video mode": "Modalità video",
@@ -385,7 +385,7 @@
"preferences_quality_dash_option_144p": "144p",
"Released under the AGPLv3 on Github.": "Rilasciato su GitHub con licenza AGPLv3.",
"preferences_quality_option_medium": "Media",
- "preferences_quality_option_small": "Piccola",
+ "preferences_quality_option_small": "Limitata",
"preferences_quality_dash_option_best": "Migliore",
"preferences_quality_dash_option_worst": "Peggiore",
"invidious": "Invidious",
@@ -393,7 +393,7 @@
"preferences_quality_option_hd720": "HD720",
"preferences_quality_dash_option_auto": "Automatica",
"videoinfo_watch_on_youTube": "Guarda su YouTube",
- "preferences_extend_desc_label": "Espandi automaticamente la descrizione del video: ",
+ "preferences_extend_desc_label": "Estendi automaticamente la descrizione del video: ",
"preferences_vr_mode_label": "Video interattivi a 360 gradi: ",
"Show less": "Mostra di meno",
"Switch Invidious Instance": "Cambia istanza Invidious",
@@ -425,5 +425,51 @@
"search_filters_type_option_show": "Serie",
"search_filters_duration_option_short": "Corto (< 4 minuti)",
"search_filters_duration_option_long": "Lungo (> 20 minuti)",
- "search_filters_features_option_purchased": "Acquistato"
+ "search_filters_features_option_purchased": "Acquistato",
+ "comments_view_x_replies": "Vedi {{count}} risposta",
+ "comments_view_x_replies_plural": "Vedi {{count}} risposte",
+ "comments_points_count": "{{count}} punto",
+ "comments_points_count_plural": "{{count}} punti",
+ "Portuguese (auto-generated)": "Portoghese (auto-generato)",
+ "crash_page_you_found_a_bug": "Sembra che tu abbia trovato un bug in Invidious!",
+ "crash_page_switch_instance": "provato a <a href=\"`x`\">usare un'altra istanza</a>",
+ "crash_page_before_reporting": "Prima di segnalare un bug, assicurati di aver:",
+ "crash_page_read_the_faq": "letto le <a href=\"`x`\">domande più frequenti (FAQ)</a>",
+ "crash_page_search_issue": "cercato tra <a href=\"`x`\"> i problemi esistenti su GitHub</a>",
+ "crash_page_report_issue": "Se niente di tutto ciò ha aiutato, per favore <a href=\"`x`\">apri un nuovo problema su GitHub</a> (preferibilmente in inglese) e includi il seguente testo nel tuo messaggio (NON tradurre il testo):",
+ "Popular enabled: ": "Popolare attivato: ",
+ "English (United Kingdom)": "Inglese (Regno Unito)",
+ "Portuguese (Brazil)": "Portoghese (Brasile)",
+ "preferences_watch_history_label": "Attiva cronologia di riproduzione: ",
+ "French (auto-generated)": "Francese (auto-generato)",
+ "search_message_use_another_instance": " Puoi anche <a href=\"`x`\">cercare in un'altra istanza</a>.",
+ "search_message_no_results": "Nessun risultato trovato.",
+ "search_message_change_filters_or_query": "Prova ad ampliare la ricerca e/o modificare i filtri.",
+ "English (United States)": "Inglese (Stati Uniti)",
+ "Cantonese (Hong Kong)": "Cantonese (Hong Kong)",
+ "Chinese": "Cinese",
+ "Chinese (China)": "Cinese (Cina)",
+ "Chinese (Hong Kong)": "Cinese (Hong Kong)",
+ "Chinese (Taiwan)": "Cinese (Taiwan)",
+ "Dutch (auto-generated)": "Olandese (auto-generato)",
+ "German (auto-generated)": "Tedesco (auto-generato)",
+ "Indonesian (auto-generated)": "Indonesiano (auto-generato)",
+ "Interlingue": "Interlingua",
+ "Italian (auto-generated)": "Italiano (auto-generato)",
+ "Japanese (auto-generated)": "Giapponese (auto-generato)",
+ "Korean (auto-generated)": "Coreano (auto-generato)",
+ "Russian (auto-generated)": "Russo (auto-generato)",
+ "Spanish (auto-generated)": "Spagnolo (auto-generato)",
+ "Spanish (Mexico)": "Spagnolo (Messico)",
+ "Spanish (Spain)": "Spagnolo (Spagna)",
+ "Turkish (auto-generated)": "Turco (auto-generato)",
+ "Vietnamese (auto-generated)": "Vietnamita (auto-generato)",
+ "search_filters_date_label": "Data caricamento",
+ "search_filters_date_option_none": "Qualunque data",
+ "search_filters_type_option_all": "Qualunque tipo",
+ "search_filters_duration_option_none": "Qualunque durata",
+ "search_filters_duration_option_medium": "Media (4 - 20 minuti)",
+ "search_filters_features_option_vr180": "VR180",
+ "search_filters_apply_button": "Applica filtri selezionati",
+ "crash_page_refresh": "provato a <a href=\"`x`\">ricaricare la pagina</a>"
}
diff --git a/locales/ja.json b/locales/ja.json
index 20d3c20e..7918fe95 100644
--- a/locales/ja.json
+++ b/locales/ja.json
@@ -433,5 +433,10 @@
"Spanish (Spain)": "スペイン語 (スペイン)",
"Vietnamese (auto-generated)": "ベトナム語 (自動生成)",
"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_no_results": "一致する検索結果はありませんでした",
+ "English (United States)": "英語 (アメリカ)",
+ "search_filters_date_label": "アップロード日",
+ "search_filters_features_option_vr180": "VR180"
}
diff --git a/locales/nb-NO.json b/locales/nb-NO.json
index 8d80c10c..77c688d5 100644
--- a/locales/nb-NO.json
+++ b/locales/nb-NO.json
@@ -460,5 +460,16 @@
"Russian (auto-generated)": "Russisk (laget automatisk)",
"Dutch (auto-generated)": "Nederlandsk (laget automatisk)",
"Turkish (auto-generated)": "Tyrkisk (laget automatisk)",
- "search_filters_title": "Filtrer"
+ "search_filters_title": "Filtrer",
+ "Popular enabled: ": "Populære påskrudd: ",
+ "search_message_change_filters_or_query": "Prøv ett mindre snevert søk og/eller endre filterne.",
+ "search_filters_duration_option_medium": "Middels (4–20 minutter)",
+ "search_message_no_results": "Resultatløst.",
+ "search_filters_type_option_all": "Alle typer",
+ "search_filters_duration_option_none": "Uvilkårlig varighet",
+ "search_message_use_another_instance": " Du kan også <a href=\"`x`\">søke på en annen instans</a>.",
+ "search_filters_date_label": "Opplastningsdato",
+ "search_filters_apply_button": "Bruk valgte filtre",
+ "search_filters_date_option_none": "Siden begynnelsen",
+ "search_filters_features_option_vr180": "VR180"
}
diff --git a/locales/pt-BR.json b/locales/pt-BR.json
index df149564..9576d646 100644
--- a/locales/pt-BR.json
+++ b/locales/pt-BR.json
@@ -470,5 +470,6 @@
"Spanish (Spain)": "Espanhol (Espanha)",
"Turkish (auto-generated)": "Turco (gerado automaticamente)",
"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: "
}
diff --git a/locales/pt-PT.json b/locales/pt-PT.json
index a57a2939..b00ebc72 100644
--- a/locales/pt-PT.json
+++ b/locales/pt-PT.json
@@ -21,15 +21,15 @@
"No": "Não",
"Import and Export Data": "Importar e exportar dados",
"Import": "Importar",
- "Import Invidious data": "Importar dados do Invidious",
- "Import YouTube subscriptions": "Importar subscrições do YouTube",
+ "Import Invidious data": "Importar dados JSON do Invidious",
+ "Import YouTube subscriptions": "Importar subscrições OPML ou do YouTube",
"Import FreeTube subscriptions (.db)": "Importar subscrições do FreeTube (.db)",
"Import NewPipe subscriptions (.json)": "Importar subscrições do NewPipe (.json)",
"Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
"Export": "Exportar",
"Export subscriptions as OPML": "Exportar subscrições como OPML",
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar subscrições como OPML (para NewPipe e FreeTube)",
- "Export data as JSON": "Exportar dados como JSON",
+ "Export data as JSON": "Exportar dados do Invidious como JSON",
"Delete account?": "Eliminar conta?",
"History": "Histórico",
"An alternative front-end to YouTube": "Uma interface alternativa ao YouTube",
@@ -60,13 +60,13 @@
"preferences_volume_label": "Volume da reprodução: ",
"preferences_comments_label": "Preferência dos comentários: ",
"youtube": "YouTube",
- "reddit": "reddit",
+ "reddit": "Reddit",
"preferences_captions_label": "Legendas predefinidas: ",
"Fallback captions: ": "Legendas alternativas: ",
"preferences_related_videos_label": "Mostrar vídeos relacionados: ",
"preferences_annotations_label": "Mostrar anotações sempre: ",
"preferences_extend_desc_label": "Estender automaticamente a descrição do vídeo: ",
- "preferences_vr_mode_label": "Vídeos interativos de 360 graus: ",
+ "preferences_vr_mode_label": "Vídeos interativos de 360 graus (necessita de WebGL): ",
"preferences_category_visual": "Preferências visuais",
"preferences_player_style_label": "Estilo do reprodutor: ",
"Dark mode: ": "Modo escuro: ",
@@ -374,5 +374,39 @@
"next_steps_error_message": "Pode tentar as seguintes opções: ",
"next_steps_error_message_refresh": "Atualizar",
"next_steps_error_message_go_to_youtube": "Ir ao YouTube",
- "search_filters_title": "Filtro"
+ "search_filters_title": "Filtro",
+ "generic_videos_count": "{{count}} vídeo",
+ "generic_videos_count_plural": "{{count}} vídeos",
+ "generic_playlists_count": "{{count}} lista de reprodução",
+ "generic_playlists_count_plural": "{{count}} listas de reprodução",
+ "generic_subscriptions_count": "{{count}} subscrição",
+ "generic_subscriptions_count_plural": "{{count}} subscrições",
+ "generic_views_count": "{{count}} visualização",
+ "generic_views_count_plural": "{{count}} visualizações",
+ "generic_subscribers_count": "{{count}} subscritor",
+ "generic_subscribers_count_plural": "{{count}} subscritores",
+ "preferences_quality_dash_option_4320p": "4320p",
+ "preferences_quality_dash_label": "Qualidade de vídeo DASH preferencial ",
+ "preferences_quality_dash_option_2160p": "2160p",
+ "subscriptions_unseen_notifs_count": "{{count}} notificação por ver",
+ "subscriptions_unseen_notifs_count_plural": "{{count}} notificações por ver",
+ "Popular enabled: ": "Página \"Popular\" ativada: ",
+ "search_message_no_results": "Nenhum resultado encontrado.",
+ "preferences_quality_dash_option_auto": "Automática",
+ "preferences_region_label": "País para o conteúdo: ",
+ "preferences_quality_dash_option_1440p": "1440p",
+ "preferences_quality_dash_option_720p": "720p",
+ "preferences_watch_history_label": "Ativar histórico de visualizações ",
+ "preferences_quality_dash_option_best": "Melhor",
+ "preferences_quality_dash_option_worst": "Pior",
+ "preferences_quality_dash_option_144p": "144p",
+ "invidious": "Invidious",
+ "preferences_quality_option_hd720": "HD720",
+ "preferences_quality_option_dash": "DASH (qualidade adaptativa)",
+ "preferences_quality_option_medium": "Média",
+ "preferences_quality_option_small": "Pequena",
+ "preferences_quality_dash_option_1080p": "1080p",
+ "preferences_quality_dash_option_480p": "480p",
+ "preferences_quality_dash_option_360p": "360p",
+ "preferences_quality_dash_option_240p": "240p"
}
diff --git a/locales/pt.json b/locales/pt.json
index 1abe46fa..654cfdeb 100644
--- a/locales/pt.json
+++ b/locales/pt.json
@@ -470,5 +470,6 @@
"search_filters_date_label": "Data de publicação",
"search_filters_date_option_none": "Qualquer data",
"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: "
}
diff --git a/locales/ru.json b/locales/ru.json
index 00d24502..4680e350 100644
--- a/locales/ru.json
+++ b/locales/ru.json
@@ -75,11 +75,11 @@
"light": "светлая",
"preferences_thin_mode_label": "Облегчённое оформление: ",
"preferences_category_misc": "Прочие настройки",
- "preferences_automatic_instance_redirect_label": "Автоматическое перенаправление на зеркало сайта (переход на redirect.invidious.io): ",
+ "preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ",
"preferences_category_subscription": "Настройки подписок",
"preferences_annotations_subscribed_label": "Всегда показывать аннотации на каналах из ваших подписок? ",
- "Redirect homepage to feed: ": "Отображать видео с каналов, на которые вы подписаны, как главную страницу: ",
- "preferences_max_results_label": "Число видео, на которые вы подписаны, в ленте: ",
+ "Redirect homepage to feed: ": "Показывать подписки на главной странице: ",
+ "preferences_max_results_label": "Число видео в ленте: ",
"preferences_sort_label": "Сортировать видео: ",
"published": "по дате публикации",
"published - reverse": "по дате публикации в обратном порядке",
@@ -158,7 +158,7 @@
"View more comments on Reddit": "Посмотреть больше комментариев на Reddit",
"View `x` comments": {
"([^.,0-9]|^)1([^.,0-9]|$)": "Показано `x` комментариев",
- "": "Показано`x` комментариев"
+ "": "Показано `x` комментариев"
},
"View Reddit comments": "Смотреть комментарии с Reddit",
"Hide replies": "Скрыть ответы",
@@ -186,7 +186,7 @@
"Could not fetch comments": "Не удаётся загрузить комментарии",
"`x` ago": "`x` назад",
"Load more": "Загрузить ещё",
- "Could not create mix.": "Не удаётся создать микс.",
+ "Could not create mix.": "Не удалось создать микс.",
"Empty playlist": "Плейлист пуст",
"Not a playlist.": "Некорректный плейлист.",
"Playlist does not exist.": "Плейлист не существует.",
@@ -486,5 +486,6 @@
"search_filters_features_option_vr180": "VR180",
"search_message_change_filters_or_query": "Попробуйте расширить поисковый запрос или изменить фильтры.",
"search_filters_duration_option_medium": "Средние (4 - 20 минут)",
- "search_filters_apply_button": "Применить фильтры"
+ "search_filters_apply_button": "Применить фильтры",
+ "Popular enabled: ": "Популярное включено: "
}
diff --git a/locales/sl.json b/locales/sl.json
index 9165e714..288f8da5 100644
--- a/locales/sl.json
+++ b/locales/sl.json
@@ -502,5 +502,6 @@
"crash_page_refresh": "poskušal/a <a href=\"`x`\">osvežiti stran</a>",
"crash_page_before_reporting": "Preden prijaviš napako, se prepričaj, da si:",
"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: "
}
diff --git a/locales/tr.json b/locales/tr.json
index b1991c35..bd499746 100644
--- a/locales/tr.json
+++ b/locales/tr.json
@@ -470,5 +470,6 @@
"search_filters_duration_option_medium": "Orta (4 - 20 dakika)",
"search_filters_features_option_vr180": "VR180",
"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: "
}
diff --git a/locales/uk.json b/locales/uk.json
index 23f56c9a..0cc14579 100644
--- a/locales/uk.json
+++ b/locales/uk.json
@@ -486,5 +486,6 @@
"search_filters_features_option_purchased": "Придбано",
"search_filters_sort_option_relevance": "Відповідні",
"search_filters_sort_option_rating": "Рейтингові",
- "search_filters_sort_option_views": "Популярні"
+ "search_filters_sort_option_views": "Популярні",
+ "Popular enabled: ": "Популярне ввімкнено: "
}
diff --git a/locales/zh-CN.json b/locales/zh-CN.json
index ed180628..ff48e101 100644
--- a/locales/zh-CN.json
+++ b/locales/zh-CN.json
@@ -454,5 +454,6 @@
"search_message_change_filters_or_query": "尝试扩大你的搜索查询和/或更改过滤器。",
"search_filters_duration_option_none": "任意时长",
"search_filters_type_option_all": "任意类型",
- "search_filters_features_option_vr180": "VR180"
+ "search_filters_features_option_vr180": "VR180",
+ "Popular enabled: ": "已启用流行度: "
}
diff --git a/locales/zh-TW.json b/locales/zh-TW.json
index 4b6fa71b..90614e48 100644
--- a/locales/zh-TW.json
+++ b/locales/zh-TW.json
@@ -454,5 +454,6 @@
"search_filters_title": "過濾條件",
"search_filters_date_label": "上傳日期",
"search_filters_type_option_all": "任何類型",
- "search_filters_date_option_none": "任何日期"
+ "search_filters_date_option_none": "任何日期",
+ "Popular enabled: ": "已啟用人氣: "
}
diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr
index 565f2bca..c2027f90 100644
--- a/src/invidious/channels/about.cr
+++ b/src/invidious/channels/about.cr
@@ -31,7 +31,12 @@ def get_about_info(ucid, locale) : AboutChannel
end
if initdata.dig?("alerts", 0, "alertRenderer", "type") == "ERROR"
- raise InfoException.new(initdata["alerts"][0]["alertRenderer"]["text"]["simpleText"].as_s)
+ error_message = initdata["alerts"][0]["alertRenderer"]["text"]["simpleText"].as_s
+ if error_message == "This channel does not exist."
+ raise NotFoundException.new(error_message)
+ else
+ raise InfoException.new(error_message)
+ end
end
if browse_endpoint = initdata["onResponseReceivedActions"]?.try &.[0]?.try &.["navigateAction"]?.try &.["endpoint"]?.try &.["browseEndpoint"]?
diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr
index 4701ecbd..2a2c74aa 100644
--- a/src/invidious/channels/community.cr
+++ b/src/invidious/channels/community.cr
@@ -6,20 +6,18 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
end
if response.status_code != 200
- raise InfoException.new("This channel does not exist.")
+ raise NotFoundException.new("This channel does not exist.")
end
ucid = response.body.match(/https:\/\/www.youtube.com\/channel\/(?<ucid>UC[a-zA-Z0-9_-]{22})/).not_nil!["ucid"]
if !continuation || continuation.empty?
initial_data = extract_initial_data(response.body)
- body = initial_data["contents"]?.try &.["twoColumnBrowseResultsRenderer"]["tabs"].as_a.select { |tab| tab["tabRenderer"]?.try &.["selected"].as_bool.== true }[0]?
+ body = extract_selected_tab(initial_data["contents"]["twoColumnBrowseResultsRenderer"]["tabs"])["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]
if !body
raise InfoException.new("Could not extract community tab.")
end
-
- body = body["tabRenderer"]["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]
else
continuation = produce_channel_community_continuation(ucid, continuation)
@@ -49,7 +47,11 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
error_message = (message["text"]["simpleText"]? ||
message["text"]["runs"]?.try &.[0]?.try &.["text"]?)
.try &.as_s || ""
- raise InfoException.new(error_message)
+ if error_message == "This channel does not exist."
+ raise NotFoundException.new(error_message)
+ else
+ raise InfoException.new(error_message)
+ end
end
response = JSON.build do |json|
diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr
index 593189fd..5112ad3d 100644
--- a/src/invidious/comments.cr
+++ b/src/invidious/comments.cr
@@ -95,7 +95,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b
contents = body["contents"]?
header = body["header"]?
else
- raise InfoException.new("Could not fetch comments")
+ raise NotFoundException.new("Comments not found.")
end
if !contents
@@ -290,7 +290,7 @@ def fetch_reddit_comments(id, sort_by = "confidence")
thread = result[0].data.as(RedditListing).children[0].data.as(RedditLink)
else
- raise InfoException.new("Could not fetch comments")
+ raise NotFoundException.new("Comments not found.")
end
client.close
diff --git a/src/invidious/exceptions.cr b/src/invidious/exceptions.cr
index bfaa3fd5..471a199a 100644
--- a/src/invidious/exceptions.cr
+++ b/src/invidious/exceptions.cr
@@ -18,3 +18,7 @@ class BrokenTubeException < Exception
return "Missing JSON element \"#{@element}\""
end
end
+
+# Exception threw when an element is not found.
+class NotFoundException < InfoException
+end
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index aefa34cc..c4eb7507 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -317,7 +317,7 @@ def get_playlist(plid : String)
if playlist = Invidious::Database::Playlists.select(id: plid)
return playlist
else
- raise InfoException.new("Playlist does not exist.")
+ raise NotFoundException.new("Playlist does not exist.")
end
else
return fetch_playlist(plid)
diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr
index 8bc36946..f8766b66 100644
--- a/src/invidious/routes/api/manifest.cr
+++ b/src/invidious/routes/api/manifest.cr
@@ -16,6 +16,8 @@ module Invidious::Routes::API::Manifest
video = get_video(id, region: region)
rescue ex : VideoRedirect
return env.redirect env.request.resource.gsub(id, ex.video_id)
+ rescue ex : NotFoundException
+ haltf env, status_code: 404
rescue ex
haltf env, status_code: 403
end
diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr
index b559a01a..1f5ad8ef 100644
--- a/src/invidious/routes/api/v1/authenticated.cr
+++ b/src/invidious/routes/api/v1/authenticated.cr
@@ -237,6 +237,8 @@ module Invidious::Routes::API::V1::Authenticated
begin
video = get_video(video_id)
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
diff --git a/src/invidious/routes/api/v1/channels.cr b/src/invidious/routes/api/v1/channels.cr
index 8650976d..6b81c546 100644
--- a/src/invidious/routes/api/v1/channels.cr
+++ b/src/invidious/routes/api/v1/channels.cr
@@ -13,6 +13,8 @@ module Invidious::Routes::API::V1::Channels
rescue ex : ChannelRedirect
env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id)
return error_json(302, "Channel is unavailable", {"authorId" => ex.channel_id})
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
@@ -170,6 +172,8 @@ module Invidious::Routes::API::V1::Channels
rescue ex : ChannelRedirect
env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id)
return error_json(302, "Channel is unavailable", {"authorId" => ex.channel_id})
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
@@ -205,6 +209,8 @@ module Invidious::Routes::API::V1::Channels
rescue ex : ChannelRedirect
env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id)
return error_json(302, "Channel is unavailable", {"authorId" => ex.channel_id})
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr
index a9f891f5..1b7b4fa7 100644
--- a/src/invidious/routes/api/v1/videos.cr
+++ b/src/invidious/routes/api/v1/videos.cr
@@ -12,6 +12,8 @@ module Invidious::Routes::API::V1::Videos
rescue ex : VideoRedirect
env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id)
return error_json(302, "Video is unavailable", {"videoId" => ex.video_id})
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
@@ -42,6 +44,8 @@ module Invidious::Routes::API::V1::Videos
rescue ex : VideoRedirect
env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id)
return error_json(302, "Video is unavailable", {"videoId" => ex.video_id})
+ rescue ex : NotFoundException
+ haltf env, 404
rescue ex
haltf env, 500
end
@@ -167,6 +171,8 @@ module Invidious::Routes::API::V1::Videos
rescue ex : VideoRedirect
env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id)
return error_json(302, "Video is unavailable", {"videoId" => ex.video_id})
+ rescue ex : NotFoundException
+ haltf env, 404
rescue ex
haltf env, 500
end
@@ -324,6 +330,8 @@ module Invidious::Routes::API::V1::Videos
begin
comments = fetch_youtube_comments(id, continuation, format, locale, thin_mode, region, sort_by: sort_by)
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
diff --git a/src/invidious/routes/channels.cr b/src/invidious/routes/channels.cr
index cd2e3323..c6e02cbd 100644
--- a/src/invidious/routes/channels.cr
+++ b/src/invidious/routes/channels.cr
@@ -85,6 +85,9 @@ module Invidious::Routes::Channels
rescue ex : InfoException
env.response.status_code = 500
error_message = ex.message
+ rescue ex : NotFoundException
+ env.response.status_code = 404
+ error_message = ex.message
rescue ex
return error_template(500, ex)
end
@@ -118,7 +121,7 @@ module Invidious::Routes::Channels
resolved_url = YoutubeAPI.resolve_url("https://youtube.com#{env.request.path}#{yt_url_params.size > 0 ? "?#{yt_url_params}" : ""}")
ucid = resolved_url["endpoint"]["browseEndpoint"]["browseId"]
rescue ex : InfoException | KeyError
- raise InfoException.new(translate(locale, "This channel does not exist."))
+ return error_template(404, translate(locale, "This channel does not exist."))
end
selected_tab = env.request.path.split("/")[-1]
@@ -141,7 +144,7 @@ module Invidious::Routes::Channels
user = env.params.query["user"]?
if !user
- raise InfoException.new("This channel does not exist.")
+ return error_template(404, "This channel does not exist.")
else
env.redirect "/user/#{user}#{uri_params}"
end
@@ -197,6 +200,8 @@ module Invidious::Routes::Channels
channel = get_about_info(ucid, locale)
rescue ex : ChannelRedirect
return env.redirect env.request.resource.gsub(ucid, ex.channel_id)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
rescue ex
return error_template(500, ex)
end
diff --git a/src/invidious/routes/embed.cr b/src/invidious/routes/embed.cr
index 207970b0..84da9993 100644
--- a/src/invidious/routes/embed.cr
+++ b/src/invidious/routes/embed.cr
@@ -7,6 +7,8 @@ module Invidious::Routes::Embed
playlist = get_playlist(plid)
offset = env.params.query["index"]?.try &.to_i? || 0
videos = get_playlist_videos(playlist, offset: offset)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
rescue ex
return error_template(500, ex)
end
@@ -60,6 +62,8 @@ module Invidious::Routes::Embed
playlist = get_playlist(plid)
offset = env.params.query["index"]?.try &.to_i? || 0
videos = get_playlist_videos(playlist, offset: offset)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
rescue ex
return error_template(500, ex)
end
@@ -119,6 +123,8 @@ module Invidious::Routes::Embed
video = get_video(id, region: params.region)
rescue ex : VideoRedirect
return env.redirect env.request.resource.gsub(id, ex.video_id)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
rescue ex
return error_template(500, ex)
end
diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr
index 2e6043f7..44a87175 100644
--- a/src/invidious/routes/feeds.cr
+++ b/src/invidious/routes/feeds.cr
@@ -150,6 +150,8 @@ module Invidious::Routes::Feeds
channel = get_about_info(ucid, locale)
rescue ex : ChannelRedirect
return env.redirect env.request.resource.gsub(ucid, ex.channel_id)
+ rescue ex : NotFoundException
+ return error_atom(404, ex)
rescue ex
return error_atom(500, ex)
end
diff --git a/src/invidious/routes/playlists.cr b/src/invidious/routes/playlists.cr
index de981d81..fe7e4e1c 100644
--- a/src/invidious/routes/playlists.cr
+++ b/src/invidious/routes/playlists.cr
@@ -66,7 +66,13 @@ module Invidious::Routes::Playlists
user = user.as(User)
playlist_id = env.params.query["list"]
- playlist = get_playlist(playlist_id)
+ begin
+ playlist = get_playlist(playlist_id)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
+ rescue ex
+ return error_template(500, ex)
+ end
subscribe_playlist(user, playlist)
env.redirect "/playlist?list=#{playlist.id}"
@@ -304,6 +310,8 @@ module Invidious::Routes::Playlists
playlist_id = env.params.query["playlist_id"]
playlist = get_playlist(playlist_id).as(InvidiousPlaylist)
raise "Invalid user" if playlist.author != user.email
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
if redirect
return error_template(400, ex)
@@ -334,6 +342,8 @@ module Invidious::Routes::Playlists
begin
video = get_video(video_id)
+ rescue ex : NotFoundException
+ return error_json(404, ex)
rescue ex
if redirect
return error_template(500, ex)
@@ -394,6 +404,8 @@ module Invidious::Routes::Playlists
begin
playlist = get_playlist(plid)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
rescue ex
return error_template(500, ex)
end
diff --git a/src/invidious/routes/video_playback.cr b/src/invidious/routes/video_playback.cr
index 3a92ef96..560f9c19 100644
--- a/src/invidious/routes/video_playback.cr
+++ b/src/invidious/routes/video_playback.cr
@@ -265,7 +265,13 @@ module Invidious::Routes::VideoPlayback
return error_template(403, "Administrator has disabled this endpoint.")
end
- video = get_video(id, region: region)
+ begin
+ video = get_video(id, region: region)
+ rescue ex : NotFoundException
+ return error_template(404, ex)
+ rescue ex
+ return error_template(500, ex)
+ end
fmt = video.fmt_stream.find(nil) { |f| f["itag"].as_i == itag } || video.adaptive_fmts.find(nil) { |f| f["itag"].as_i == itag }
url = fmt.try &.["url"]?.try &.as_s
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
index 7280de4f..fe1d8e54 100644
--- a/src/invidious/routes/watch.cr
+++ b/src/invidious/routes/watch.cr
@@ -63,6 +63,9 @@ module Invidious::Routes::Watch
video = get_video(id, region: params.region)
rescue ex : VideoRedirect
return env.redirect env.request.resource.gsub(id, ex.video_id)
+ rescue ex : NotFoundException
+ LOGGER.error("get_video not found: #{id} : #{ex.message}")
+ return error_template(404, ex)
rescue ex
LOGGER.error("get_video: #{id} : #{ex.message}")
return error_template(500, ex)
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index 1504e390..1a547ee0 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -1158,7 +1158,11 @@ def fetch_video(id, region)
end
if reason = info["reason"]?
- raise InfoException.new(reason.as_s || "")
+ if reason == "Video unavailable"
+ raise NotFoundException.new(reason.as_s || "")
+ else
+ raise InfoException.new(reason.as_s || "")
+ end
end
video = Video.new({
diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr
index c4326cab..b9609eb9 100644
--- a/src/invidious/yt_backend/extractors.cr
+++ b/src/invidious/yt_backend/extractors.cr
@@ -417,7 +417,7 @@ private module Extractors
# {"tabRenderer": {
# "endpoint": {...}
# "title": "Playlists",
- # "selected": true,
+ # "selected": true, # Is nil unless tab is selected
# "content": {...},
# ...
# }}
diff --git a/src/invidious/yt_backend/extractors_utils.cr b/src/invidious/yt_backend/extractors_utils.cr
index 3d5e5787..f8245160 100644
--- a/src/invidious/yt_backend/extractors_utils.cr
+++ b/src/invidious/yt_backend/extractors_utils.cr
@@ -84,7 +84,7 @@ end
def extract_selected_tab(tabs)
# Extract the selected tab from the array of tabs Youtube returns
- return selected_target = tabs.as_a.select(&.["tabRenderer"]?.try &.["selected"].as_bool)[0]["tabRenderer"]
+ return selected_target = tabs.as_a.select(&.["tabRenderer"]?.try &.["selected"]?.try &.as_bool)[0]["tabRenderer"]
end
def fetch_continuation_token(items : Array(JSON::Any))