mirror of
https://github.com/iv-org/invidious.git
synced 2024-10-01 01:25:56 -04:00
Merge branch 'iv-org:master' into iframe_api
This commit is contained in:
commit
74bf3bc8b2
9
assets/hashtag.svg
Normal file
9
assets/hashtag.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" version="1.1" id="svg5" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect fill="#c84fff" width="128" height="128" x="0" y="0" />
|
||||
<g aria-label="#" transform="matrix(1.1326954,0,0,1.1326954,-20.255282,-23.528147)">
|
||||
<path d="m 87.780593,70.524217 -2.624999,13.666661 h 11.666662 v 5.708331 H 84.030595 L 80.61393,107.73253 H 74.488932 L 77.988931,89.899209 H 65.863936 L 62.447271,107.73253 H 56.447273 L 59.697272,89.899209 H 48.947276 V 84.190878 H 60.822271 L 63.530603,70.524217 H 52.113942 V 64.815886 H 64.57227 l 3.416665,-17.999993 h 6.124997 l -3.416665,17.999993 h 12.208328 l 3.499999,-17.999993 h 5.999997 l -3.499998,17.999993 h 10.916662 v 5.708331 z M 66.947269,84.190878 H 79.072264 L 81.738929,70.524217 H 69.613934 Z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 918 B |
@ -540,5 +540,13 @@
|
||||
"Channel Sponsor": "راعي القناة",
|
||||
"Standard YouTube license": "ترخيص YouTube القياسي",
|
||||
"Download is disabled": "تم تعطيل التحميلات",
|
||||
"Import YouTube playlist (.csv)": "استيراد قائمة تشغيل YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "استيراد قائمة تشغيل YouTube (.csv)",
|
||||
"generic_button_save": "حفظ",
|
||||
"generic_button_delete": "حذف",
|
||||
"generic_button_edit": "تحرير",
|
||||
"generic_button_cancel": "الغاء",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "الإصدارات",
|
||||
"playlist_button_add_items": "إضافة مقاطع فيديو",
|
||||
"channel_tab_podcasts_label": "البودكاست"
|
||||
}
|
||||
|
1
locales/az.json
Normal file
1
locales/az.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -492,5 +492,13 @@
|
||||
"Song: ": "Skladba: ",
|
||||
"Standard YouTube license": "Standardní licence YouTube",
|
||||
"Download is disabled": "Stahování je zakázáno",
|
||||
"Import YouTube playlist (.csv)": "Importovat YouTube playlist (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importovat YouTube playlist (.csv)",
|
||||
"generic_button_save": "Uložit",
|
||||
"generic_button_delete": "Odstranit",
|
||||
"generic_button_cancel": "Zrušit",
|
||||
"channel_tab_podcasts_label": "Podcasty",
|
||||
"channel_tab_releases_label": "Vydání",
|
||||
"generic_button_edit": "Upravit",
|
||||
"generic_button_rss": "RSS",
|
||||
"playlist_button_add_items": "Přidat videa"
|
||||
}
|
||||
|
@ -476,5 +476,11 @@
|
||||
"Standard YouTube license": "Standard YouTube-Lizenz",
|
||||
"Song: ": "Musik: ",
|
||||
"Download is disabled": "Herunterladen ist deaktiviert",
|
||||
"Import YouTube playlist (.csv)": "YouTube Playlist Importieren (.csv)"
|
||||
"Import YouTube playlist (.csv)": "YouTube Playlist Importieren (.csv)",
|
||||
"generic_button_delete": "Löschen",
|
||||
"generic_button_edit": "Bearbeiten",
|
||||
"generic_button_save": "Speichern",
|
||||
"generic_button_cancel": "Abbrechen",
|
||||
"generic_button_rss": "RSS",
|
||||
"playlist_button_add_items": "Videos hinzufügen"
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
"generic_channels_count": "{{count}} channel",
|
||||
"generic_channels_count_plural": "{{count}} channels",
|
||||
"generic_views_count": "{{count}} view",
|
||||
"generic_views_count_plural": "{{count}} views",
|
||||
"generic_videos_count": "{{count}} video",
|
||||
|
@ -154,7 +154,7 @@
|
||||
"View YouTube comments": "Vidi komentojn de JuTubo",
|
||||
"View more comments on Reddit": "Vidi pli komentoj en Reddit",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Vidi `x` komentojn",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Vidi `x` komenton",
|
||||
"": "Vidi `x` komentojn"
|
||||
},
|
||||
"View Reddit comments": "Vidi komentojn de Reddit",
|
||||
@ -447,8 +447,8 @@
|
||||
"French (auto-generated)": "Franca (aŭtomate generita)",
|
||||
"Spanish (Mexico)": "Hispana (Meksiko)",
|
||||
"Spanish (auto-generated)": "Hispana (aŭtomate generita)",
|
||||
"generic_count_days": "{{count}} jaro",
|
||||
"generic_count_days_plural": "{{count}} jaroj",
|
||||
"generic_count_days": "{{count}} tago",
|
||||
"generic_count_days_plural": "{{count}} tagoj",
|
||||
"search_filters_type_option_all": "Ajna speco",
|
||||
"search_filters_duration_option_none": "Ajna daŭro",
|
||||
"search_filters_apply_button": "Uzi elektitajn filtrilojn",
|
||||
@ -476,5 +476,13 @@
|
||||
"Song: ": "Muzikaĵo: ",
|
||||
"Standard YouTube license": "Implicita YouTube-licenco",
|
||||
"Download is disabled": "Elŝuto estas malebligita",
|
||||
"Import YouTube playlist (.csv)": "Importi YouTube-ludliston (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importi YouTube-ludliston (.csv)",
|
||||
"generic_button_edit": "Redakti",
|
||||
"playlist_button_add_items": "Aldoni videojn",
|
||||
"generic_button_rss": "RSS",
|
||||
"generic_button_delete": "Forigi",
|
||||
"channel_tab_podcasts_label": "Podkastoj",
|
||||
"generic_button_cancel": "Nuligi",
|
||||
"channel_tab_releases_label": "Eldonoj",
|
||||
"generic_button_save": "Konservi"
|
||||
}
|
||||
|
@ -113,7 +113,7 @@
|
||||
"Token manager": "Gestor de tokens",
|
||||
"Token": "Ficha",
|
||||
"Import/export": "Importar/Exportar",
|
||||
"unsubscribe": "Desuscribirse",
|
||||
"unsubscribe": "desuscribirse",
|
||||
"revoke": "revocar",
|
||||
"Subscriptions": "Suscripciones",
|
||||
"search": "buscar",
|
||||
@ -154,7 +154,7 @@
|
||||
"View YouTube comments": "Ver los comentarios de YouTube",
|
||||
"View more comments on Reddit": "Ver más comentarios en Reddit",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentarios",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentario",
|
||||
"": "Ver `x` comentarios"
|
||||
},
|
||||
"View Reddit comments": "Ver los comentarios de Reddit",
|
||||
@ -476,5 +476,13 @@
|
||||
"Channel Sponsor": "Patrocinador del canal",
|
||||
"Standard YouTube license": "Licencia de YouTube estándar",
|
||||
"Download is disabled": "La descarga está deshabilitada",
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reproducción de YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reproducción de YouTube (.csv)",
|
||||
"playlist_button_add_items": "Añadir vídeos",
|
||||
"generic_button_edit": "Editar",
|
||||
"generic_button_save": "Guardar",
|
||||
"generic_button_delete": "Borrar",
|
||||
"generic_button_cancel": "Cancelar",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_podcasts_label": "Podcasts",
|
||||
"channel_tab_releases_label": "Publicaciones"
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
"generic_channels_count": "{{count}} chaîne",
|
||||
"generic_channels_count_plural": "{{count}} chaînes",
|
||||
"generic_views_count": "{{count}} vue",
|
||||
"generic_views_count_plural": "{{count}} vues",
|
||||
"generic_videos_count": "{{count}} vidéo",
|
||||
@ -55,10 +57,10 @@
|
||||
"Password": "Mot de passe",
|
||||
"Time (h:mm:ss):": "Heure (h:mm:ss) :",
|
||||
"Text CAPTCHA": "CAPTCHA textuel",
|
||||
"Image CAPTCHA": "CAPTCHA graphique",
|
||||
"Sign In": "Se connecter",
|
||||
"Image CAPTCHA": "CAPTCHA pictural",
|
||||
"Sign In": "S'identifier",
|
||||
"Register": "S'inscrire",
|
||||
"E-mail": "E-mail",
|
||||
"E-mail": "Courriel",
|
||||
"Preferences": "Préférences",
|
||||
"preferences_category_player": "Préférences du lecteur",
|
||||
"preferences_video_loop_label": "Lire en boucle : ",
|
||||
@ -128,8 +130,8 @@
|
||||
"Subscription manager": "Gestionnaire d'abonnement",
|
||||
"Token manager": "Gestionnaire de token",
|
||||
"Token": "Token",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokens",
|
||||
"tokens_count": "{{count}} jeton",
|
||||
"tokens_count_plural": "{{count}} jetons",
|
||||
"Import/export": "Importer/Exporter",
|
||||
"unsubscribe": "se désabonner",
|
||||
"revoke": "révoquer",
|
||||
@ -482,5 +484,7 @@
|
||||
"Music in this video": "Musique dans cette vidéo",
|
||||
"Channel Sponsor": "Soutien de la chaîne",
|
||||
"Download is disabled": "Le téléchargement est désactivé",
|
||||
"Import YouTube playlist (.csv)": "Importer des listes de lecture de Youtube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importer des listes de lecture de Youtube (.csv)",
|
||||
"channel_tab_releases_label": "Parutions",
|
||||
"channel_tab_podcasts_label": "Émissions audio"
|
||||
}
|
||||
|
@ -471,5 +471,18 @@
|
||||
"channel_tab_shorts_label": "शॉर्ट्स",
|
||||
"channel_tab_streams_label": "लाइवस्ट्रीम्स",
|
||||
"channel_tab_playlists_label": "प्लेलिस्ट्स",
|
||||
"channel_tab_channels_label": "चैनल्स"
|
||||
"channel_tab_channels_label": "चैनल्स",
|
||||
"generic_button_save": "सहेजें",
|
||||
"generic_button_cancel": "रद्द करें",
|
||||
"generic_button_rss": "आरएसएस",
|
||||
"generic_button_edit": "संपादित करें",
|
||||
"generic_button_delete": "मिटाएं",
|
||||
"playlist_button_add_items": "वीडियो जोड़ें",
|
||||
"Song: ": "गाना: ",
|
||||
"channel_tab_podcasts_label": "पाॅडकास्ट",
|
||||
"channel_tab_releases_label": "रिलीज़ेस्",
|
||||
"Import YouTube playlist (.csv)": "YouTube प्लेलिस्ट (.csv) आयात करें",
|
||||
"Standard YouTube license": "मानक यूट्यूब लाइसेंस",
|
||||
"Channel Sponsor": "चैनल प्रायोजक",
|
||||
"Download is disabled": "डाउनलोड करना अक्षम है"
|
||||
}
|
||||
|
@ -492,5 +492,13 @@
|
||||
"Song: ": "Pjesma: ",
|
||||
"Standard YouTube license": "Standardna YouTube licenca",
|
||||
"Download is disabled": "Preuzimanje je deaktivirano",
|
||||
"Import YouTube playlist (.csv)": "Uvezi YouTube zbirku (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Uvezi YouTube zbirku (.csv)",
|
||||
"generic_button_delete": "Izbriši",
|
||||
"playlist_button_add_items": "Dodaj videa",
|
||||
"channel_tab_podcasts_label": "Podcasti",
|
||||
"generic_button_edit": "Uredi",
|
||||
"generic_button_save": "Spremi",
|
||||
"generic_button_cancel": "Odustani",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "Izdanja"
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
"View playlist on YouTube": "Vedi playlist su YouTube",
|
||||
"newest": "più recente",
|
||||
"oldest": "più vecchio",
|
||||
"popular": "Tendenze",
|
||||
"popular": "popolare",
|
||||
"last": "ultimo",
|
||||
"Next page": "Pagina successiva",
|
||||
"Previous page": "Pagina precedente",
|
||||
@ -467,7 +467,7 @@
|
||||
"channel_tab_shorts_label": "Short",
|
||||
"channel_tab_playlists_label": "Playlist",
|
||||
"channel_tab_channels_label": "Canali",
|
||||
"channel_tab_streams_label": "Livestream",
|
||||
"channel_tab_streams_label": "Trasmissioni in diretta",
|
||||
"channel_tab_community_label": "Comunità",
|
||||
"Music in this video": "Musica in questo video",
|
||||
"Artist: ": "Artista: ",
|
||||
@ -476,5 +476,13 @@
|
||||
"Song: ": "Canzone: ",
|
||||
"Standard YouTube license": "Licenza standard di YouTube",
|
||||
"Channel Sponsor": "Sponsor del canale",
|
||||
"Import YouTube playlist (.csv)": "Importa playlist di YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importa playlist di YouTube (.csv)",
|
||||
"generic_button_edit": "Modifica",
|
||||
"generic_button_cancel": "Annulla",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "Pubblicazioni",
|
||||
"generic_button_delete": "Elimina",
|
||||
"generic_button_save": "Salva",
|
||||
"playlist_button_add_items": "Aggiungi video",
|
||||
"channel_tab_podcasts_label": "Podcast"
|
||||
}
|
||||
|
@ -81,7 +81,7 @@
|
||||
"preferences_category_subscription": "登録チャンネル設定",
|
||||
"preferences_annotations_subscribed_label": "最初から登録チャンネルのアノテーションを表示 ",
|
||||
"Redirect homepage to feed: ": "ホームからフィードにリダイレクト: ",
|
||||
"preferences_max_results_label": "フィードに表示する動画の量: ",
|
||||
"preferences_max_results_label": "フィードに表示する動画数: ",
|
||||
"preferences_sort_label": "動画を並び替え: ",
|
||||
"published": "投稿日",
|
||||
"published - reverse": "投稿日 - 逆順",
|
||||
@ -366,13 +366,13 @@
|
||||
"next_steps_error_message": "下記のものを試して下さい: ",
|
||||
"next_steps_error_message_refresh": "再読込",
|
||||
"next_steps_error_message_go_to_youtube": "YouTubeへ",
|
||||
"search_filters_duration_option_short": "4 分未満",
|
||||
"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",
|
||||
"search_filters_duration_option_long": "20 分以上",
|
||||
"search_filters_duration_option_long": "20分以上",
|
||||
"preferences_region_label": "地域: ",
|
||||
"footer_donate_page": "寄付する",
|
||||
"preferences_quality_dash_label": "優先するDASH画質: ",
|
||||
@ -443,7 +443,7 @@
|
||||
"search_filters_date_option_none": "すべて",
|
||||
"search_filters_type_option_all": "すべての種類",
|
||||
"search_filters_duration_option_none": "すべての長さ",
|
||||
"search_filters_duration_option_medium": "4 ~ 20 分",
|
||||
"search_filters_duration_option_medium": "4 ~ 20分",
|
||||
"preferences_save_player_pos_label": "再生位置を保存: ",
|
||||
"crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。",
|
||||
"crash_page_report_issue": "上記が助けにならないなら、<a href=\"`x`\">GitHub</a> に新しい issue を作成し(英語が好ましい)、メッセージに次のテキストを含めてください(テキストは翻訳しない)。",
|
||||
@ -460,5 +460,13 @@
|
||||
"Channel Sponsor": "チャンネルのスポンサー",
|
||||
"Standard YouTube license": "標準 Youtube ライセンス",
|
||||
"Download is disabled": "ダウンロード: このインスタンスでは未対応",
|
||||
"Import YouTube playlist (.csv)": "YouTube 再生リストをインポート (.csv)"
|
||||
"Import YouTube playlist (.csv)": "YouTube 再生リストをインポート (.csv)",
|
||||
"generic_button_delete": "削除",
|
||||
"generic_button_cancel": "キャンセル",
|
||||
"channel_tab_podcasts_label": "ポッドキャスト",
|
||||
"channel_tab_releases_label": "リリース",
|
||||
"generic_button_edit": "編集",
|
||||
"generic_button_save": "保存",
|
||||
"generic_button_rss": "RSS",
|
||||
"playlist_button_add_items": "動画を追加"
|
||||
}
|
||||
|
@ -460,5 +460,13 @@
|
||||
"Music in this video": "동영상 속 음악",
|
||||
"Artist: ": "아티스트: ",
|
||||
"Download is disabled": "다운로드가 비활성화 되어있음",
|
||||
"Import YouTube playlist (.csv)": "유튜브 플레이리스트 가져오기 (.csv)"
|
||||
"Import YouTube playlist (.csv)": "유튜브 플레이리스트 가져오기 (.csv)",
|
||||
"playlist_button_add_items": "동영상 추가",
|
||||
"channel_tab_podcasts_label": "팟캐스트",
|
||||
"generic_button_delete": "삭제",
|
||||
"generic_button_edit": "편집",
|
||||
"generic_button_save": "저장",
|
||||
"generic_button_cancel": "취소",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "출시"
|
||||
}
|
||||
|
1
locales/la.json
Normal file
1
locales/la.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -154,7 +154,7 @@
|
||||
"View YouTube comments": "Vis YouTube-kommentarer",
|
||||
"View more comments on Reddit": "Vis flere kommenterer på Reddit",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Vis `x` kommentarer",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Vis `x` kommentar",
|
||||
"": "Vis `x` kommentarer"
|
||||
},
|
||||
"View Reddit comments": "Vis Reddit-kommentarer",
|
||||
@ -476,5 +476,13 @@
|
||||
"Album: ": "Album: ",
|
||||
"Download is disabled": "Nedlasting er avskrudd",
|
||||
"Channel Sponsor": "Kanalsponsor",
|
||||
"Import YouTube playlist (.csv)": "Importer YouTube-spilleliste (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importer YouTube-spilleliste (.csv)",
|
||||
"channel_tab_podcasts_label": "Podkaster",
|
||||
"channel_tab_releases_label": "Utgaver",
|
||||
"generic_button_delete": "Slett",
|
||||
"generic_button_edit": "Endre",
|
||||
"generic_button_save": "Lagre",
|
||||
"generic_button_cancel": "Avbryt",
|
||||
"generic_button_rss": "RSS",
|
||||
"playlist_button_add_items": "Legg til videoer"
|
||||
}
|
||||
|
@ -1 +1,29 @@
|
||||
{}
|
||||
{
|
||||
"preferences_quality_dash_option_720p": "୭୨୦ପି",
|
||||
"preferences_quality_dash_option_4320p": "୪୩୨୦ପି",
|
||||
"preferences_quality_dash_option_240p": "୨୪୦ପି",
|
||||
"preferences_quality_dash_option_2160p": "୨୧୬୦ପି",
|
||||
"preferences_quality_dash_option_144p": "୧୪୪ପି",
|
||||
"reddit": "Reddit",
|
||||
"preferences_quality_dash_option_480p": "୪୮୦ପି",
|
||||
"preferences_dark_mode_label": "ଥିମ୍: ",
|
||||
"dark": "ଗାଢ଼",
|
||||
"published": "ପ୍ରକାଶିତ",
|
||||
"generic_videos_count": "{{count}}ଟିଏ ଵିଡ଼ିଓ",
|
||||
"generic_videos_count_plural": "{{count}}ଟି ଵିଡ଼ିଓ",
|
||||
"generic_button_edit": "ସମ୍ପାଦନା",
|
||||
"light": "ହାଲୁକା",
|
||||
"last": "ଗତ",
|
||||
"New password": "ନୂଆ ପାସ୍ୱର୍ଡ଼",
|
||||
"preferences_quality_dash_option_1440p": "୧୪୪୦ପି",
|
||||
"preferences_quality_dash_option_360p": "୩୬୦ପି",
|
||||
"preferences_quality_option_medium": "ମଧ୍ୟମ",
|
||||
"preferences_quality_dash_option_1080p": "୧୦୮୦ପି",
|
||||
"youtube": "YouTube",
|
||||
"preferences_quality_option_hd720": "HD୭୨୦",
|
||||
"invidious": "Invidious",
|
||||
"generic_playlists_count": "{{count}}ଟିଏ ଚାଳନାତାଲିକା",
|
||||
"generic_playlists_count_plural": "{{count}}ଟି ଚାଳନାତାଲିକା",
|
||||
"Yes": "ହଁ",
|
||||
"No": "ନାହିଁ"
|
||||
}
|
||||
|
@ -148,12 +148,12 @@
|
||||
"Blacklisted regions: ": "Niedostępny na obszarach: ",
|
||||
"Shared `x`": "Udostępniono `x`",
|
||||
"Premieres in `x`": "Publikacja za `x`",
|
||||
"Premieres `x`": "Publikacja za `x`",
|
||||
"Premieres `x`": "Publikacja `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.": "Cześć! Wygląda na to, że masz wyłączoną obsługę JavaScriptu. Kliknij tutaj, żeby zobaczyć komentarze. Pamiętaj, że wczytywanie może potrwać dłużej.",
|
||||
"View YouTube comments": "Wyświetl komentarze z YouTube",
|
||||
"View more comments on Reddit": "Wyświetl więcej komentarzy na Reddicie",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Wyświetl `x` komentarzy",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Wyświetl `x` komentarz",
|
||||
"": "Wyświetl `x` komentarzy"
|
||||
},
|
||||
"View Reddit comments": "Wyświetl komentarze z Redditta",
|
||||
@ -492,5 +492,13 @@
|
||||
"Song: ": "Piosenka: ",
|
||||
"Channel Sponsor": "Sponsor kanału",
|
||||
"Standard YouTube license": "Standardowa licencja YouTube",
|
||||
"Import YouTube playlist (.csv)": "Importuj playlistę YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importuj playlistę YouTube (.csv)",
|
||||
"generic_button_edit": "Edytuj",
|
||||
"generic_button_cancel": "Anuluj",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_podcasts_label": "Podkasty",
|
||||
"channel_tab_releases_label": "Wydania",
|
||||
"generic_button_delete": "Usuń",
|
||||
"generic_button_save": "Zapisz",
|
||||
"playlist_button_add_items": "Dodaj filmy"
|
||||
}
|
||||
|
@ -475,6 +475,14 @@
|
||||
"Standard YouTube license": "Licença padrão do YouTube",
|
||||
"Song: ": "Música: ",
|
||||
"Channel Sponsor": "Patrocinador do Canal",
|
||||
"Download is disabled": "Download está desativado",
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reprodução do YouTube (.csv)"
|
||||
"Download is disabled": "Download está desabilitado",
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reprodução do YouTube (.csv)",
|
||||
"generic_button_delete": "Apagar",
|
||||
"generic_button_save": "Salvar",
|
||||
"generic_button_edit": "Editar",
|
||||
"playlist_button_add_items": "Adicionar vídeos",
|
||||
"channel_tab_releases_label": "Lançamentos",
|
||||
"channel_tab_podcasts_label": "Podcasts",
|
||||
"generic_button_cancel": "Cancelar",
|
||||
"generic_button_rss": "RSS"
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_features_option_location": "Localização",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_live": "Em direto",
|
||||
"search_filters_features_option_live": "Ao Vivo",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_subtitles": "Legendas",
|
||||
@ -365,7 +365,7 @@
|
||||
"Subscribe": "Subscrever",
|
||||
"Unsubscribe": "Anular subscrição",
|
||||
"Shared `x` ago": "Partilhado `x` atrás",
|
||||
"LIVE": "Em direto",
|
||||
"LIVE": "AO VIVO",
|
||||
"search_filters_duration_option_short": "Curto (< 4 minutos)",
|
||||
"search_filters_duration_option_long": "Longo (> 20 minutos)",
|
||||
"footer_source_code": "Código-fonte",
|
||||
@ -476,5 +476,13 @@
|
||||
"Channel Sponsor": "Patrocinador do canal",
|
||||
"Standard YouTube license": "Licença padrão do YouTube",
|
||||
"Download is disabled": "A descarga está desativada",
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reprodução do YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reprodução do YouTube (.csv)",
|
||||
"generic_button_delete": "Deletar",
|
||||
"generic_button_edit": "Editar",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_podcasts_label": "Podcasts",
|
||||
"channel_tab_releases_label": "Lançamentos",
|
||||
"generic_button_save": "Salvar",
|
||||
"generic_button_cancel": "Cancelar",
|
||||
"playlist_button_add_items": "Adicionar vídeos"
|
||||
}
|
||||
|
@ -492,5 +492,13 @@
|
||||
"Standard YouTube license": "Стандартная лицензия YouTube",
|
||||
"Channel Sponsor": "Спонсор канала",
|
||||
"Download is disabled": "Загрузка отключена",
|
||||
"Import YouTube playlist (.csv)": "Импорт плейлиста YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Импорт плейлиста YouTube (.csv)",
|
||||
"channel_tab_releases_label": "Релизы",
|
||||
"generic_button_delete": "Удалить",
|
||||
"generic_button_edit": "Редактировать",
|
||||
"generic_button_save": "Сохранить",
|
||||
"generic_button_cancel": "Отменить",
|
||||
"generic_button_rss": "RSS",
|
||||
"playlist_button_add_items": "Добавить видео",
|
||||
"channel_tab_podcasts_label": "Подкасты"
|
||||
}
|
||||
|
@ -89,7 +89,7 @@
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_option_auto": "ස්වයංක්රීය",
|
||||
"preferences_quality_option_small": "කුඩා",
|
||||
"preferences_quality_dash_option_best": "උසස්",
|
||||
"preferences_quality_dash_option_best": "හොඳම",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
@ -119,5 +119,9 @@
|
||||
"Only show latest unwatched video from channel: ": "නාලිකාවේ නවතම නැරඹන නොලද වීඩියෝව පමණක් පෙන්වන්න: ",
|
||||
"preferences_category_data": "දත්ත මනාප",
|
||||
"Clear watch history": "නැරඹුම් ඉතිහාසය මකාදැමීම",
|
||||
"Subscriptions": "දායකත්ව"
|
||||
"Subscriptions": "දායකත්ව",
|
||||
"generic_button_rss": "RSS",
|
||||
"generic_button_save": "සුරකින්න",
|
||||
"generic_button_cancel": "අවලංගු කරන්න",
|
||||
"preferences_quality_dash_option_worst": "නරකම"
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
"last": "posledné",
|
||||
"Next page": "Ďalšia strana",
|
||||
"Previous page": "Predchádzajúca strana",
|
||||
"Clear watch history?": "Vymazať históriu sledovania?",
|
||||
"Clear watch history?": "Vymazať históriu pozerania?",
|
||||
"New password": "Nové heslo",
|
||||
"New passwords must match": "Nové heslá sa musia zhodovať",
|
||||
"Authorize token?": "Autorizovať token?",
|
||||
@ -99,5 +99,23 @@
|
||||
"generic_subscriptions_count_1": "{{count}} odbery",
|
||||
"generic_subscriptions_count_2": "{{count}} odberov",
|
||||
"Authorize token for `x`?": "Autorizovať token pre `x`?",
|
||||
"View playlist on YouTube": "Zobraziť playlist na YouTube"
|
||||
"View playlist on YouTube": "Zobraziť playlist na YouTube",
|
||||
"preferences_quality_dash_option_best": "Najlepšia",
|
||||
"preferences_quality_dash_option_worst": "Najhoršia",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_dash_label": "Preferovaná video kvalita DASH: ",
|
||||
"preferences_quality_option_dash": "DASH (adaptívna kvalita)",
|
||||
"preferences_quality_option_small": "Malá",
|
||||
"preferences_watch_history_label": "Zapnúť históriu pozerania: ",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_auto": "Auto",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"invidious": "Invidious",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_360p": "360p"
|
||||
}
|
||||
|
@ -222,7 +222,7 @@
|
||||
"search_filters_date_option_week": "Ta teden",
|
||||
"search_filters_type_label": "Vrsta",
|
||||
"search_filters_type_option_all": "Katerakoli vrsta",
|
||||
"search_filters_type_option_playlist": "Seznami predvajanja",
|
||||
"search_filters_type_option_playlist": "Seznam predvajanja",
|
||||
"search_filters_features_option_subtitles": "Podnapisi/CC",
|
||||
"search_filters_features_option_location": "Lokacija",
|
||||
"footer_donate_page": "Prispevaj",
|
||||
@ -508,5 +508,13 @@
|
||||
"Standard YouTube license": "Standardna licenca YouTube",
|
||||
"Channel Sponsor": "Sponzor kanala",
|
||||
"Download is disabled": "Prenos je onemogočen",
|
||||
"Import YouTube playlist (.csv)": "Uvoz seznama predvajanja YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Uvoz seznama predvajanja YouTube (.csv)",
|
||||
"generic_button_delete": "Izbriši",
|
||||
"generic_button_edit": "Uredi",
|
||||
"generic_button_save": "Shrani",
|
||||
"generic_button_cancel": "Prekliči",
|
||||
"generic_button_rss": "RSS",
|
||||
"playlist_button_add_items": "Dodaj videoposnetke",
|
||||
"channel_tab_podcasts_label": "Poddaje",
|
||||
"channel_tab_releases_label": "Izdaje"
|
||||
}
|
||||
|
@ -476,5 +476,13 @@
|
||||
"Song: ": "Şarkı: ",
|
||||
"Standard YouTube license": "Standart YouTube lisansı",
|
||||
"Download is disabled": "İndirme devre dışı",
|
||||
"Import YouTube playlist (.csv)": "YouTube Oynatma Listesini İçe Aktar (.csv)"
|
||||
"Import YouTube playlist (.csv)": "YouTube Oynatma Listesini İçe Aktar (.csv)",
|
||||
"generic_button_delete": "Sil",
|
||||
"generic_button_edit": "Düzenle",
|
||||
"generic_button_save": "Kaydet",
|
||||
"generic_button_cancel": "İptal",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "Yayınlar",
|
||||
"playlist_button_add_items": "Video ekle",
|
||||
"channel_tab_podcasts_label": "Podcast'ler"
|
||||
}
|
||||
|
@ -492,5 +492,13 @@
|
||||
"Channel Sponsor": "Спонсор каналу",
|
||||
"Standard YouTube license": "Стандартна ліцензія YouTube",
|
||||
"Download is disabled": "Завантаження вимкнено",
|
||||
"Import YouTube playlist (.csv)": "Імпорт списку відтворення YouTube (.csv)"
|
||||
"Import YouTube playlist (.csv)": "Імпорт списку відтворення YouTube (.csv)",
|
||||
"channel_tab_podcasts_label": "Подкасти",
|
||||
"playlist_button_add_items": "Додати відео",
|
||||
"generic_button_cancel": "Скасувати",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "Випуски",
|
||||
"generic_button_delete": "Видалити",
|
||||
"generic_button_edit": "Змінити",
|
||||
"generic_button_save": "Зберегти"
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_subscribers_count_0": "{{count}} người theo dõi",
|
||||
"LIVE": "TRỰC TIẾP",
|
||||
"Shared `x` ago": "Đã chia sẻ` x` trước",
|
||||
"Shared `x` ago": "Đã chia sẻ `x` trước",
|
||||
"Unsubscribe": "Hủy theo dõi",
|
||||
"Subscribe": "Theo dõi",
|
||||
"View channel on YouTube": "Xem kênh trên YouTube",
|
||||
@ -71,7 +71,7 @@
|
||||
"Dark mode: ": "Chế độ tối: ",
|
||||
"preferences_dark_mode_label": "Chủ đề: ",
|
||||
"dark": "tối",
|
||||
"light": "ánh sáng",
|
||||
"light": "sáng",
|
||||
"preferences_thin_mode_label": "Chế độ mỏng: ",
|
||||
"preferences_category_misc": "Tùy chọn khác",
|
||||
"preferences_automatic_instance_redirect_label": "Tự động chuyển hướng phiên bản (dự phòng về redirect.invidious.io): ",
|
||||
@ -120,7 +120,7 @@
|
||||
"View JavaScript license information.": "Xem thông tin giấy phép JavaScript.",
|
||||
"View privacy policy.": "Xem chính sách bảo mật.",
|
||||
"Trending": "Xu hướng",
|
||||
"Public": "Công cộng",
|
||||
"Public": "Công khai",
|
||||
"Unlisted": "Không hiển thị",
|
||||
"Private": "Riêng tư",
|
||||
"View all playlists": "Xem tất cả danh sách phát",
|
||||
@ -182,17 +182,17 @@
|
||||
"Amharic": "Amharic",
|
||||
"Arabic": "Tiếng Ả Rập",
|
||||
"Armenian": "Tiếng Armenia",
|
||||
"Azerbaijani": "Azerbaijan",
|
||||
"Bangla": "Bangla",
|
||||
"Azerbaijani": "Tiếng Azerbaijan",
|
||||
"Bangla": "Tiếng Bengal",
|
||||
"Basque": "Tiếng Basque",
|
||||
"Belarusian": "Người Belarus",
|
||||
"Belarusian": "Tiếng Belarus",
|
||||
"Bosnian": "Tiếng Bosnia",
|
||||
"Bulgarian": "Tiếng Bungari",
|
||||
"Burmese": "Tiếng Miến Điện",
|
||||
"Catalan": "Tiếng Catalan",
|
||||
"Cebuano": "Cebuano",
|
||||
"Chinese (Simplified)": "Tiếng Trung (Giản thể)",
|
||||
"Chinese (Traditional)": "Truyền thống Trung Hoa)",
|
||||
"Chinese (Traditional)": "Tiếng Trung (Phồn thể)",
|
||||
"Corsican": "Corsican",
|
||||
"Croatian": "Tiếng Croatia",
|
||||
"Czech": "Tiếng Séc",
|
||||
@ -219,22 +219,22 @@
|
||||
"Igbo": "Igbo",
|
||||
"Indonesian": "Tiếng Indonesia",
|
||||
"Irish": "Tiếng Ailen",
|
||||
"Italian": "Người Ý",
|
||||
"Italian": "Tiếng Ý",
|
||||
"Japanese": "Tiếng Nhật",
|
||||
"Javanese": "Tiếng Java",
|
||||
"Kannada": "Tiếng Kannada",
|
||||
"Kazakh": "Tiếng Kazakh",
|
||||
"Khmer": "Tiếng Khmer",
|
||||
"Korean": "Hàn Quốc",
|
||||
"Korean": "Tiếng Hàn",
|
||||
"Kurdish": "Tiếng Kurd",
|
||||
"Kyrgyz": "Kyrgyz",
|
||||
"Lao": "Lào",
|
||||
"Latin": "Latin",
|
||||
"Kyrgyz": "Tiếng Kyrgyz",
|
||||
"Lao": "Tiếng Lào",
|
||||
"Latin": "Tiếng Latin",
|
||||
"Latvian": "Tiếng Latvia",
|
||||
"Lithuanian": "Tiếng Litva",
|
||||
"Luxembourgish": "Tiếng Luxembourg",
|
||||
"Macedonian": "Người Macedonian",
|
||||
"Malagasy": "Malagasy",
|
||||
"Macedonian": "Tiếng Macedonian",
|
||||
"Malagasy": "Tiếng Malagasy",
|
||||
"Malay": "Tiếng Mã Lai",
|
||||
"Malayalam": "Tiếng Malayalam",
|
||||
"Maltese": "Cây nho",
|
||||
@ -364,7 +364,7 @@
|
||||
"Import/export": "Xuất/nhập dữ liệu",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_option_dash": "DASH (tự tối ưu chất lượng)",
|
||||
"generic_subscriptions_count_0": "{{count}} thuê bao",
|
||||
"generic_subscriptions_count_0": "{{count}} người đăng kí",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
@ -383,5 +383,9 @@
|
||||
"Standard YouTube license": "Giấy phép YouTube thông thường",
|
||||
"Album: ": "Album: ",
|
||||
"preferences_save_player_pos_label": "Lưu vị trí xem cuối cùng ",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Xin chào! Có vẻ như bạn đã tắt JavaScript. Bấm vào đây để xem bình luận, lưu ý rằng thời gian tải có thể lâu hơn."
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Xin chào! Có vẻ như bạn đã tắt JavaScript. Bấm vào đây để xem bình luận, lưu ý rằng thời gian tải có thể lâu hơn.",
|
||||
"Chinese (China)": "Tiếng Trung (Trung Quốc)",
|
||||
"generic_button_cancel": "Hủy",
|
||||
"Chinese": "Tiếng Trung",
|
||||
"generic_button_delete": "Xóa"
|
||||
}
|
||||
|
@ -460,5 +460,13 @@
|
||||
"Channel Sponsor": "频道赞助者",
|
||||
"Standard YouTube license": "标准 YouTube 许可证",
|
||||
"Download is disabled": "已禁用下载",
|
||||
"Import YouTube playlist (.csv)": "导入 YouTube 播放列表(.csv)"
|
||||
"Import YouTube playlist (.csv)": "导入 YouTube 播放列表(.csv)",
|
||||
"generic_button_cancel": "取消",
|
||||
"playlist_button_add_items": "添加视频",
|
||||
"generic_button_delete": "删除",
|
||||
"channel_tab_podcasts_label": "播客",
|
||||
"generic_button_edit": "编辑",
|
||||
"generic_button_save": "保存",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_releases_label": "公告"
|
||||
}
|
||||
|
@ -460,5 +460,13 @@
|
||||
"Song: ": "歌曲: ",
|
||||
"Standard YouTube license": "標準 YouTube 授權條款",
|
||||
"Download is disabled": "已停用下載",
|
||||
"Import YouTube playlist (.csv)": "匯入 YouTube 播放清單 (.csv)"
|
||||
"Import YouTube playlist (.csv)": "匯入 YouTube 播放清單 (.csv)",
|
||||
"generic_button_cancel": "取消",
|
||||
"generic_button_edit": "編輯",
|
||||
"generic_button_save": "儲存",
|
||||
"generic_button_rss": "RSS",
|
||||
"generic_button_delete": "刪除",
|
||||
"playlist_button_add_items": "新增影片",
|
||||
"channel_tab_podcasts_label": "Podcast",
|
||||
"channel_tab_releases_label": "發布"
|
||||
}
|
||||
|
@ -232,6 +232,25 @@ struct SearchChannel
|
||||
end
|
||||
end
|
||||
|
||||
struct SearchHashtag
|
||||
include DB::Serializable
|
||||
|
||||
property title : String
|
||||
property url : String
|
||||
property video_count : Int64
|
||||
property channel_count : Int64
|
||||
|
||||
def to_json(locale : String?, json : JSON::Builder)
|
||||
json.object do
|
||||
json.field "type", "hashtag"
|
||||
json.field "title", self.title
|
||||
json.field "url", self.url
|
||||
json.field "videoCount", self.video_count
|
||||
json.field "channelCount", self.channel_count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Category
|
||||
include DB::Serializable
|
||||
|
||||
@ -274,4 +293,4 @@ struct Continuation
|
||||
end
|
||||
end
|
||||
|
||||
alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist | Category
|
||||
alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist | SearchHashtag | Category
|
||||
|
@ -1,5 +1,10 @@
|
||||
module Invidious::Routes::ErrorRoutes
|
||||
def self.error_404(env)
|
||||
# Workaround for #3117
|
||||
if HOST_URL.empty? && env.request.path.starts_with?("/v1/storyboards/sb")
|
||||
return env.redirect "#{env.request.path[15..]}?#{env.params.query}"
|
||||
end
|
||||
|
||||
if md = env.request.path.match(/^\/(?<id>([a-zA-Z0-9_-]{11})|(\w+))$/)
|
||||
item = md["id"]
|
||||
|
||||
|
@ -133,7 +133,7 @@ struct Invidious::User
|
||||
next if !video_id
|
||||
|
||||
begin
|
||||
video = get_video(video_id)
|
||||
video = get_video(video_id, false)
|
||||
rescue ex
|
||||
next
|
||||
end
|
||||
|
@ -55,9 +55,7 @@ def extract_video_info(video_id : String, proxy_region : String? = nil)
|
||||
client_config = YoutubeAPI::ClientConfig.new(proxy_region: proxy_region)
|
||||
|
||||
# Fetch data from the player endpoint
|
||||
# CgIQBg is a workaround for streaming URLs that returns a 403.
|
||||
# See https://github.com/iv-org/invidious/issues/4027#issuecomment-1666944520
|
||||
player_response = YoutubeAPI.player(video_id: video_id, params: "CgIQBg", client_config: client_config)
|
||||
player_response = YoutubeAPI.player(video_id: video_id, params: "", client_config: client_config)
|
||||
|
||||
playability_status = player_response.dig?("playabilityStatus", "status").try &.as_s
|
||||
|
||||
@ -120,6 +118,9 @@ def extract_video_info(video_id : String, proxy_region : String? = nil)
|
||||
|
||||
# Replace player response and reset reason
|
||||
if !new_player_response.nil?
|
||||
# Preserve storyboard data before replacement
|
||||
new_player_response["storyboards"] = player_response["storyboards"] if player_response["storyboards"]?
|
||||
|
||||
player_response = new_player_response
|
||||
params.delete("reason")
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
<%-
|
||||
thin_mode = env.get("preferences").as(Preferences).thin_mode
|
||||
item_watched = !item.is_a?(SearchChannel | SearchPlaylist | InvidiousPlaylist | Category) && env.get?("user").try &.as(User).watched.index(item.id) != nil
|
||||
item_watched = !item.is_a?(SearchChannel | SearchHashtag | SearchPlaylist | InvidiousPlaylist | Category) && env.get?("user").try &.as(User).watched.index(item.id) != nil
|
||||
author_verified = item.responds_to?(:author_verified) && item.author_verified
|
||||
-%>
|
||||
|
||||
@ -29,6 +29,30 @@
|
||||
<p><%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %></p>
|
||||
<% if !item.auto_generated %><p><%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %></p><% end %>
|
||||
<h5><%= item.description_html %></h5>
|
||||
<% when SearchHashtag %>
|
||||
<% if !thin_mode %>
|
||||
<a tabindex="-1" href="<%= item.url %>">
|
||||
<center><img style="width:56.25%" src="/hashtag.svg" alt="" /></center>
|
||||
</a>
|
||||
<%- else -%>
|
||||
<div class="thumbnail-placeholder" style="width:56.25%"></div>
|
||||
<% end %>
|
||||
|
||||
<div class="video-card-row">
|
||||
<div class="flex-left"><a href="<%= item.url %>"><%= HTML.escape(item.title) %></a></div>
|
||||
</div>
|
||||
|
||||
<div class="video-card-row">
|
||||
<%- if item.video_count != 0 -%>
|
||||
<p><%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %></p>
|
||||
<%- end -%>
|
||||
</div>
|
||||
|
||||
<div class="video-card-row">
|
||||
<%- if item.channel_count != 0 -%>
|
||||
<p><%= translate_count(locale, "generic_channels_count", item.channel_count, NumberFormatting::Separator) %></p>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<% when SearchPlaylist, InvidiousPlaylist %>
|
||||
<%-
|
||||
if item.id.starts_with? "RD"
|
||||
|
@ -11,15 +11,16 @@ private ITEM_CONTAINER_EXTRACTOR = {
|
||||
}
|
||||
|
||||
private ITEM_PARSERS = {
|
||||
Parsers::RichItemRendererParser,
|
||||
Parsers::VideoRendererParser,
|
||||
Parsers::ChannelRendererParser,
|
||||
Parsers::GridPlaylistRendererParser,
|
||||
Parsers::PlaylistRendererParser,
|
||||
Parsers::CategoryRendererParser,
|
||||
Parsers::RichItemRendererParser,
|
||||
Parsers::ReelItemRendererParser,
|
||||
Parsers::ItemSectionRendererParser,
|
||||
Parsers::ContinuationItemRendererParser,
|
||||
Parsers::HashtagRendererParser,
|
||||
}
|
||||
|
||||
private alias InitialData = Hash(String, JSON::Any)
|
||||
@ -210,6 +211,56 @@ private module Parsers
|
||||
end
|
||||
end
|
||||
|
||||
# Parses an Innertube `hashtagTileRenderer` into a `SearchHashtag`.
|
||||
# Returns `nil` when the given object is not a `hashtagTileRenderer`.
|
||||
#
|
||||
# A `hashtagTileRenderer` is a kind of search result.
|
||||
# It can be found when searching for any hashtag (e.g "#hi" or "#shorts")
|
||||
module HashtagRendererParser
|
||||
def self.process(item : JSON::Any, author_fallback : AuthorFallback)
|
||||
if item_contents = item["hashtagTileRenderer"]?
|
||||
return self.parse(item_contents)
|
||||
end
|
||||
end
|
||||
|
||||
private def self.parse(item_contents)
|
||||
title = extract_text(item_contents["hashtag"]).not_nil! # E.g "#hi"
|
||||
|
||||
# E.g "/hashtag/hi"
|
||||
url = item_contents.dig?("onTapCommand", "commandMetadata", "webCommandMetadata", "url").try &.as_s
|
||||
url ||= URI.encode_path("/hashtag/#{title.lchop('#')}")
|
||||
|
||||
video_count_txt = extract_text(item_contents["hashtagVideoCount"]?) # E.g "203K videos"
|
||||
channel_count_txt = extract_text(item_contents["hashtagChannelCount"]?) # E.g "81K channels"
|
||||
|
||||
# Fallback for video/channel counts
|
||||
if channel_count_txt.nil? || video_count_txt.nil?
|
||||
# E.g: "203K videos • 81K channels"
|
||||
info_text = extract_text(item_contents["hashtagInfoText"]?).try &.split(" • ")
|
||||
|
||||
if info_text && info_text.size == 2
|
||||
video_count_txt ||= info_text[0]
|
||||
channel_count_txt ||= info_text[1]
|
||||
end
|
||||
end
|
||||
|
||||
return SearchHashtag.new({
|
||||
title: title,
|
||||
url: url,
|
||||
video_count: short_text_to_number(video_count_txt || ""),
|
||||
channel_count: short_text_to_number(channel_count_txt || ""),
|
||||
})
|
||||
rescue ex
|
||||
LOGGER.debug("HashtagRendererParser: Failed to extract renderer.")
|
||||
LOGGER.debug("HashtagRendererParser: Got exception: #{ex.message}")
|
||||
return nil
|
||||
end
|
||||
|
||||
def self.parser_name
|
||||
return {{@type.name}}
|
||||
end
|
||||
end
|
||||
|
||||
# Parses a InnerTube gridPlaylistRenderer into a SearchPlaylist. Returns nil when the given object isn't a gridPlaylistRenderer
|
||||
#
|
||||
# A gridPlaylistRenderer renders a playlist, that is located in a grid, to click on within the YouTube and Invidious UI.
|
||||
|
Loading…
Reference in New Issue
Block a user