├── .gitignore ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.yml │ └── bug_report.yml ├── FUNDING.yml └── workflows │ ├── main.yml │ ├── ytp_beta.yml │ └── cyan_ts.yml ├── Resources ├── icon.png ├── scr1.jpg ├── scr2.jpg ├── scr3.jpg ├── scr4.jpg ├── scr5.jpg ├── scr6.jpg ├── scr7.jpg ├── scr8.jpg ├── scr9.jpg ├── header.png └── depiction.json ├── layout └── Library │ └── Application Support │ └── YTLite.bundle │ ├── Assets.car │ ├── SponsorAudio.m4a │ ├── Info.plist │ ├── zh-Hans.lproj │ └── Localizable.strings │ ├── zh-Hant.lproj │ └── Localizable.strings │ ├── ja.lproj │ └── Localizable.strings │ └── ko.lproj │ └── Localizable.strings ├── Utils ├── YTLUserDefaults.h ├── NSBundle+YTLite.h ├── NSBundle+YTLite.m ├── YTLUserDefaults.m ├── Reachability.h └── Reachability.m ├── YTLite.plist ├── control ├── Makefile ├── YouTubeHeaders.h ├── FAQs ├── FAQ_RU.md ├── FAQ_EN.md ├── FAQ_IT.md └── FAQ_PL.md ├── Sideloading.x ├── YTNativeShare.x ├── README.md └── YTLite.h /.gitignore: -------------------------------------------------------------------------------- 1 | .theos/ 2 | packages/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/icon.png -------------------------------------------------------------------------------- /Resources/scr1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr1.jpg -------------------------------------------------------------------------------- /Resources/scr2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr2.jpg -------------------------------------------------------------------------------- /Resources/scr3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr3.jpg -------------------------------------------------------------------------------- /Resources/scr4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr4.jpg -------------------------------------------------------------------------------- /Resources/scr5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr5.jpg -------------------------------------------------------------------------------- /Resources/scr6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr6.jpg -------------------------------------------------------------------------------- /Resources/scr7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr7.jpg -------------------------------------------------------------------------------- /Resources/scr8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr8.jpg -------------------------------------------------------------------------------- /Resources/scr9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/scr9.jpg -------------------------------------------------------------------------------- /Resources/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/Resources/header.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: dayanch96 2 | github: dayanch96 3 | buy_me_a_coffee: dayanch96 4 | -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/Assets.car: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/layout/Library/Application Support/YTLite.bundle/Assets.car -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/SponsorAudio.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dayanch96/YTLite/HEAD/layout/Library/Application Support/YTLite.bundle/SponsorAudio.m4a -------------------------------------------------------------------------------- /Utils/YTLUserDefaults.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface YTLUserDefaults : NSUserDefaults 6 | 7 | @property (class, readonly, strong) YTLUserDefaults *standardUserDefaults; 8 | 9 | - (void)reset; 10 | 11 | + (void)resetUserDefaults; 12 | 13 | @end 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /Utils/NSBundle+YTLite.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | NS_ASSUME_NONNULL_BEGIN 5 | 6 | @interface NSBundle (YTLite) 7 | 8 | // Returns YTLite default bundle. Supports rootless if defined in compilation parameters 9 | @property (class, nonatomic, readonly) NSBundle *ytl_defaultBundle; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /YTLite.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Filter 6 | 7 | Bundles 8 | 9 | com.google.ios.youtube 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.dvntm.ytlite 2 | Name: YTLite 3 | Depends: mobilesubstrate 4 | Version: 0.0.1 5 | Architecture: iphoneos-arm 6 | Description: Lightweight YouTube Enhancer 7 | Maintainer: dvntm 8 | Author: dvntm 9 | Section: Tweaks 10 | Icon: https://raw.githubusercontent.com/dayanch96/icons/main/ytlite.png 11 | SileoDepiction: https://raw.githubusercontent.com/dayanch96/icons/main/ytlite.json 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(ROOTLESS),1) 2 | THEOS_PACKAGE_SCHEME=rootless 3 | else ifeq ($(ROOTHIDE),1) 4 | THEOS_PACKAGE_SCHEME=roothide 5 | endif 6 | 7 | DEBUG=0 8 | FINALPACKAGE=1 9 | ARCHS = arm64 10 | PACKAGE_VERSION = 3.0.1 11 | TARGET := iphone:clang:16.5:13.0 12 | 13 | include $(THEOS)/makefiles/common.mk 14 | 15 | TWEAK_NAME = YTLite 16 | $(TWEAK_NAME)_FRAMEWORKS = UIKit Foundation SystemConfiguration 17 | $(TWEAK_NAME)_CFLAGS = -fobjc-arc -DTWEAK_VERSION=$(PACKAGE_VERSION) 18 | $(TWEAK_NAME)_FILES = $(wildcard *.x Utils/*.m) 19 | 20 | include $(THEOS_MAKE_PATH)/tweak.mk 21 | -------------------------------------------------------------------------------- /Utils/NSBundle+YTLite.m: -------------------------------------------------------------------------------- 1 | #import "NSBundle+YTLite.h" 2 | 3 | @implementation NSBundle (YTLite) 4 | 5 | + (NSBundle *)ytl_defaultBundle { 6 | static NSBundle *bundle = nil; 7 | static dispatch_once_t onceToken; 8 | 9 | dispatch_once(&onceToken, ^{ 10 | NSString *tweakBundlePath = [[NSBundle mainBundle] pathForResource:@"YTLite" ofType:@"bundle"]; 11 | NSString *kBundlePath = jbroot(@"/Library/Application Support/YTLite.bundle"); 12 | 13 | bundle = [NSBundle bundleWithPath:tweakBundlePath ?: kBundlePath]; 14 | }); 15 | 16 | return bundle; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleShortVersionString 6 | 1.0.0 7 | CFBundleIdentifier 8 | com.dvntm.ytlite 9 | CFBundleSignature 10 | ???? 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleDevelopmentRegion 14 | English 15 | CFBundleExecutable 16 | YTLite 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleVersion 20 | 1.0 21 | NSPrincipalClass 22 | YTLite 23 | 24 | 25 | -------------------------------------------------------------------------------- /Utils/YTLUserDefaults.m: -------------------------------------------------------------------------------- 1 | #import "YTLUserDefaults.h" 2 | 3 | @implementation YTLUserDefaults 4 | 5 | static NSString *const kDefaultsSuiteName = @"com.dvntm.ytlite"; 6 | 7 | + (YTLUserDefaults *)standardUserDefaults { 8 | static dispatch_once_t onceToken; 9 | static YTLUserDefaults *defaults = nil; 10 | 11 | dispatch_once(&onceToken, ^{ 12 | defaults = [[self alloc] initWithSuiteName:kDefaultsSuiteName]; 13 | [defaults registerDefaults]; 14 | }); 15 | 16 | return defaults; 17 | } 18 | 19 | - (void)reset { 20 | [self removePersistentDomainForName:kDefaultsSuiteName]; 21 | } 22 | 23 | - (void)registerDefaults { 24 | [self registerDefaults:@{ 25 | @"noAds": @YES, 26 | @"backgroundPlayback": @YES, 27 | @"removeUploads": @YES, 28 | @"speedIndex": @1, 29 | @"autoSpeedIndex": @3, 30 | @"wiFiQualityIndex": @0, 31 | @"cellQualityIndex": @0, 32 | @"pivotIndex": @0 33 | }]; 34 | } 35 | 36 | + (void)resetUserDefaults { 37 | [[self standardUserDefaults] reset]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /YouTubeHeaders.h: -------------------------------------------------------------------------------- 1 | #import "../YouTubeHeader/YTAlertView.h" 2 | #import "../YouTubeHeader/YTIGuideResponse.h" 3 | #import "../YouTubeHeader/YTIGuideResponseSupportedRenderers.h" 4 | #import "../YouTubeHeader/YTIPivotBarSupportedRenderers.h" 5 | #import "../YouTubeHeader/YTIPivotBarRenderer.h" 6 | #import "../YouTubeHeader/YTIBrowseRequest.h" 7 | #import "../YouTubeHeader/YTISectionListRenderer.h" 8 | #import "../YouTubeHeader/YTQTMButton.h" 9 | #import "../YouTubeHeader/YTIButtonRenderer.h" 10 | #import "../YouTubeHeader/YTVideoQualitySwitchOriginalController.h" 11 | #import "../YouTubeHeader/YTWatchController.h" 12 | #import "../YouTubeHeader/YTPlayerOverlay.h" 13 | #import "../YouTubeHeader/YTPlayerOverlayProvider.h" 14 | #import "../YouTubeHeader/YTSettingsViewController.h" 15 | #import "../YouTubeHeader/YTSettingsSectionItem.h" 16 | #import "../YouTubeHeader/YTSettingsSectionItemManager.h" 17 | #import "../YouTubeHeader/YTSettingsPickerViewController.h" 18 | #import "../YouTubeHeader/YTUIUtils.h" 19 | #import "../YouTubeHeader/YTIMenuConditionalServiceItemRenderer.h" 20 | #import "../YouTubeHeader/YTToastResponderEvent.h" 21 | #import "../YouTubeHeader/YTPageStyleController.h" 22 | #import "../YouTubeHeader/ASCollectionElement.h" 23 | #import "../YouTubeHeader/ASCollectionView.h" 24 | #import "../YouTubeHeader/ELMNodeController.h" -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: This template is designed to help you suggest improvements or new features for our project. 3 | labels: enhancement 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Describe the feature request 8 | description: Describe the feature or enhancement in detail here. Include any relevant context or background information. Be clear and concise. 9 | placeholder: | 10 | Enter your description here 11 | validations: 12 | required: true 13 | 14 | - type: checkboxes 15 | attributes: 16 | label: Post Requisites 17 | description: | 18 | **IMPORTANT:** Read carefully before checking the box. 19 | options: 20 | - label: I have checked that a similar feature request has not been reported before. 21 | required: true 22 | - label: Verified the relevance of the project and the version you are using. 23 | required: true 24 | - label: Provided a detailed description of the request and have filled in all required fields. 25 | required: true 26 | - label: I did not answer truthfully to **ALL** the above checkboxes. 27 | required: false 28 | - label: By submitting this request, **I confirm that I have filled in all the necessary fields and complied with the guidelines. Failure to comply may result in the request being closed without discussion, and repeated violations may lead to restrict account from further participation.** 29 | required: true 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: This issue template is designed to help you report problems and suggest improvements for our project. 3 | labels: bug 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Describe the bug 8 | description: Describe the issue in detail here, including any relevant context or background information. Be clear and concise. 9 | placeholder: | 10 | Enter your description here 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | attributes: 16 | label: Steps to reproduce 17 | description: | 18 | Steps to reproduce the behavior (bug) 19 | placeholder: | 20 | Example: 21 | 1. Go to Main tab 22 | 2. Tap to the video 23 | 3. See error 24 | validations: 25 | required: true 26 | 27 | - type: textarea 28 | attributes: 29 | label: Crashlog 30 | description: | 31 | **Do not put text from crashlog, include zipped Crashlog_File.ips instead** 32 | 33 | **To find and attach your crashlog:** 34 | 1. Open the Analytics & Improvements section of Settings on the device. 35 | 2. Tap Analytics Data. 36 | 3. Locate the log for your app. The log name starts with YouTubeMusic_(DateTime). 37 | 4. Select the desired log. 38 | 5. Tap the Share icon, save it in the Files app, then zip saved file. 39 | placeholder: | 40 | Drag and drop your Crashlog.zip here. 41 | validations: 42 | required: false 43 | 44 | - type: checkboxes 45 | attributes: 46 | label: Post Requisites 47 | description: | 48 | **IMPORTANT:** Read carefully before checking the box. 49 | options: 50 | - label: I have checked that a similar issue has not been reported before. 51 | required: true 52 | - label: Verified the relevance of the project and the version you are using. 53 | required: true 54 | - label: Provided a detailed description of the problem and have filled in all required fields. 55 | required: true 56 | - label: I did not answer truthfully to **ALL** the above checkboxes. 57 | required: false 58 | - label: By submitting this issue, **I confirm that I have filled in all the necessary fields and complied with the guidelines. Failure to comply may result in the issue being closed without discussion, and repeated violations may lead to restrict account from further participation.** 59 | required: true 60 | -------------------------------------------------------------------------------- /FAQs/FAQ_RU.md: -------------------------------------------------------------------------------- 1 | # ЧаВо (Часто задаваемые вопросы) 2 | 3 | [🇺🇸 English FAQ](FAQ_EN.md) | [✓] 🇷🇺 ЧаВо на Русском | [🇮🇹 FAQ in Italiano](FAQ_IT.md) | [🇵🇱 FAQ po polsku](FAQ_PL.md) 4 | 5 |
6 | Какие версии iOS поддерживает YouTube Plus? 7 |

YouTube Plus поддерживает iOS 14 и выше. Однако, если вы устанавливаете его сертификатом разработчика, нужно учитывать совместимость самой YouTube с вашей iOS. Вот список последних поддерживаемых версий YouTube для каждой iOS:

8 |
  • iOS 14: YouTube v19.20.2
  • 9 |
  • iOS 15: YouTube v20.21.6
  • 10 |
  • iOS 16+: Любая версия, поддерживаемая YouTube
  • 11 |
    12 |
    13 |
    14 | Моя версия iOS более не поддерживается последним YouTube-ом. Что делать? 15 |

    Вот возможные варианты:

    16 |
  • Установить джейлбрейк, установить поддерживаемую версию YouTube из App Store, затем установить YouTube Plus как твик
  • 17 |
  • Установить TrollStore, установить TrollFools через TrollStore, установить подходящую версию YouTube из App Store, затем «инжектнуть» YouTube Plus через TrollFools
  • 18 |
  • Найти и скачать совместимую IPA-версию в интернете, затем собрать YouTube Plus через GitHub Actions
  • 19 |
    20 |
    21 |
    22 | Перестала работать функция трансляции на ТВ на сертификате разработчика. Что делать? 23 |

    Пока проблема не будет решена, рекомендуется использовать версию YouTube 20.14.1 или ниже.

    24 |
    25 |
    26 |
    27 | При попытке воспроизведения видео появляется Произошла ошибка. Обновите страницу и попробуйте снова. 28 |

    Прежде чем делать выводы, уточним несколько моментов:

    29 |
      30 |
    1. Это НЕ из-за блокировщика рекламы
    2. 31 |
    3. Это НЕ потому что ваш аккаунт каким-то образом был помечен
    4. 32 |
    5. Это НЕ из-за того, что ваш аккаунт добавлен в загадочный чёрный список
    6. 33 |
    34 |
    35 |

    Проблема, скорее, кроется в самом процессе сайдлоадинга, даже «чистом» YouTube без твиков. Тут пишут, что причина в некорректных или отсутствующих VisitorID/VisitorData. Такая ошибка стала встречаться чаще из-за новых механизмов YouTube по борьбе с загрузчиками.

    36 |

    Возможные временные решения:

    37 |
      38 |
    1. Полностью выйдите из аккаунта (или всех аккаунтов): Перейдите во вкладку «Вы» → Сменить аккаунт → Управление аккаунтами на этом устройстве → Удалить
    2. 39 |
    3. Просмотрите несколько длинных видео без входа в аккаунт. Оставайтесь в разлогиненном состоянии несколько часов.
    4. 40 |
    5. Заново войдите в аккаунт, на котором возникала проблема
    6. 41 |
    42 |
    43 | -------------------------------------------------------------------------------- /FAQs/FAQ_EN.md: -------------------------------------------------------------------------------- 1 | # FAQ (Frequently Asked Questions) 2 | 3 | [✓] 🇺🇸 English FAQ | [🇷🇺 ЧаВо на Русском](FAQ_RU.md) | [🇮🇹 FAQ in Italiano](FAQ_IT.md) | [🇵🇱 FAQ po Polsku](FAQ_PL.md) 4 | 5 |
    6 | What iOS versions does YouTube Plus support? 7 |

    YouTube Plus supports iOS 14 and above. However, if you're sideloading it on a non-jailbroken device, you must also consider the YouTube app's compatibility with your iOS version. Below is a list of the latest supported YouTube versions per iOS:

    8 |
  • iOS 14: YouTube v19.20.2
  • 9 |
  • iOS 15: YouTube v20.21.6
  • 10 |
  • iOS 16+: Any version, as supported by YouTube
  • 11 |
    12 |
    13 |
    14 | My iOS version is no longer supported by the latest YouTube app. What can I do? 15 |

    Here are some possible options:

    16 |
  • Jailbreak your device, install the latest supported YouTube version from the App Store, and install YouTube Plus as a tweak
  • 17 |
  • Install TrollStore, then TrollFools, install the latest supported YouTube version from the App Store, and inject YouTube Plus using TrollFools
  • 18 |
  • Find a compatible IPA version online and build a YouTube Plus app using Github actions
  • 19 |
    20 |
    21 |
    22 | Cast stopped working on sideloaded YouTube Plus. What should I do? 23 |

    Until this issue is resolved, it is recommended to use YouTube version 20.14.1 or below.

    24 |
    25 |
    26 |
    27 | When I try to play a video, I get Something went wrong. Refresh and try again later. 28 |

    Before jumping to conclusions, let’s clarify a few things:

    29 |
      30 |
    1. This is NOT caused by ad blocking
    2. 31 |
    3. This is NOT because your account was magically flagged
    4. 32 |
    5. This is NOT due to your account being secretly blacklisted
    6. 33 |
    34 |
    35 |

    The issue seems to lie somewhere in the sideloading process itself, even without any tweaks applied. It might be related to an invalid or missing VisitorID or VisitorData, as suggested here. This error has become more frequent due to YouTube’s stricter anti-download measures.

    36 |
    37 |

    Possible temporary workaround:

    38 |
      39 |
    1. Sign out of your current account (or all accounts) completely: Go to the You tab → Switch account → Manage accounts on this device → Remove from this device
    2. 40 |
    3. Watch a few full-length videos without being signed in. Stay signed out for a few hours.
    4. 41 |
    5. Sign back into the account that was having issues
    6. 42 |
    43 |
    44 | -------------------------------------------------------------------------------- /FAQs/FAQ_IT.md: -------------------------------------------------------------------------------- 1 | # FAQ (Frequently Asked Questions) 2 | 3 | [🇺🇸 English FAQ](FAQ_EN.md) | [🇷🇺 ЧаВо на Русском](FAQ_RU.md) | [✓] 🇮🇹 FAQ in Italiano | [🇵🇱 FAQ po Polsku](FAQ_PL.md) 4 | 5 |
    6 | Che versioni di iOS supporta YouTube Plus? 7 |

    YouTube Plus supporta iOS 14 e superiori. Però, se stai eseguendo il sideload su un dispositivo senza jailbreak, devi tenere conto della compatibilità dell'app di YouTube con la tua versione di iOS. Sotto trovi una lista delle ultime versioni di YouTube supportate per ogni iOS:

    8 |
  • iOS 14: YouTube v19.20.2
  • 9 |
  • iOS 15: YouTube v20.21.6
  • 10 |
  • iOS 16+: Qualsiasi versione
  • 11 |
    12 |
    13 |
    14 | La mia versione di iOS non è più supportata dall'app YouTube. Cosa posso fare? 15 |

    Ecco delle possibili opzioni:

    16 |
  • Esegui il jailbreak sul tuo dispositivo, installa l'ultima versione di YouTube supportata nell'App Store, poi installa il tweak di YouTube Plus
  • 17 |
  • Installa TrollStore, poi TrollFools, installa l'ultima versione di YouTube supportata nell'App Store, e installa YouTube Plus utilizzando TrollFools
  • 18 |
  • Trova un'IPA compatibile online e builda YouTube Plus utilizzando Github actions
  • 19 |
    20 |
    21 |
    22 | Il Cast non funziona più su YouTube Plus sideloaded. Cosa dovrei fare? 23 |

    Finché non si risolve il problema, è consigliato usare YouTube 20.14.1 o inferiori.

    24 |
    25 |
    26 |
    27 | Quando provo a riprodurre un video, mi esce Qualcosa è andato storto. Aggiorna e riprova più tardi. 28 |

    Prima di giungere a conclusioni affrettate, chiariamo un paio di cose:

    29 |
      30 |
    1. Non è causato dall'ad blocking
    2. 31 |
    3. Non è causato dal fatto che il tuo account è stato magicamente segnalato
    4. 32 |
    5. Non è causato dal fatto che il tuo account è stato inserito in blacklist
    6. 33 |
    34 |
    35 |

    Questo problema risiede nel processo del sideloading stesso, anche senza nessun tweak applicato. Potrebbe essere causato da VisitorID o VisitorData invalidi o mancanti, come suggerito qui. Questo errore è diventato più frequente a causa delle contromisure anti-download di YouTube.

    36 |
    37 |

    Possibili workaround temporanei:

    38 |
      39 |
    1. Esci dal tuo account completamente: Vai su Tab Tu → Cambia account → Gestisci account su questo dispositivo → Rimuovi da questo dispositivo
    2. 40 |
    3. Guarda un paio di video fino alla fine senza eseguire il login. Non eseguire il login per un paio d'ore.
    4. 41 |
    5. Riesegui il login nell'account con cui stavi avendo problemi
    6. 42 |
    43 |
    44 | -------------------------------------------------------------------------------- /FAQs/FAQ_PL.md: -------------------------------------------------------------------------------- 1 | # FAQ (Najczęściej Zadawane Pytania) 2 | 3 | [🇺🇸 English FAQ](FAQ_EN.md) | [🇷🇺 ЧаВо на Русском](FAQ_RU.md) | [🇮🇹 FAQ in Italiano](FAQ_IT.md) | [✓] 🇵🇱 FAQ po Polsku 4 | 5 |
    6 | Jakie wersje iOS obsługuje YouTube Plus? 7 |

    YouTube Plus obsługuje iOS 14 i nowsze. Jednakże, jeśli instalujesz go metodą sideload na urządzeniu bez jailbreaka, musisz również wziąć pod uwagę kompatybilność aplikacji YouTube z Twoją wersją iOS. Poniżej znajduje się lista ostatnich obsługiwanych wersji YouTube dla poszczególnych wersji iOS:

    8 |
  • iOS 14: YouTube v19.20.2
  • 9 |
  • iOS 15: YouTube v20.21.6
  • 10 |
  • iOS 16+: Dowolna wersja, zgodna z obsługą przez YouTube
  • 11 |
    12 |
    13 |
    14 | Moja wersja iOS nie jest już obsługiwana przez najnowszą aplikację YouTube. Co mogę zrobić? 15 |

    Oto kilka możliwych opcji:

    16 |
  • Zrób jailbreak urządzenia, zainstaluj ostatnią obsługiwaną wersję YouTube ze sklepu App Store i zainstaluj YouTube Plus jako tweak
  • 17 |
  • Zainstaluj TrollStore, następnie TrollFools, zainstaluj ostatnią obsługiwaną wersję YouTube ze sklepu App Store i wstrzyknij YouTube Plus przy użyciu TrollFools
  • 18 |
  • Znajdź kompatybilną wersję IPA w internecie i zbuduj aplikację YouTube Plus przy użyciu GitHub Actions
  • 19 |
    20 |
    21 |
    22 | Przestało działać przesyłanie (Cast) w zainstalowanym metodą sideload YouTube Plus. Co powinienem zrobić? 23 |

    Do czasu rozwiązania problemu zaleca się korzystanie z wersji YouTube 20.14.1 lub starszej.

    24 |
    25 |
    26 |
    27 | Podczas próby odtworzenia filmu pojawia się komunikat Coś poszło nie tak. Odśwież i spróbuj ponownie później. 28 |

    Zanim wyciągniesz wnioski, wyjaśnijmy kilka rzeczy:

    29 |
      30 |
    1. To NIE jest spowodowane blokowaniem reklam
    2. 31 |
    3. To NIE jest spowodowane rzekomym oznaczeniem Twojego konta
    4. 32 |
    5. To NIE jest spowodowane ukrytym umieszczeniem Twojego konta na czarnej liście
    6. 33 |
    34 |
    35 |

    Problem wydaje się tkwić w samym procesie sideloadingu, nawet bez zastosowania jakichkolwiek tweaków. Może być on związany z nieprawidłowym lub brakującym VisitorID lub VisitorData, jak zasugerowano tutaj. Błąd ten występuje częściej z powodu zaostrzenia zabezpieczeń anty-pobieraniowych przez YouTube.

    36 |
    37 |

    Możliwe tymczasowe obejście:

    38 |
      39 |
    1. Całkowicie wyloguj się z obecnego konta (lub wszystkich kont): Przejdź do zakładki Ty → Zmień konto → Zarządzaj kontami na tym urządzeniu → Usuń z tego urządzenia
    2. 40 |
    3. Obejrzyj kilka pełnometrażowych filmów bez logowania się. Pozostań wylogowany przez kilka godzin.
    4. 41 |
    5. Zaloguj się ponownie na konto, na którym występował problem
    6. 42 |
    43 |
    -------------------------------------------------------------------------------- /Utils/Reachability.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011, Tony Million. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #import 29 | #import 30 | 31 | //! Project version number for MacOSReachability. 32 | FOUNDATION_EXPORT double ReachabilityVersionNumber; 33 | 34 | //! Project version string for MacOSReachability. 35 | FOUNDATION_EXPORT const unsigned char ReachabilityVersionString[]; 36 | 37 | /** 38 | * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X. 39 | * 40 | * @see http://nshipster.com/ns_enum-ns_options/ 41 | **/ 42 | #ifndef NS_ENUM 43 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 44 | #endif 45 | 46 | extern NSString *const kReachabilityChangedNotification; 47 | 48 | typedef NS_ENUM(NSInteger, NetworkStatus) { 49 | // Apple NetworkStatus Compatible Names. 50 | NotReachable = 0, 51 | ReachableViaWiFi = 2, 52 | ReachableViaWWAN = 1 53 | }; 54 | 55 | @class Reachability; 56 | 57 | typedef void (^NetworkReachable)(Reachability * reachability); 58 | typedef void (^NetworkUnreachable)(Reachability * reachability); 59 | typedef void (^NetworkReachability)(Reachability * reachability, SCNetworkConnectionFlags flags); 60 | 61 | 62 | @interface Reachability : NSObject 63 | 64 | @property (nonatomic, copy) NetworkReachable reachableBlock; 65 | @property (nonatomic, copy) NetworkUnreachable unreachableBlock; 66 | @property (nonatomic, copy) NetworkReachability reachabilityBlock; 67 | 68 | @property (nonatomic, assign) BOOL reachableOnWWAN; 69 | 70 | 71 | +(instancetype)reachabilityWithHostname:(NSString*)hostname; 72 | // This is identical to the function above, but is here to maintain 73 | //compatibility with Apples original code. (see .m) 74 | +(instancetype)reachabilityWithHostName:(NSString*)hostname; 75 | +(instancetype)reachabilityForInternetConnection; 76 | +(instancetype)reachabilityWithAddress:(void *)hostAddress; 77 | +(instancetype)reachabilityForLocalWiFi; 78 | +(instancetype)reachabilityWithURL:(NSURL*)url; 79 | 80 | -(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref; 81 | 82 | -(BOOL)startNotifier; 83 | -(void)stopNotifier; 84 | 85 | -(BOOL)isReachable; 86 | -(BOOL)isReachableViaWWAN; 87 | -(BOOL)isReachableViaWiFi; 88 | 89 | // WWAN may be available, but not active until a connection has been established. 90 | // WiFi may require a connection for VPN on Demand. 91 | -(BOOL)isConnectionRequired; // Identical DDG variant. 92 | -(BOOL)connectionRequired; // Apple's routine. 93 | // Dynamic, on demand connection? 94 | -(BOOL)isConnectionOnDemand; 95 | // Is user intervention required? 96 | -(BOOL)isInterventionRequired; 97 | 98 | -(NetworkStatus)currentReachabilityStatus; 99 | -(SCNetworkReachabilityFlags)reachabilityFlags; 100 | -(NSString*)currentReachabilityString; 101 | -(NSString*)currentReachabilityFlags; 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /Sideloading.x: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | #define YT_BUNDLE_ID @"com.google.ios.youtube" 6 | #define YT_NAME @"YouTube" 7 | 8 | @interface SSOConfiguration : NSObject 9 | @end 10 | 11 | %group gSideloading 12 | // Keychain patching 13 | static NSString *accessGroupID() { 14 | NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: 15 | (__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass, 16 | @"bundleSeedID", kSecAttrAccount, 17 | @"", kSecAttrService, 18 | (id)kCFBooleanTrue, kSecReturnAttributes, 19 | nil]; 20 | CFDictionaryRef result = nil; 21 | OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); 22 | if (status == errSecItemNotFound) 23 | status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); 24 | if (status != errSecSuccess) 25 | return nil; 26 | NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; 27 | 28 | return accessGroup; 29 | } 30 | 31 | // IAmYouTube (https://github.com/PoomSmart/IAmYouTube/) 32 | %hook YTVersionUtils 33 | + (NSString *)appName { return YT_NAME; } 34 | + (NSString *)appID { return YT_BUNDLE_ID; } 35 | %end 36 | 37 | %hook GCKBUtils 38 | + (NSString *)appIdentifier { return YT_BUNDLE_ID; } 39 | %end 40 | 41 | %hook GPCDeviceInfo 42 | + (NSString *)bundleId { return YT_BUNDLE_ID; } 43 | %end 44 | 45 | %hook OGLBundle 46 | + (NSString *)shortAppName { return YT_NAME; } 47 | %end 48 | 49 | %hook GVROverlayView 50 | + (NSString *)appName { return YT_NAME; } 51 | %end 52 | 53 | %hook OGLPhenotypeFlagServiceImpl 54 | - (NSString *)bundleId { return YT_BUNDLE_ID; } 55 | %end 56 | 57 | %hook APMAEU 58 | + (BOOL)isFAS { return YES; } 59 | %end 60 | 61 | %hook GULAppEnvironmentUtil 62 | + (BOOL)isFromAppStore { return YES; } 63 | %end 64 | 65 | %hook SSOConfiguration 66 | - (id)initWithClientID:(id)clientID supportedAccountServices:(id)supportedAccountServices { 67 | self = %orig; 68 | [self setValue:YT_NAME forKey:@"_shortAppName"]; 69 | [self setValue:YT_BUNDLE_ID forKey:@"_applicationIdentifier"]; 70 | return self; 71 | } 72 | %end 73 | 74 | BOOL isSelf() { 75 | NSArray *address = [NSThread callStackReturnAddresses]; 76 | Dl_info info = {0}; 77 | if (dladdr((void *)[address[2] longLongValue], &info) == 0) return NO; 78 | NSString *path = [NSString stringWithUTF8String:info.dli_fname]; 79 | return [path hasPrefix:NSBundle.mainBundle.bundlePath]; 80 | } 81 | 82 | %hook NSBundle 83 | - (NSString *)bundleIdentifier { 84 | return isSelf() ? YT_BUNDLE_ID : %orig; 85 | } 86 | 87 | - (NSDictionary *)infoDictionary { 88 | NSDictionary *dict = %orig; 89 | if (!isSelf()) 90 | return %orig; 91 | NSMutableDictionary *info = [dict mutableCopy]; 92 | if (info[@"CFBundleIdentifier"]) info[@"CFBundleIdentifier"] = YT_BUNDLE_ID; 93 | if (info[@"CFBundleDisplayName"]) info[@"CFBundleDisplayName"] = YT_NAME; 94 | if (info[@"CFBundleName"]) info[@"CFBundleName"] = YT_NAME; 95 | return info; 96 | } 97 | 98 | - (id)objectForInfoDictionaryKey:(NSString *)key { 99 | if (!isSelf()) 100 | return %orig; 101 | if ([key isEqualToString:@"CFBundleIdentifier"]) 102 | return YT_BUNDLE_ID; 103 | if ([key isEqualToString:@"CFBundleDisplayName"] || [key isEqualToString:@"CFBundleName"]) 104 | return YT_NAME; 105 | return %orig; 106 | } 107 | %end 108 | 109 | // Fix login for YouTube 18.13.2 and higher 110 | %hook SSOKeychainHelper 111 | + (NSString *)accessGroup { 112 | return accessGroupID(); 113 | } 114 | + (NSString *)sharedAccessGroup { 115 | return accessGroupID(); 116 | } 117 | %end 118 | 119 | // Fix login for YouTube 17.33.2 and higher 120 | %hook SSOKeychainCore 121 | + (NSString *)accessGroup { 122 | return accessGroupID(); 123 | } 124 | 125 | + (NSString *)sharedAccessGroup { 126 | return accessGroupID(); 127 | } 128 | %end 129 | 130 | // Fix App Group Directory by moving it to documents directory 131 | %hook NSFileManager 132 | - (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier { 133 | if (groupIdentifier != nil) { 134 | NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; 135 | NSURL *documentsURL = [paths lastObject]; 136 | return [documentsURL URLByAppendingPathComponent:@"AppGroup"]; 137 | } 138 | return %orig(groupIdentifier); 139 | } 140 | %end 141 | %end 142 | 143 | %ctor { 144 | BOOL isAppStoreApp = [[NSFileManager defaultManager] fileExistsAtPath:[[NSBundle mainBundle] appStoreReceiptURL].path]; 145 | if (!isAppStoreApp) %init(gSideloading); 146 | } 147 | -------------------------------------------------------------------------------- /Resources/depiction.json: -------------------------------------------------------------------------------- 1 | { 2 | "minVersion": "0.1", 3 | "headerImage": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/header.png", 4 | "class": "DepictionTabView", 5 | "tintColor": "#E36678", 6 | "tabs": [ 7 | { 8 | "views": [ 9 | { 10 | "class": "DepictionSubheaderView", 11 | "useBottomMargin": false, 12 | "title": "YouTube Plus", 13 | "useBoldText": true 14 | }, 15 | { 16 | "useSpacing": true, 17 | "class": "DepictionMarkdownView", 18 | "markdown": "A flexible enhancer for YouTube app" 19 | }, 20 | { 21 | "spacing": 8, 22 | "class": "DepictionSpacerView" 23 | }, 24 | { 25 | "screenshots": [ 26 | { 27 | "accessibilityText": "Screenshot0", 28 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr1.jpg" 29 | }, 30 | { 31 | "accessibilityText": "Screenshot1", 32 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr2.jpg" 33 | }, 34 | { 35 | "accessibilityText": "Screenshot2", 36 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr3.jpg" 37 | }, 38 | { 39 | "accessibilityText": "Screenshot3", 40 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr4.jpg" 41 | }, 42 | { 43 | "accessibilityText": "Screenshot4", 44 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr5.jpg" 45 | }, 46 | { 47 | "accessibilityText": "Screenshot5", 48 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr6.jpg" 49 | }, 50 | { 51 | "accessibilityText": "Screenshot6", 52 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr7.jpg" 53 | }, 54 | { 55 | "accessibilityText": "Screenshot7", 56 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr8.jpg" 57 | }, 58 | { 59 | "accessibilityText": "Screenshot8", 60 | "url": "https://raw.githubusercontent.com/dayanch96/YTLite/refs/heads/main/Resources/scr9.jpg" 61 | } 62 | ], 63 | "itemSize": "{160, 275.41333333333336}", 64 | "class": "DepictionScreenshotsView", 65 | "itemCornerRadius": 6 66 | }, 67 | { 68 | "markdown": "### Features:\n- Download videos, audio (including audio track selection), thumbnails, posts, and profile pictures\n- Copy video, comment, and post information\n- Interface customization: Remove feed elements, reorder tabs, enable OLED mode, and as use Shorts-only mode\n- Player settings: Gestures, default quality, preferred audio track\n- Save, Load and Restore settings. Clear cache once or automatically on app startup\n- Built-in SponsorBlock\n- And much, much more\n\n*YouTube Plus preferences can be found in the YouTube settings*", 69 | "class": "DepictionMarkdownView", 70 | "useBottomMargin": false, 71 | "title": "markdown-description", 72 | "useBoldText": true 73 | }, 74 | { 75 | "class": "DepictionSeparatorView" 76 | }, 77 | { 78 | "spacing": 8, 79 | "class": "DepictionSpacerView" 80 | }, 81 | { 82 | "text": "dayanch96", 83 | "class": "DepictionTableTextView", 84 | "title": "Developer" 85 | }, 86 | { 87 | "spacing": 8, 88 | "class": "DepictionSpacerView" 89 | } 90 | ], 91 | "class": "DepictionStackView", 92 | "tabname": "Details" 93 | }, 94 | { 95 | "views": [ 96 | { 97 | "class": "DepictionTableButtonView", 98 | "title": "My Patreon", 99 | "action": "https://patreon.com/dayanch96" 100 | }, 101 | { 102 | "class": "DepictionTableButtonView", 103 | "title": "Buy me a coffee", 104 | "action": "https://buymeacoffee.com/dayanch96" 105 | } 106 | ], 107 | "class": "DepictionStackView", 108 | "tabname": "Support" 109 | } 110 | ] 111 | } 112 | -------------------------------------------------------------------------------- /YTNativeShare.x: -------------------------------------------------------------------------------- 1 | /* YouTube Native Share - An iOS Tweak to replace YouTube's share sheet and remove source identifiers. 2 | * Copyright (C) 2024 YouTube Native Share Contributors 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | * SPDX-License-Identifier: GPL-3.0-or-later 18 | */ 19 | 20 | // Source code can be found here: https://github.com/jkhsjdhjs/youtube-native-share (Thanks to @jkhsjdhjs) 21 | 22 | #include 23 | 24 | #import "../YouTubeHeader/YTUIUtils.h" 25 | 26 | #import "../protobuf/objectivec/GPBDescriptor.h" 27 | #import "../protobuf/objectivec/GPBMessage.h" 28 | #import "../protobuf/objectivec/GPBUnknownField.h" 29 | #import "../protobuf/objectivec/GPBUnknownFieldSet.h" 30 | 31 | #define ytlBool(key) [[[NSUserDefaults alloc] initWithSuiteName:@"com.dvntm.ytlite"] boolForKey:key] 32 | 33 | @interface CustomGPBMessage : GPBMessage 34 | + (instancetype)deserializeFromString:(NSString *)string; 35 | @end 36 | 37 | @interface YTICommand : GPBMessage 38 | @end 39 | 40 | @interface ELMPBCommand : GPBMessage 41 | @end 42 | 43 | @interface ELMPBShowActionSheetCommand : GPBMessage 44 | @property (nonatomic, strong, readwrite) ELMPBCommand *onAppear; 45 | @property (nonatomic, assign, readwrite) BOOL hasOnAppear; 46 | @end 47 | 48 | @interface YTIUpdateShareSheetCommand 49 | @property (nonatomic, assign, readwrite) BOOL hasSerializedShareEntity; 50 | @property (nonatomic, copy, readwrite) NSString *serializedShareEntity; 51 | + (GPBExtensionDescriptor*)updateShareSheetCommand; 52 | @end 53 | 54 | @interface YTIInnertubeCommandExtensionRoot 55 | + (GPBExtensionDescriptor*)innertubeCommand; 56 | @end 57 | 58 | typedef NS_ENUM(NSInteger, ShareEntityType) { 59 | ShareEntityFieldVideo = 1, 60 | ShareEntityFieldPlaylist = 2, 61 | ShareEntityFieldChannel = 3, 62 | ShareEntityFieldClip = 8 63 | }; 64 | 65 | static inline NSString* extractIdWithFormat(GPBUnknownFieldSet *fields, NSInteger fieldNumber, NSString *format) { 66 | if (![fields hasField:fieldNumber]) 67 | return nil; 68 | GPBUnknownField *idField = [fields getField:fieldNumber]; 69 | if ([idField.lengthDelimitedList count] != 1) 70 | return nil; 71 | NSString *id = [[NSString alloc] initWithData:[idField.lengthDelimitedList firstObject] encoding:NSUTF8StringEncoding]; 72 | return [NSString stringWithFormat:format, id]; 73 | } 74 | 75 | %hook ELMPBShowActionSheetCommand 76 | - (void)executeWithCommandContext:(id)_context handler:(id)_handler { 77 | if (!ytlBool(@"nativeShare")) 78 | return %orig; 79 | 80 | if (!self.hasOnAppear) 81 | return %orig; 82 | GPBExtensionDescriptor *innertubeCommandDescriptor = [%c(YTIInnertubeCommandExtensionRoot) innertubeCommand]; 83 | if (![self.onAppear hasExtension:innertubeCommandDescriptor]) 84 | return %orig; 85 | YTICommand *innertubeCommand = [self.onAppear getExtension:innertubeCommandDescriptor]; 86 | GPBExtensionDescriptor *updateShareSheetCommandDescriptor = [%c(YTIUpdateShareSheetCommand) updateShareSheetCommand]; 87 | if(![innertubeCommand hasExtension:updateShareSheetCommandDescriptor]) 88 | return %orig; 89 | YTIUpdateShareSheetCommand *updateShareSheetCommand = [innertubeCommand getExtension:updateShareSheetCommandDescriptor]; 90 | if (!updateShareSheetCommand.hasSerializedShareEntity) 91 | return %orig; 92 | 93 | GPBMessage *shareEntity = [%c(GPBMessage) deserializeFromString:updateShareSheetCommand.serializedShareEntity]; 94 | GPBUnknownFieldSet *fields = shareEntity.unknownFields; 95 | NSString *shareUrl; 96 | 97 | if ([fields hasField:ShareEntityFieldClip]) { 98 | GPBUnknownField *shareEntityClip = [fields getField:ShareEntityFieldClip]; 99 | if ([shareEntityClip.lengthDelimitedList count] != 1) 100 | return %orig; 101 | GPBMessage *clipMessage = [%c(GPBMessage) parseFromData:[shareEntityClip.lengthDelimitedList firstObject] error:nil]; 102 | shareUrl = extractIdWithFormat(clipMessage.unknownFields, 1, @"https://youtube.com/clip/%@"); 103 | } 104 | 105 | if (!shareUrl) 106 | shareUrl = extractIdWithFormat(fields, ShareEntityFieldChannel, @"https://youtube.com/channel/%@"); 107 | 108 | if (!shareUrl) { 109 | shareUrl = extractIdWithFormat(fields, ShareEntityFieldPlaylist, @"%@"); 110 | if (shareUrl) { 111 | if (![shareUrl hasPrefix:@"PL"] && ![shareUrl hasPrefix:@"FL"]) 112 | shareUrl = [shareUrl stringByAppendingString:@"&playnext=1"]; 113 | shareUrl = [@"https://youtube.com/playlist?list=" stringByAppendingString:shareUrl]; 114 | } 115 | } 116 | 117 | if (!shareUrl) 118 | shareUrl = extractIdWithFormat(fields, ShareEntityFieldVideo, @"https://youtube.com/watch?v=%@"); 119 | 120 | if (!shareUrl) 121 | return %orig; 122 | 123 | UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[shareUrl] applicationActivities:nil]; 124 | [[%c(YTUIUtils) topViewControllerForPresenting] presentViewController:activityViewController animated:YES completion:^{}]; 125 | } 126 | %end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YouTube Plus (ex. YTLite) 2 | A flexible enhancer for YouTube on iOS, featuring over hundred customizable options. 3 | 4 | ## Table of Contents 5 | - [Screenshots](#screenshots) 6 | - [Main Features](#main-features) 7 | - [FAQ](#faq) 8 | - [Reviews](#reviews) 9 | - [How to build a YouTube Plus app using GitHub Actions](#how-to-build-a-youtube-plus-app-using-github-actions) 10 | - [Supported YouTube Version](#supported-youtube-version) 11 | - [Tweak Integration Details](#tweak-integration-details) 12 | 13 | ## Screenshots 14 | 15 | 16 | 17 | 18 | 19 | 20 |
    Screenshot 1Screenshot 2Screenshot 3
    21 | 22 |
    23 | More screenshots 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
    Screenshot 4Screenshot 5Screenshot 6
    Screenshot 7Screenshot 8Screenshot 9
    36 |
    37 | 38 | ## Main Features 39 |
  • Download videos, audio (including audio track selection), thumbnails, posts, and profile pictures
  • 40 |
  • Copy video, comment, and post information
  • 41 |
  • Interface customization: Remove feed elements, reorder tabs, enable OLED mode, and as use Shorts-only mode
  • 42 |
  • Player settings: Gestures, default quality, preferred audio track
  • 43 |
  • Save, Load and Restore settings. Clear cache once or automatically on app startup
  • 44 |
  • Built-in SponsorBlock
  • 45 |
  • And much, much more
  • 46 |
    47 | 48 | 49 | **YouTube Plus preferences can be found in the YouTube Settings** 50 | 51 | **All contributors are listed in the Contributors section** 52 | **Used open-source libraries are listed in the Open Source Libraries section** 53 | 54 | ## FAQ 55 | - [🇺🇸 English FAQ](FAQs/FAQ_EN.md) 56 | - [🇷🇺 ЧаВо на Русском](FAQs/FAQ_RU.md) 57 | - [🇮🇹 FAQ in Italiano](FAQs/FAQ_IT.md) 58 | - [🇵🇱 FAQ po polsku](FAQs/FAQ_PL.md) 59 | 60 | ## Reviews 61 | Review by [@qbap](https://github.com/qbap) on ONE Jailbreak: https://onejailbreak.com/blog/youtube-plus/ 62 | 63 | ## How to build a YouTube Plus app using Github actions 64 | > [!NOTE] 65 | > If this your first time, complete following steps before starting: 66 | > 67 | > 1. Fork this repository using the fork button on the top right 68 | > 2. On your forked repository, go to **Repository Settings** > **Actions**, enable **Read and Write** permissions. 69 | 70 |
    71 | How to build the YouTube Plus app 72 |
      73 |
    1. Click on Sync fork, and if your branch is out-of-date, click on Update branch.
    2. 74 |
    3. Navigate to the Actions tab in your forked repository and select Create YouTube Plus app.
    4. 75 |
    5. Click the Run workflow button located on the right side.
    6. 76 |
    7. Mark or unmark the tweaks you want to integrate. Learn more about them in the Tweak Integration Details section.
    8. 77 |
    9. Prepare a decrypted .ipa file (we cannot provide this due to legal reasons), then upload it to a file provider (e.g., filebin.net, filemail.com, or Dropbox is recommended). Paste the URL of the decrypted IPA file in the provided field.
    10. 78 |
    11. NOTE: Make sure to provide a direct download link to the file, not a link to a webpage. Otherwise, the process will fail.
    12. 79 |
    13. Enter the tweak version from the releases (the latest release is selected by default). You can also change the BundleID and Display Name if desired.
    14. 80 |
    15. Make sure all inputs are correct, then click Run workflow to start the process.
    16. 81 |
    17. Wait for the build to finish. You can download the YouTube Plus app from the releases section of your forked repo. (If you can't find the releases section, go to your forked repo and add /releases to the URL, i.e., github.com/user/YTLite/releases.)
    18. 82 |
    83 |
    84 | 85 | 86 |
    87 | How to build the YouTube Plus app with your own link for the YouTube Plus tweak 88 |
      89 |
      90 |

      NOTE: This option is primarily intended for building the YouTube Plus app based on the beta file you have. In other cases, it is generally not needed.

      91 |
      92 |
    1. Click on Sync fork, and if your branch is out-of-date, click on Update branch.
    2. 93 |
    3. Navigate to the Actions tab in your forked repository and select [BETA] Build YouTube Plus app.
    4. 94 |
    5. Click the Run workflow button located on the right side.
    6. 95 |
    7. Mark or unmark the tweaks you want to integrate. Learn more about them in the Tweak Integration Details section.
    8. 96 |
    9. Prepare a decrypted .ipa file (we cannot provide this due to legal reasons), then upload it to a file provider (e.g., filebin.net, filemail.com, or Dropbox is recommended). Paste the URL of the decrypted IPA file in the provided field.
    10. 97 |
    11. Upload your beta tweak file to a file provider and paste direct link to the URL to the YouTube Plus tweak file field. You can also change the BundleID and Display Name if desired.
    12. 98 |
    13. NOTE: Make sure to provide a direct download link to the file, not a link to a webpage. Otherwise, the process will fail.
    14. 99 |
    15. Make sure all inputs are correct, then click Run workflow to start the process.
    16. 100 |
    17. Wait for the build to finish. You can download the YouTube Plus app from the releases section of your forked repo. (If you can't find the releases section, go to your forked repo and add /releases to the URL, i.e., github.com/user/YTLite/releases.)
    18. 101 |
    102 |
    103 | 104 | ## Supported YouTube Version 105 |
      106 |
    • Latest confirmed: 20.42.3
    • 107 |
    • Date tested: Nov 5, 2025
    • 108 |
    • YouTube Plus: 5.2 beta 4
    • 109 |
    110 | 111 | ## Tweak Integration Details 112 |
    113 | YouPiP 114 |

    YouPiP is a tweak developed by PoomSmart that enables the native Picture-in-Picture feature for videos in the iOS YouTube app.

    115 |

    YouPiP preferences are available in the YouTube settings.

    116 |

    Source code and additional information are available in PoomSmart's GitHub repository.

    117 |
    118 | 119 |
    120 | YTUHD 121 |

    YTUHD is a tweak developed by PoomSmart that unlocks 1440p (2K) and 2160p (4K) resolutions in the iOS YouTube app.

    122 |

    YTUHD preferences are available in the Video quality preferences section under YouTube settings.

    123 |

    Source code and additional information are available in PoomSmart's GitHub repository.

    124 |
    125 | 126 |
    127 | Return YouTube Dislikes 128 |

    Return YouTube Dislikes is a tweak developed by PoomSmart that brings back dislikes on the YouTube app.

    129 |

    Return YouTube Dislikes preferences are available in the YouTube settings.

    130 |

    Source code and additional information are available in PoomSmart's GitHub repository.

    131 |
    132 | 133 |
    134 | YouQuality 135 |

    YouQuality is a tweak developed by PoomSmart that allows to view and change video quality directly from the video overlay.

    136 |

    YouQuality can be enabled in the Video overlay section under YouTube settings.

    137 |

    Source code and additional information are available in PoomSmart's GitHub repository.

    138 |
    139 | 140 |
    141 | DontEatMyContent 142 |

    DontEatMyContent is a tweak developed by therealFoxster that prevents the Notch/Dynamic Island from munching on 2:1 video content in the iOS YouTube app.

    143 |

    DontEatMyContent preferences are available in the YouTube settings.

    144 |

    Source code and additional information are available in therealFoxster's GitHub repository.

    145 |
    146 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Create YouTube Plus app 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | 7 | enable_youpip: 8 | description: "Integrate YouPiP" 9 | type: boolean 10 | required: true 11 | default: false 12 | 13 | enable_ytuhd: 14 | description: "Integrate YTUHD" 15 | type: boolean 16 | required: true 17 | default: false 18 | 19 | enable_yq: 20 | description: "Integrate YouQuality" 21 | type: boolean 22 | required: true 23 | default: false 24 | 25 | enable_ryd: 26 | description: "Integrate Return YouTube Dislikes" 27 | type: boolean 28 | required: true 29 | default: false 30 | 31 | enable_demc: 32 | description: "Integrate DontEatMyContent" 33 | type: boolean 34 | required: true 35 | default: false 36 | 37 | ipa_url: 38 | description: "URL to the decrypted IPA file" 39 | default: "" 40 | required: true 41 | type: string 42 | 43 | tweak_version: 44 | description: "The version of the tweak to use. Enter the version manually from dayanch96/YTLite/releases or leave default" 45 | default: "5.2b4" 46 | required: true 47 | type: string 48 | 49 | display_name: 50 | description: "App Name (Optional)" 51 | default: "YouTube" 52 | required: true 53 | type: string 54 | 55 | bundle_id: 56 | description: "BundleID (Optional)" 57 | default: "com.google.ios.youtube" 58 | required: true 59 | type: string 60 | 61 | info_note: 62 | description: "TIP: Learn more about integrations in the README via the link below" 63 | default: "https://github.com/dayanch96/YTLite#tweak-integration-details" 64 | type: string 65 | required: false 66 | 67 | concurrency: 68 | group: ${{ github.workflow }}-${{ github.ref }} 69 | cancel-in-progress: true 70 | 71 | jobs: 72 | build: 73 | name: 74 | runs-on: macos-latest 75 | permissions: 76 | contents: write 77 | 78 | steps: 79 | - name: Checkout Main 80 | uses: actions/checkout@v4.1.1 81 | with: 82 | path: main 83 | submodules: recursive 84 | 85 | - name: Hide sensitive inputs 86 | uses: levibostian/action-hide-sensitive-inputs@v1 87 | with: 88 | exclude_inputs: bundle_id,display_name,enable_demc,enable_ryd,enable_youpip,enable_yq,enable_ytuhd,info_note,tweak_version 89 | 90 | - name: Download and validate IPA 91 | run: | 92 | wget "${{ inputs.ipa_url }}" --no-verbose -O ${{ github.workspace }}/youtube.ipa 93 | 94 | file_type=$(file --mime-type -b ${{ github.workspace }}/youtube.ipa) 95 | 96 | if [[ "$file_type" != "application/x-ios-app" && "$file_type" != "application/zip" ]]; then 97 | echo "::error::Validation failed: The downloaded file is not a valid IPA. Detected type: $file_type." 98 | exit 1 99 | fi 100 | 101 | - name: Install Dependencies 102 | run: brew install make ldid 103 | 104 | - name: Set PATH environment variable 105 | run: echo "$(brew --prefix make)/libexec/gnubin" >> $GITHUB_PATH 106 | 107 | - name: Cache Theos 108 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 109 | id: theos 110 | uses: actions/cache@v4 111 | env: 112 | cache-name: theos_cache_67db2ab 113 | with: 114 | path: theos/ 115 | key: ${{ env.cache-name }} 116 | restore-keys: ${{ env.cache-name }} 117 | 118 | - name: Setup Theos 119 | if: ${{ (inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc) && steps.theos.outputs.cache-hit != 'true' }} 120 | uses: actions/checkout@v4.1.7 121 | with: 122 | repository: theos/theos 123 | ref: 67db2ab8d950910161730de77c322658ea3e6b44 124 | path: ${{ github.workspace }}/theos 125 | submodules: recursive 126 | 127 | - name: Download iOS SDK 128 | if: ${{ (inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc) && steps.theos.outputs.cache-hit != 'true' }} 129 | run: | 130 | git clone --quiet -n --depth=1 --filter=tree:0 https://github.com/theos/sdks/ 131 | cd sdks 132 | git sparse-checkout set --no-cone iPhoneOS16.5.sdk 133 | git checkout 134 | mv *.sdk $THEOS/sdks 135 | env: 136 | THEOS: ${{ github.workspace }}/theos 137 | 138 | - name: Install cyan 139 | run: pipx install --force https://github.com/asdfzxcvbn/pyzule-rw/archive/main.zip 140 | 141 | - name: Download YouTube Plus 142 | id: download_ytp 143 | run: | 144 | deb_url="https://github.com/dayanch96/YTLite/releases/download/v${{ inputs.tweak_version }}/com.dvntm.ytlite_${{ inputs.tweak_version }}_iphoneos-arm.deb" 145 | wget "$deb_url" --no-verbose -O ${{ github.workspace }}/ytplus.deb 146 | 147 | - name: Clone Open in YouTube (Safari extension) 148 | run: | 149 | git clone --quiet -n --depth=1 --filter=tree:0 https://github.com/CokePokes/YoutubeExtensions/ 150 | cd YoutubeExtensions 151 | git sparse-checkout set --no-cone OpenYoutubeSafariExtension.appex 152 | git checkout 153 | mv *.appex ${{ github.workspace }} 154 | 155 | - name: Clone YouTubeHeader 156 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 157 | run: | 158 | if [ -d "$THEOS/include/YouTubeHeader" ]; then 159 | echo "YouTubeHeader exists. Pulling latest changes..." 160 | cd $THEOS/include/YouTubeHeader 161 | git pull 162 | else 163 | echo "YouTubeHeader does not exist. Cloning repository..." 164 | cd $THEOS/include 165 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouTubeHeader.git 166 | fi 167 | 168 | if [ "${{ inputs.enable_demc }}" = "true" ]; then 169 | echo "Copying YouTubeHeader to YTHeaders..." 170 | rm -rf "$THEOS/include/YTHeaders" 171 | cp -r "$THEOS/include/YouTubeHeader" "$THEOS/include/YTHeaders" 172 | fi 173 | env: 174 | THEOS: ${{ github.workspace }}/theos 175 | 176 | - name: Clone PSHeader 177 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 178 | run: | 179 | if [ -d "$THEOS/include/PSHeader" ]; then 180 | echo "PSHeader exists. Pulling latest changes..." 181 | cd $THEOS/include/PSHeader 182 | git pull 183 | else 184 | echo "PSHeader does not exist. Cloning repository..." 185 | cd $THEOS/include 186 | git clone --quiet --depth=1 https://github.com/PoomSmart/PSHeader.git 187 | fi 188 | env: 189 | THEOS: ${{ github.workspace }}/theos 190 | 191 | - name: Clone YouPiP 192 | if: ${{ inputs.enable_youpip }} 193 | run: | 194 | cd ${{ github.workspace }} 195 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouPiP.git 196 | 197 | - name: Clone YTUHD 198 | if: ${{ inputs.enable_ytuhd }} 199 | run: | 200 | cd ${{ github.workspace }} 201 | git clone --quiet --depth=1 https://github.com/Tonwalter888/YTUHD.git 202 | 203 | - name: Clone Return-YouTube-Dislikes 204 | if: ${{ inputs.enable_ryd }} 205 | run: | 206 | cd ${{ github.workspace }} 207 | git clone --quiet --depth=1 https://github.com/PoomSmart/Return-YouTube-Dislikes.git 208 | 209 | - name: Clone YouGroupSettings 210 | if: ${{ inputs.enable_demc }} 211 | run: | 212 | cd ${{ github.workspace }} 213 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouGroupSettings.git 214 | 215 | - name: Clone YouQuality 216 | if: ${{ inputs.enable_yq }} 217 | run: | 218 | cd ${{ github.workspace }} 219 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouQuality.git 220 | 221 | - name: Clone YTVideoOverlay 222 | if: ${{ inputs.enable_yq || inputs.enable_youpip }} 223 | run: | 224 | cd ${{ github.workspace }} 225 | git clone --quiet --depth=1 https://github.com/PoomSmart/YTVideoOverlay.git 226 | 227 | - name: Clone DontEatMyContent 228 | if: ${{ inputs.enable_demc }} 229 | run: | 230 | cd ${{ github.workspace }} 231 | git clone --quiet --depth=1 --recurse-submodules https://github.com/therealFoxster/DontEatMyContent.git 232 | 233 | - name: Build YouPiP 234 | if: ${{ inputs.enable_youpip }} 235 | run: | 236 | cd ${{ github.workspace }}/YouPiP 237 | make clean package DEBUG=0 FINALPACKAGE=1 238 | mv packages/*.deb ${{ github.workspace }}/youpip.deb 239 | env: 240 | THEOS: ${{ github.workspace }}/theos 241 | 242 | - name: Build YTUHD 243 | if: ${{ inputs.enable_ytuhd }} 244 | run: | 245 | cd ${{ github.workspace }}/YTUHD 246 | make clean package DEBUG=0 FINALPACKAGE=1 247 | mv packages/*.deb ${{ github.workspace }}/ytuhd.deb 248 | env: 249 | THEOS: ${{ github.workspace }}/theos 250 | 251 | - name: Build Return-YouTube-Dislikes 252 | if: ${{ inputs.enable_ryd }} 253 | run: | 254 | cd ${{ github.workspace }}/Return-YouTube-Dislikes 255 | make clean package DEBUG=0 FINALPACKAGE=1 256 | mv packages/*.deb ${{ github.workspace }}/ryd.deb 257 | env: 258 | THEOS: ${{ github.workspace }}/theos 259 | 260 | - name: Build YouGroupSettings 261 | if: ${{ inputs.enable_demc }} 262 | run: | 263 | cd ${{ github.workspace }}/YouGroupSettings 264 | make clean package DEBUG=0 FINALPACKAGE=1 265 | mv packages/*.deb ${{ github.workspace }}/ygs.deb 266 | env: 267 | THEOS: ${{ github.workspace }}/theos 268 | 269 | - name: Build YouQuality 270 | if: ${{ inputs.enable_yq }} 271 | run: | 272 | cd ${{ github.workspace }}/YouQuality 273 | make clean package DEBUG=0 FINALPACKAGE=1 274 | mv packages/*.deb ${{ github.workspace }}/yq.deb 275 | env: 276 | THEOS: ${{ github.workspace }}/theos 277 | 278 | - name: Build YTVideoOverlay 279 | if: ${{ inputs.enable_yq || inputs.enable_youpip }} 280 | run: | 281 | cd ${{ github.workspace }}/YTVideoOverlay 282 | make clean package DEBUG=0 FINALPACKAGE=1 283 | mv packages/*.deb ${{ github.workspace }}/ytvo.deb 284 | env: 285 | THEOS: ${{ github.workspace }}/theos 286 | 287 | - name: Build DontEatMyContent 288 | if: ${{ inputs.enable_demc }} 289 | run: | 290 | cd ${{ github.workspace }}/DontEatMyContent 291 | make clean package DEBUG=0 FINALPACKAGE=1 292 | mv packages/*.deb ${{ github.workspace }}/demc.deb 293 | env: 294 | THEOS: ${{ github.workspace }}/theos 295 | 296 | - name: Inject tweaks into IPA 297 | run: | 298 | tweaks="ytplus.deb OpenYoutubeSafariExtension.appex" 299 | 300 | for f in *.deb; do 301 | if [ -f "$f" ]; then 302 | tweaks="$tweaks $f" 303 | fi 304 | done 305 | 306 | cyan -i youtube.ipa -o YouTubePlus_${{ inputs.tweak_version }}.ipa -uwef $tweaks -n "${{ inputs.display_name }}" -b ${{ inputs.bundle_id }} 307 | 308 | - name: Upload to GitHub Releases 309 | uses: softprops/action-gh-release@v2.0.1 310 | with: 311 | tag_name: ytp-${{ github.run_number }} 312 | name: YouTubePlus v${{ inputs.tweak_version }} (${{ github.run_number }}) 313 | files: YouTubePlus_${{ inputs.tweak_version }}.ipa 314 | draft: true 315 | 316 | - name: Output Release URL 317 | run: | 318 | echo "::notice::Release available at: https://github.com/${{ github.repository }}/releases" 319 | -------------------------------------------------------------------------------- /.github/workflows/ytp_beta.yml: -------------------------------------------------------------------------------- 1 | name: '[BETA] Create YouTube Plus app' 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | 7 | enable_youpip: 8 | description: "Integrate YouPiP" 9 | type: boolean 10 | required: true 11 | default: false 12 | 13 | enable_ytuhd: 14 | description: "Integrate YTUHD" 15 | type: boolean 16 | required: true 17 | default: false 18 | 19 | enable_yq: 20 | description: "Integrate YouQuality" 21 | type: boolean 22 | required: true 23 | default: false 24 | 25 | enable_ryd: 26 | description: "Integrate Return YouTube Dislikes" 27 | type: boolean 28 | required: true 29 | default: false 30 | 31 | enable_demc: 32 | description: "Integrate DontEatMyContent" 33 | type: boolean 34 | required: true 35 | default: false 36 | 37 | ipa_url: 38 | description: "URL to the decrypted IPA file" 39 | default: "" 40 | required: true 41 | type: string 42 | 43 | tweak_url: 44 | description: "URL to the YouTube Plus tweak file" 45 | default: "" 46 | required: true 47 | type: string 48 | 49 | display_name: 50 | description: "App Name (Optional)" 51 | default: "YouTube" 52 | required: true 53 | type: string 54 | 55 | bundle_id: 56 | description: "BundleID (Optional)" 57 | default: "com.google.ios.youtube" 58 | required: true 59 | type: string 60 | 61 | info_note: 62 | description: "TIP: Learn more about integrations in the README via the link below" 63 | default: "https://github.com/dayanch96/YTLite#tweak-integration-details" 64 | type: string 65 | required: false 66 | 67 | concurrency: 68 | group: ${{ github.workflow }}-${{ github.ref }} 69 | cancel-in-progress: true 70 | 71 | jobs: 72 | build: 73 | name: 74 | runs-on: macos-latest 75 | permissions: 76 | contents: write 77 | 78 | steps: 79 | - name: Checkout Main 80 | uses: actions/checkout@v4.1.1 81 | with: 82 | path: main 83 | submodules: recursive 84 | 85 | - name: Hide sensitive inputs 86 | uses: levibostian/action-hide-sensitive-inputs@v1 87 | with: 88 | exclude_inputs: bundle_id,display_name,enable_demc,enable_ryd,enable_youpip,enable_yq,enable_ytuhd,info_note 89 | 90 | - name: Download and validate IPA 91 | run: | 92 | wget "${{ inputs.ipa_url }}" --no-verbose -O ${{ github.workspace }}/youtube.ipa 93 | 94 | file_type=$(file --mime-type -b ${{ github.workspace }}/youtube.ipa) 95 | 96 | if [[ "$file_type" != "application/x-ios-app" && "$file_type" != "application/zip" ]]; then 97 | echo "::error::Validation failed: The downloaded file is not a valid IPA. Detected type: $file_type." 98 | exit 1 99 | fi 100 | 101 | - name: Download and validate tweak 102 | run: | 103 | wget "${{ inputs.tweak_url }}" --no-verbose -O ${{ github.workspace }}/ytplus.deb 104 | 105 | file_type=$(file --mime-type -b ${{ github.workspace }}/ytplus.deb) 106 | 107 | if [[ "$file_type" != "application/vnd.debian.binary-package" ]]; then 108 | echo "::error::Validation failed: The file is not a valid DEB file. Detected type: $file_type." 109 | exit 1 110 | fi 111 | 112 | - name: Install Dependencies 113 | run: brew install make ldid 114 | 115 | - name: Set PATH environment variable 116 | run: echo "$(brew --prefix make)/libexec/gnubin" >> $GITHUB_PATH 117 | 118 | - name: Cache Theos 119 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 120 | id: theos 121 | uses: actions/cache@v4 122 | env: 123 | cache-name: theos_cache_67db2ab 124 | with: 125 | path: theos/ 126 | key: ${{ env.cache-name }} 127 | restore-keys: ${{ env.cache-name }} 128 | 129 | - name: Setup Theos 130 | if: ${{ (inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc) && steps.theos.outputs.cache-hit != 'true' }} 131 | uses: actions/checkout@v4.1.7 132 | with: 133 | repository: theos/theos 134 | ref: 67db2ab8d950910161730de77c322658ea3e6b44 135 | path: ${{ github.workspace }}/theos 136 | submodules: recursive 137 | 138 | - name: Download iOS SDK 139 | if: ${{ (inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc) && steps.theos.outputs.cache-hit != 'true' }} 140 | run: | 141 | git clone --quiet -n --depth=1 --filter=tree:0 https://github.com/theos/sdks/ 142 | cd sdks 143 | git sparse-checkout set --no-cone iPhoneOS16.5.sdk 144 | git checkout 145 | mv *.sdk $THEOS/sdks 146 | env: 147 | THEOS: ${{ github.workspace }}/theos 148 | 149 | - name: Install cyan 150 | run: pipx install --force https://github.com/asdfzxcvbn/pyzule-rw/archive/main.zip 151 | 152 | - name: Clone Open in YouTube (Safari extension) 153 | run: | 154 | git clone --quiet -n --depth=1 --filter=tree:0 https://github.com/CokePokes/YoutubeExtensions/ 155 | cd YoutubeExtensions 156 | git sparse-checkout set --no-cone OpenYoutubeSafariExtension.appex 157 | git checkout 158 | mv *.appex ${{ github.workspace }} 159 | 160 | - name: Clone YouTubeHeader 161 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 162 | run: | 163 | if [ -d "$THEOS/include/YouTubeHeader" ]; then 164 | echo "YouTubeHeader exists. Pulling latest changes..." 165 | cd $THEOS/include/YouTubeHeader 166 | git pull 167 | else 168 | echo "YouTubeHeader does not exist. Cloning repository..." 169 | cd $THEOS/include 170 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouTubeHeader.git 171 | fi 172 | 173 | if [ "${{ inputs.enable_demc }}" = "true" ]; then 174 | echo "Copying YouTubeHeader to YTHeaders..." 175 | rm -rf "$THEOS/include/YTHeaders" 176 | cp -r "$THEOS/include/YouTubeHeader" "$THEOS/include/YTHeaders" 177 | fi 178 | env: 179 | THEOS: ${{ github.workspace }}/theos 180 | 181 | - name: Clone PSHeader 182 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 183 | run: | 184 | if [ -d "$THEOS/include/PSHeader" ]; then 185 | echo "PSHeader exists. Pulling latest changes..." 186 | cd $THEOS/include/PSHeader 187 | git pull 188 | else 189 | echo "PSHeader does not exist. Cloning repository..." 190 | cd $THEOS/include 191 | git clone --quiet --depth=1 https://github.com/PoomSmart/PSHeader.git 192 | fi 193 | env: 194 | THEOS: ${{ github.workspace }}/theos 195 | 196 | - name: Clone YouPiP 197 | if: ${{ inputs.enable_youpip }} 198 | run: | 199 | cd ${{ github.workspace }} 200 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouPiP.git 201 | 202 | - name: Clone YTUHD 203 | if: ${{ inputs.enable_ytuhd }} 204 | run: | 205 | cd ${{ github.workspace }} 206 | git clone --quiet --depth=1 https://github.com/Tonwalter888/YTUHD.git 207 | 208 | - name: Clone Return-YouTube-Dislikes 209 | if: ${{ inputs.enable_ryd }} 210 | run: | 211 | cd ${{ github.workspace }} 212 | git clone --quiet --depth=1 https://github.com/PoomSmart/Return-YouTube-Dislikes.git 213 | 214 | - name: Clone YouGroupSettings 215 | if: ${{ inputs.enable_demc }} 216 | run: | 217 | cd ${{ github.workspace }} 218 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouGroupSettings.git 219 | 220 | - name: Clone YouQuality 221 | if: ${{ inputs.enable_yq }} 222 | run: | 223 | cd ${{ github.workspace }} 224 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouQuality.git 225 | 226 | - name: Clone YTVideoOverlay 227 | if: ${{ inputs.enable_yq || inputs.enable_youpip }} 228 | run: | 229 | cd ${{ github.workspace }} 230 | git clone --quiet --depth=1 https://github.com/PoomSmart/YTVideoOverlay.git 231 | 232 | - name: Clone DontEatMyContent 233 | if: ${{ inputs.enable_demc }} 234 | run: | 235 | cd ${{ github.workspace }} 236 | git clone --quiet --depth=1 --recurse-submodules https://github.com/therealFoxster/DontEatMyContent.git 237 | 238 | - name: Build YouPiP 239 | if: ${{ inputs.enable_youpip }} 240 | run: | 241 | cd ${{ github.workspace }}/YouPiP 242 | make clean package DEBUG=0 FINALPACKAGE=1 243 | mv packages/*.deb ${{ github.workspace }}/youpip.deb 244 | env: 245 | THEOS: ${{ github.workspace }}/theos 246 | 247 | - name: Build YTUHD 248 | if: ${{ inputs.enable_ytuhd }} 249 | run: | 250 | cd ${{ github.workspace }}/YTUHD 251 | make clean package DEBUG=0 FINALPACKAGE=1 252 | mv packages/*.deb ${{ github.workspace }}/ytuhd.deb 253 | env: 254 | THEOS: ${{ github.workspace }}/theos 255 | 256 | - name: Build Return-YouTube-Dislikes 257 | if: ${{ inputs.enable_ryd }} 258 | run: | 259 | cd ${{ github.workspace }}/Return-YouTube-Dislikes 260 | make clean package DEBUG=0 FINALPACKAGE=1 261 | mv packages/*.deb ${{ github.workspace }}/ryd.deb 262 | env: 263 | THEOS: ${{ github.workspace }}/theos 264 | 265 | - name: Build YouGroupSettings 266 | if: ${{ inputs.enable_demc }} 267 | run: | 268 | cd ${{ github.workspace }}/YouGroupSettings 269 | make clean package DEBUG=0 FINALPACKAGE=1 270 | mv packages/*.deb ${{ github.workspace }}/ygs.deb 271 | env: 272 | THEOS: ${{ github.workspace }}/theos 273 | 274 | - name: Build YouQuality 275 | if: ${{ inputs.enable_yq }} 276 | run: | 277 | cd ${{ github.workspace }}/YouQuality 278 | make clean package DEBUG=0 FINALPACKAGE=1 279 | mv packages/*.deb ${{ github.workspace }}/yq.deb 280 | env: 281 | THEOS: ${{ github.workspace }}/theos 282 | 283 | - name: Build YTVideoOverlay 284 | if: ${{ inputs.enable_yq || inputs.enable_youpip }} 285 | run: | 286 | cd ${{ github.workspace }}/YTVideoOverlay 287 | make clean package DEBUG=0 FINALPACKAGE=1 288 | mv packages/*.deb ${{ github.workspace }}/ytvo.deb 289 | env: 290 | THEOS: ${{ github.workspace }}/theos 291 | 292 | - name: Build DontEatMyContent 293 | if: ${{ inputs.enable_demc }} 294 | run: | 295 | cd ${{ github.workspace }}/DontEatMyContent 296 | make clean package DEBUG=0 FINALPACKAGE=1 297 | mv packages/*.deb ${{ github.workspace }}/demc.deb 298 | env: 299 | THEOS: ${{ github.workspace }}/theos 300 | 301 | - name: Inject tweaks into IPA 302 | run: | 303 | tweaks="ytplus.deb OpenYoutubeSafariExtension.appex" 304 | 305 | for f in *.deb; do 306 | if [ -f "$f" ]; then 307 | tweaks="$tweaks $f" 308 | fi 309 | done 310 | 311 | cyan -i youtube.ipa -o YouTubePlus_Beta.ipa -uwef $tweaks -n "${{ inputs.display_name }}" -b ${{ inputs.bundle_id }} 312 | 313 | - name: Upload to GitHub Releases 314 | uses: softprops/action-gh-release@v2.0.1 315 | with: 316 | tag_name: ytp-beta-${{ github.run_number }} 317 | name: YouTubePlus Beta (${{ github.run_number }}) 318 | files: YouTubePlus_Beta.ipa 319 | draft: true 320 | 321 | - name: Output Release URL 322 | run: | 323 | echo "::notice::Release available at: https://github.com/${{ github.repository }}/releases" 324 | -------------------------------------------------------------------------------- /.github/workflows/cyan_ts.yml: -------------------------------------------------------------------------------- 1 | name: Generate TrollFools/Cyan files 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | 7 | create_cyan: 8 | description: "Generate .cyan file" 9 | type: boolean 10 | required: true 11 | default: true 12 | 13 | create_tf: 14 | description: "Generate .zip for TrollFools" 15 | type: boolean 16 | required: true 17 | default: true 18 | 19 | enable_youpip: 20 | description: "Integrate YouPiP" 21 | type: boolean 22 | required: true 23 | default: false 24 | 25 | enable_ytuhd: 26 | description: "Integrate YTUHD" 27 | type: boolean 28 | required: true 29 | default: false 30 | 31 | enable_yq: 32 | description: "Integrate YouQuality" 33 | type: boolean 34 | required: true 35 | default: false 36 | 37 | enable_ryd: 38 | description: "Integrate Return YouTube Dislikes" 39 | type: boolean 40 | required: true 41 | default: false 42 | 43 | enable_demc: 44 | description: "Integrate DontEatMyContent" 45 | type: boolean 46 | required: true 47 | default: false 48 | 49 | tweak_version: 50 | description: "The version of the tweak to use. Enter the version manually from dayanch96/YTLite/releases or leave default" 51 | default: "5.2b4" 52 | required: true 53 | type: string 54 | 55 | display_name: 56 | description: "App Name (Optional)" 57 | default: "YouTube" 58 | required: true 59 | type: string 60 | 61 | bundle_id: 62 | description: "BundleID (Optional)" 63 | default: "com.google.ios.youtube" 64 | required: true 65 | type: string 66 | 67 | concurrency: 68 | group: ${{ github.workflow }}-${{ github.ref }} 69 | cancel-in-progress: true 70 | 71 | jobs: 72 | build: 73 | name: 74 | runs-on: macos-latest 75 | permissions: 76 | contents: write 77 | 78 | steps: 79 | - name: Checkout Main 80 | uses: actions/checkout@v4.1.1 81 | with: 82 | path: main 83 | submodules: recursive 84 | 85 | - name: Check Inputs 86 | if: ${{ !inputs.create_cyan && !inputs.create_tf }} 87 | run: | 88 | echo "No output format selected." 89 | exit 0 90 | 91 | - name: Install Dependencies 92 | run: brew install make ldid dpkg 93 | 94 | - name: Set PATH environment variable 95 | run: echo "$(brew --prefix make)/libexec/gnubin" >> $GITHUB_PATH 96 | 97 | - name: Cache Theos 98 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 99 | id: theos 100 | uses: actions/cache@v4 101 | env: 102 | cache-name: theos_cache_67db2ab 103 | with: 104 | path: theos/ 105 | key: ${{ env.cache-name }} 106 | restore-keys: ${{ env.cache-name }} 107 | 108 | - name: Setup Theos 109 | if: ${{ (inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc) && steps.theos.outputs.cache-hit != 'true' }} 110 | uses: actions/checkout@v4.1.7 111 | with: 112 | repository: theos/theos 113 | ref: 67db2ab8d950910161730de77c322658ea3e6b44 114 | path: ${{ github.workspace }}/theos 115 | submodules: recursive 116 | 117 | - name: Download iOS SDK 118 | if: ${{ (inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc) && steps.theos.outputs.cache-hit != 'true' }} 119 | run: | 120 | git clone --quiet -n --depth=1 --filter=tree:0 https://github.com/theos/sdks/ 121 | cd sdks 122 | git sparse-checkout set --no-cone iPhoneOS16.5.sdk 123 | git checkout 124 | mv *.sdk $THEOS/sdks 125 | env: 126 | THEOS: ${{ github.workspace }}/theos 127 | 128 | - name: Install cyan 129 | if: ${{ inputs.create_cyan }} 130 | run: pipx install --force https://github.com/asdfzxcvbn/pyzule-rw/archive/main.zip 131 | 132 | - name: Download YouTube Plus 133 | id: download_ytp 134 | run: | 135 | deb_url="https://github.com/dayanch96/YTLite/releases/download/v${{ inputs.tweak_version }}/com.dvntm.ytlite_${{ inputs.tweak_version }}_iphoneos-arm.deb" 136 | wget "$deb_url" --no-verbose -O ${{ github.workspace }}/ytplus.deb 137 | 138 | - name: Clone Open in YouTube (Safari extension) 139 | if: ${{ inputs.create_cyan }} 140 | run: | 141 | git clone --quiet -n --depth=1 --filter=tree:0 https://github.com/CokePokes/YoutubeExtensions/ 142 | cd YoutubeExtensions 143 | git sparse-checkout set --no-cone OpenYoutubeSafariExtension.appex 144 | git checkout 145 | mv *.appex ${{ github.workspace }} 146 | 147 | - name: Clone YouTubeHeader 148 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 149 | run: | 150 | if [ -d "$THEOS/include/YouTubeHeader" ]; then 151 | echo "YouTubeHeader exists. Pulling latest changes..." 152 | cd $THEOS/include/YouTubeHeader 153 | git pull 154 | else 155 | echo "YouTubeHeader does not exist. Cloning repository..." 156 | cd $THEOS/include 157 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouTubeHeader.git 158 | fi 159 | 160 | if [ "${{ inputs.enable_demc }}" = "true" ]; then 161 | echo "Copying YouTubeHeader to YTHeaders..." 162 | rm -rf "$THEOS/include/YTHeaders" 163 | cp -r "$THEOS/include/YouTubeHeader" "$THEOS/include/YTHeaders" 164 | fi 165 | env: 166 | THEOS: ${{ github.workspace }}/theos 167 | 168 | - name: Clone PSHeader 169 | if: ${{ inputs.enable_youpip || inputs.enable_ytuhd || inputs.enable_yq || inputs.enable_ryd || inputs.enable_demc }} 170 | run: | 171 | if [ -d "$THEOS/include/PSHeader" ]; then 172 | echo "PSHeader exists. Pulling latest changes..." 173 | cd $THEOS/include/PSHeader 174 | git pull 175 | else 176 | echo "PSHeader does not exist. Cloning repository..." 177 | cd $THEOS/include 178 | git clone --quiet --depth=1 https://github.com/PoomSmart/PSHeader.git 179 | fi 180 | env: 181 | THEOS: ${{ github.workspace }}/theos 182 | 183 | - name: Clone YouPiP 184 | if: ${{ inputs.enable_youpip }} 185 | run: | 186 | cd ${{ github.workspace }} 187 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouPiP.git 188 | 189 | - name: Clone YTUHD 190 | if: ${{ inputs.enable_ytuhd }} 191 | run: | 192 | cd ${{ github.workspace }} 193 | git clone --quiet --depth=1 https://github.com/Tonwalter888/YTUHD.git 194 | 195 | - name: Clone Return-YouTube-Dislikes 196 | if: ${{ inputs.enable_ryd }} 197 | run: | 198 | cd ${{ github.workspace }} 199 | git clone --quiet --depth=1 https://github.com/PoomSmart/Return-YouTube-Dislikes.git 200 | 201 | - name: Clone YouGroupSettings 202 | if: ${{ inputs.enable_demc }} 203 | run: | 204 | cd ${{ github.workspace }} 205 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouGroupSettings.git 206 | 207 | - name: Clone YouQuality 208 | if: ${{ inputs.enable_yq }} 209 | run: | 210 | cd ${{ github.workspace }} 211 | git clone --quiet --depth=1 https://github.com/PoomSmart/YouQuality.git 212 | 213 | - name: Clone YTVideoOverlay 214 | if: ${{ inputs.enable_yq || inputs.enable_youpip }} 215 | run: | 216 | cd ${{ github.workspace }} 217 | git clone --quiet --depth=1 https://github.com/PoomSmart/YTVideoOverlay.git 218 | 219 | - name: Clone DontEatMyContent 220 | if: ${{ inputs.enable_demc }} 221 | run: | 222 | cd ${{ github.workspace }} 223 | git clone --quiet --depth=1 --recurse-submodules https://github.com/therealFoxster/DontEatMyContent.git 224 | 225 | - name: Build YouPiP 226 | if: ${{ inputs.enable_youpip }} 227 | run: | 228 | cd ${{ github.workspace }}/YouPiP 229 | make clean package DEBUG=0 FINALPACKAGE=1 230 | mv packages/*.deb ${{ github.workspace }}/youpip.deb 231 | env: 232 | THEOS: ${{ github.workspace }}/theos 233 | 234 | - name: Build YTUHD 235 | if: ${{ inputs.enable_ytuhd }} 236 | run: | 237 | cd ${{ github.workspace }}/YTUHD 238 | make clean package DEBUG=0 FINALPACKAGE=1 239 | mv packages/*.deb ${{ github.workspace }}/ytuhd.deb 240 | env: 241 | THEOS: ${{ github.workspace }}/theos 242 | 243 | - name: Build Return-YouTube-Dislikes 244 | if: ${{ inputs.enable_ryd }} 245 | run: | 246 | cd ${{ github.workspace }}/Return-YouTube-Dislikes 247 | make clean package DEBUG=0 FINALPACKAGE=1 248 | mv packages/*.deb ${{ github.workspace }}/ryd.deb 249 | env: 250 | THEOS: ${{ github.workspace }}/theos 251 | 252 | - name: Build YouGroupSettings 253 | if: ${{ inputs.enable_demc }} 254 | run: | 255 | cd ${{ github.workspace }}/YouGroupSettings 256 | make clean package DEBUG=0 FINALPACKAGE=1 257 | mv packages/*.deb ${{ github.workspace }}/ygs.deb 258 | env: 259 | THEOS: ${{ github.workspace }}/theos 260 | 261 | - name: Build YouQuality 262 | if: ${{ inputs.enable_yq }} 263 | run: | 264 | cd ${{ github.workspace }}/YouQuality 265 | make clean package DEBUG=0 FINALPACKAGE=1 266 | mv packages/*.deb ${{ github.workspace }}/yq.deb 267 | env: 268 | THEOS: ${{ github.workspace }}/theos 269 | 270 | - name: Build YTVideoOverlay 271 | if: ${{ inputs.enable_yq || inputs.enable_youpip }} 272 | run: | 273 | cd ${{ github.workspace }}/YTVideoOverlay 274 | make clean package DEBUG=0 FINALPACKAGE=1 275 | mv packages/*.deb ${{ github.workspace }}/ytvo.deb 276 | env: 277 | THEOS: ${{ github.workspace }}/theos 278 | 279 | - name: Build DontEatMyContent 280 | if: ${{ inputs.enable_demc }} 281 | run: | 282 | cd ${{ github.workspace }}/DontEatMyContent 283 | make clean package DEBUG=0 FINALPACKAGE=1 284 | mv packages/*.deb ${{ github.workspace }}/demc.deb 285 | env: 286 | THEOS: ${{ github.workspace }}/theos 287 | 288 | - name: Generate .cyan file 289 | if: ${{ inputs.create_cyan }} 290 | run: | 291 | tweaks="ytplus.deb OpenYoutubeSafariExtension.appex" 292 | 293 | for deb in youpip.deb ytuhd.deb ryd.deb ygs.deb yq.deb ytvo.deb demc.deb; do 294 | if [ -f "$deb" ]; then 295 | tweaks="$tweaks $deb" 296 | fi 297 | done 298 | 299 | cgen -uwef $tweaks -n "${{ inputs.display_name }}" -b ${{ inputs.bundle_id }} -o cyan_YouTubePlus_${{ inputs.tweak_version }}.cyan 300 | 301 | - name: Generate .zip file for TrollFools 302 | if: ${{ inputs.create_tf }} 303 | run: | 304 | mkdir -p ytp_tf 305 | 306 | for f in *.deb; do 307 | if [ -f "$f" ]; then 308 | echo "Extracting $f..." 309 | mkdir -p tmp_deb 310 | dpkg-deb -x "$f" tmp_deb 311 | find tmp_deb -type f -name "*.dylib" -exec cp -R {} ytp_tf/ \; 312 | find tmp_deb -type d -name "*.bundle" -exec cp -R {} ytp_tf/ \; 313 | rm -rf tmp_deb 314 | fi 315 | done 316 | 317 | echo "Zipping..." 318 | cd ytp_tf 319 | zip -r "../TrollFools_YouTubePlus_${{ inputs.tweak_version }}.zip" . 320 | cd .. 321 | rm -rf ytp_tf 322 | 323 | - name: Set output file list 324 | id: filelist 325 | run: | 326 | files="" 327 | if [ "${{ inputs.create_cyan }}" = "true" ]; then 328 | files="${files}cyan_YouTubePlus_${{ inputs.tweak_version }}.cyan"$'\n' 329 | fi 330 | if [ "${{ inputs.create_tf }}" = "true" ]; then 331 | files="${files}TrollFools_YouTubePlus_${{ inputs.tweak_version }}.zip"$'\n' 332 | fi 333 | echo -e "files<> $GITHUB_OUTPUT 334 | echo -e "$files" >> $GITHUB_OUTPUT 335 | echo "EOF" >> $GITHUB_OUTPUT 336 | 337 | - name: Upload to GitHub Releases 338 | uses: softprops/action-gh-release@v2.0.1 339 | with: 340 | tag_name: ytp-${{ github.run_number }} 341 | name: YouTubePlus v${{ inputs.tweak_version }}_cyan_trollfools (${{ github.run_number }}) 342 | files: ${{ steps.filelist.outputs.files }} 343 | draft: true 344 | 345 | - name: Output Release URL 346 | run: | 347 | echo "::notice::Release available at: https://github.com/${{ github.repository }}/releases" 348 | -------------------------------------------------------------------------------- /YTLite.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import "Utils/NSBundle+YTLite.h" 5 | #import "Utils/YTLUserDefaults.h" 6 | #import "Utils/Reachability.h" 7 | #import "YouTubeHeaders.h" 8 | 9 | #define LOC(key) [NSBundle.ytl_defaultBundle localizedStringForKey:key value:nil table:nil] 10 | 11 | #define ytlBool(key) [[YTLUserDefaults standardUserDefaults] boolForKey:key] 12 | #define ytlInt(key) [[YTLUserDefaults standardUserDefaults] integerForKey:key] 13 | 14 | #define ytlSetBool(value, key) [[YTLUserDefaults standardUserDefaults] setBool:(value) forKey:(key)] 15 | #define ytlSetInt(value, key) [[YTLUserDefaults standardUserDefaults] setInteger:(value) forKey:(key)] 16 | 17 | @interface YTTouchFeedbackController : YTCollectionViewCell 18 | @property (nonatomic, strong, readwrite) UIColor *feedbackColor; 19 | @end 20 | 21 | @interface ABCSwitch : UIControl 22 | @property (nonatomic, strong, readwrite) UIColor *onTintColor; 23 | @end 24 | 25 | @interface YTSettingsCell () 26 | - (void)setIndicatorIcon:(int)icon; 27 | - (void)setTitleDescription:(id)titleDescription; 28 | @end 29 | 30 | @interface YTSettingsSectionItemManager (Custom) 31 | - (YTSettingsSectionItem *)switchWithTitle:(NSString *)title key:(NSString *)key; 32 | - (YTSettingsSectionItem *)linkWithTitle:(NSString *)title description:(NSString *)description link:(NSString *)link; 33 | - (UIImage *)resizedImageNamed:(NSString *)iconName; 34 | @end 35 | 36 | @interface YTLightweightQTMButton () 37 | @property (nonatomic, assign, readwrite, getter=isShouldRaiseOnTouch) BOOL shouldRaiseOnTouch; 38 | @end 39 | 40 | @interface YTQTMButton () 41 | @property (nonatomic, strong, readwrite) YTIButtonRenderer *buttonRenderer; 42 | - (void)setSizeWithPaddingAndInsets:(BOOL)sizeWithPaddingAndInsets; 43 | - (BOOL)yt_isVisible; 44 | @end 45 | 46 | @interface YTRightNavigationButtons : UIView 47 | @property (nonatomic, strong) YTQTMButton *notificationButton; 48 | @property (nonatomic, strong) YTQTMButton *searchButton; 49 | @end 50 | 51 | @interface YTSearchViewController : UIViewController 52 | @end 53 | 54 | @interface YTNavigationBarTitleView : UIView 55 | @end 56 | 57 | @interface YTChipCloudCell : UICollectionViewCell 58 | @end 59 | 60 | @interface YTHeaderContentComboViewController : UIViewController 61 | - (void)refreshPivotBar; 62 | @end 63 | 64 | @interface YTPivotBarViewController : UIViewController 65 | @end 66 | 67 | @interface YTAppViewController : UIViewController 68 | @property (nonatomic, assign, readonly) YTPivotBarViewController *pivotBarViewController; 69 | - (void)hidePivotBar; 70 | - (void)showPivotBar; 71 | @end 72 | 73 | @interface YTPivotBarView : UIView 74 | - (void)selectItemWithPivotIdentifier:(id)pivotIndentifier; 75 | @end 76 | 77 | @interface YTPivotBarViewController () 78 | @property (nonatomic, weak, readwrite) YTAppViewController *parentViewController; 79 | @property (nonatomic, copy, readwrite) NSString *selectedPivotIdentifier; 80 | - (YTPivotBarView *)pivotBarView; 81 | - (void)selectItemWithPivotIdentifier:(id)pivotIndentifier; 82 | @end 83 | 84 | @interface YTPivotBarItemView : UIView 85 | @property (nonatomic, strong, readwrite) YTIPivotBarItemRenderer *renderer; 86 | @property (nonatomic, weak, readwrite) YTPivotBarViewController *delegate; 87 | @property (nonatomic, strong, readwrite) YTQTMButton *navigationButton; 88 | - (void)manageTab:(UILongPressGestureRecognizer *)gesture; 89 | @end 90 | 91 | @interface YTScrollableNavigationController : UINavigationController 92 | @property (nonatomic, weak, readwrite) YTAppViewController *parentViewController; 93 | @end 94 | 95 | @interface YTTabsViewController : UIViewController 96 | @property (nonatomic, weak, readwrite) YTScrollableNavigationController *navigationController; 97 | @end 98 | 99 | @interface YTIVideoDetails : NSObject 100 | @property (nonatomic, copy, readwrite) NSString *title; 101 | @property (nonatomic, copy, readwrite) NSString *shortDescription; 102 | @end 103 | 104 | @interface YTIPlayerResponse : NSObject 105 | @property (nonatomic, assign, readonly) YTIVideoDetails *videoDetails; 106 | @end 107 | 108 | @interface YTPlayerResponse : NSObject 109 | @property (nonatomic, assign, readonly) YTIPlayerResponse *playerData; 110 | @end 111 | 112 | @interface MLQuickMenuVideoQualitySettingFormatConstraint : NSObject 113 | - (instancetype)initWithVideoQualitySetting:(int)settings formatSelectionReason:(NSInteger)reason qualityLabel:(NSString *)label; 114 | @end 115 | 116 | @interface MLFormat : NSObject 117 | @property (nonatomic, assign, readonly) NSString *qualityLabel; 118 | @property (nonatomic, assign, readonly) int singleDimensionResolution; 119 | @end 120 | 121 | @interface YTSingleVideoTime : NSObject 122 | @property (nonatomic, assign, readonly) CGFloat time; 123 | @end 124 | 125 | @interface YTSingleVideoController : NSObject 126 | @property (nonatomic, assign, readonly) float playbackRate; 127 | @property (nonatomic, assign, readonly) CGFloat totalMediaTime; 128 | @property (nonatomic, assign, readonly) NSArray *selectableVideoFormats; 129 | - (void)setVideoFormatConstraint:(MLQuickMenuVideoQualitySettingFormatConstraint *)formatConstraint; 130 | @end 131 | 132 | @interface YTPlayerViewController : UIViewController 133 | @property (nonatomic, assign, readonly) YTPlayerResponse *playerResponse; 134 | @property (nonatomic, assign, readonly) YTSingleVideoController *activeVideo; 135 | @property (nonatomic, weak, readwrite) UIViewController *activeVideoPlayerOverlay; 136 | @property (nonatomic, weak, readwrite) UIViewController *parentViewController; 137 | @property (nonatomic, weak, readwrite) UIViewController *UIDelegate; 138 | @property (nonatomic, readonly) NSString *contentVideoID; 139 | - (void)setActiveCaptionTrack:(id)track; 140 | - (void)setPlaybackRate:(CGFloat)rate; 141 | - (void)shortsToRegular; 142 | - (void)autoFullscreen; 143 | - (void)turnOffCaptions; 144 | - (void)setAutoSpeed; 145 | - (void)autoQuality; 146 | - (void)play; 147 | - (void)pause; 148 | @end 149 | 150 | @interface YTPlayerView : UIView 151 | @property (nonatomic, weak, readwrite) YTPlayerViewController *playerViewDelegate; 152 | @property (nonatomic, strong, readwrite) UIView *overlayView; 153 | @end 154 | 155 | @interface YTMainAppControlsOverlayView : UIView 156 | @property (nonatomic, strong, readwrite) YTPlayerViewController *playerViewController; 157 | @end 158 | 159 | @interface YTReelWatchRootViewController : UIViewController 160 | @property (nonatomic, weak, readwrite) YTScrollableNavigationController *navigationController; 161 | @end 162 | 163 | @interface YTReelWatchPlaybackOverlayView : UIView 164 | @end 165 | 166 | @interface YTReelContentView : UIView 167 | @property (nonatomic, assign, readonly) YTReelWatchPlaybackOverlayView *playbackOverlay; 168 | - (void)turnShortsOnlyModeOff:(UILongPressGestureRecognizer *)gesture; 169 | @end 170 | 171 | @interface YTReelPlayerViewController : UIViewController 172 | @property (nonatomic, strong, readwrite) YTPlayerViewController *player; 173 | - (void)reelContentViewRequestsAdvanceToNextVideo:(id)video; 174 | @end 175 | 176 | @interface YTShortsPlayerViewController : YTReelPlayerViewController 177 | @property (nonatomic, weak, readwrite) YTScrollableNavigationController *navigationController; 178 | @end 179 | 180 | @interface YTPivotBarViewController () 181 | @property (nonatomic, weak, readwrite) YTShortsPlayerViewController *scrubberDelegate; 182 | @end 183 | 184 | @interface YTEngagementPanelIdentifier : NSObject 185 | @property (nonatomic, copy, readonly) NSString *identifierString; 186 | @end 187 | 188 | @interface YTEngagementPanelHeaderView : UIView 189 | @property (nonatomic, assign, readonly) YTQTMButton *closeButton; 190 | @end 191 | 192 | @interface YTWatchViewController : UIViewController 193 | @property (nonatomic, weak, readwrite) YTPlayerViewController *playerViewController; 194 | @end 195 | 196 | @interface YTEngagementPanelContainerController : UIViewController 197 | @property (nonatomic, weak, readwrite) YTWatchViewController *parentViewController; 198 | @end 199 | 200 | @interface YTEngagementPanelNavigationController : UIViewController 201 | @property (nonatomic, weak, readwrite) YTEngagementPanelContainerController *parentViewController; 202 | @end 203 | 204 | @interface YTMainAppEngagementPanelViewController : UIViewController 205 | @property (nonatomic, weak, readwrite) YTEngagementPanelNavigationController *parentViewController; 206 | @end 207 | 208 | @interface YTEngagementPanelView : UIView 209 | @property (nonatomic, weak, readwrite) YTMainAppEngagementPanelViewController *resizeDelegate; 210 | @property (nonatomic, copy, readwrite) YTEngagementPanelIdentifier *panelIdentifier; 211 | @property (nonatomic, assign, readonly) YTEngagementPanelHeaderView *headerView; 212 | - (void)didTapCopyInfoButton:(UIButton *)sender; 213 | @end 214 | 215 | @interface YTSegmentableInlinePlayerBarView : UIView 216 | @property (nonatomic, assign, readwrite) BOOL enableSnapToChapter; 217 | @end 218 | 219 | @interface YTPlayabilityResolutionUserActionUIController : NSObject 220 | - (void)confirmAlertDidPressConfirm; 221 | @end 222 | 223 | @interface YTReelPlayerButton : YTQTMButton 224 | @end 225 | 226 | @interface ELMCellNode 227 | @end 228 | 229 | @interface _ASCollectionViewCell : UICollectionViewCell 230 | - (id)node; 231 | @end 232 | 233 | @interface YTAsyncCollectionView : UICollectionView 234 | - (void)removeCellsAtIndexPath:(NSIndexPath *)indexPath; 235 | @end 236 | 237 | @interface YTReelTransparentStackView : UIStackView 238 | @end 239 | 240 | @interface YTELMView : UIView 241 | @end 242 | 243 | @interface ASNodeAncestryEnumerator : NSEnumerator 244 | @property (atomic, assign, readonly) NSMutableArray *allObjects; 245 | @end 246 | 247 | @interface ASDisplayNode () 248 | @property (nonatomic, assign, readonly) UIViewController *closestViewController; 249 | @property (atomic, assign, readonly) ASNodeAncestryEnumerator *supernodes; 250 | // @property (atomic, copy, readwrite) NSArray *yogaChildren; 251 | @property (atomic) CALayer *layer; 252 | @end 253 | 254 | @interface ELMContainerNode : ASDisplayNode 255 | @property (nonatomic, strong, readwrite) NSString *copiedComment; 256 | @property (nonatomic, strong, readwrite) NSURL *copiedURL; 257 | @end 258 | 259 | @interface ELMExpandableTextNode : ASDisplayNode 260 | @property (atomic, assign, readonly) ASDisplayNode *currentTextNode; 261 | @end 262 | 263 | @interface ASNetworkImageNode : ASDisplayNode 264 | @property (atomic, copy, readwrite) NSURL *URL; 265 | @end 266 | 267 | @interface YTImageZoomNode : ASNetworkImageNode 268 | @end 269 | 270 | @interface ASTextNode : ASDisplayNode 271 | @property (atomic, copy, readwrite) NSAttributedString *attributedText; 272 | @end 273 | 274 | @interface _ASDisplayView : UIView 275 | @property (nonatomic, strong, readwrite) ASDisplayNode *keepalive_node; 276 | - (void)postManager:(UILongPressGestureRecognizer *)sender; 277 | - (void)savePFP:(UILongPressGestureRecognizer *)sender; 278 | - (void)commentManager:(UILongPressGestureRecognizer *)sender; 279 | @end 280 | 281 | @interface YTVarispeedSwitchControllerOption : NSObject 282 | - (id)initWithTitle:(NSString *)title rate:(float)rate; 283 | @end 284 | 285 | @interface YTVarispeedSwitchController : NSObject 286 | - (void)addActionForOption:(YTVarispeedSwitchControllerOption *)option; 287 | @end 288 | 289 | @interface YTLabel : UILabel 290 | - (void)setFontAttributes:(id)attributes text:(NSString *)text; 291 | @end 292 | 293 | @interface YTInlinePlayerScrubUserEducationView : UIView 294 | @property (nonatomic, assign, readwrite) NSUInteger labelType; 295 | - (YTLabel *)userEducationLabel; 296 | - (void)setVisible:(BOOL)visible; 297 | @end 298 | 299 | @interface YTMainAppVideoPlayerOverlayViewController : UIViewController 300 | @property (nonatomic, weak, readwrite) YTPlayerViewController *parentViewController; 301 | - (CGFloat)currentPlaybackRate; 302 | @end 303 | 304 | @interface YTInlinePlayerBarContainerView : UIView 305 | @property (nonatomic, strong, readwrite) YTLabel *durationLabel; 306 | @property (nonatomic, strong, readwrite) NSString *endTimeString; 307 | @end 308 | 309 | @interface YTMainAppVideoPlayerOverlayView : UIView 310 | @property (nonatomic, assign, readonly) YTInlinePlayerScrubUserEducationView *scrubUserEducationView; 311 | @property (nonatomic, strong, readwrite) YTInlinePlayerBarContainerView *playerBar; 312 | @property (nonatomic, weak, readwrite) YTMainAppVideoPlayerOverlayViewController *delegate; 313 | - (void)speedmasterYtLite:(UILongPressGestureRecognizer *)sender; 314 | @end 315 | 316 | @interface YTMainAppVideoPlayerOverlayViewController () 317 | @property (nonatomic, assign, readonly) YTMainAppVideoPlayerOverlayView * videoPlayerOverlayView; 318 | @property (readonly, nonatomic) CGFloat mediaTime; 319 | @property (readonly, nonatomic) NSString *videoID; 320 | - (void)setPlaybackRate:(CGFloat)rate; 321 | - (CGFloat)currentPlaybackRate; 322 | @end 323 | 324 | @interface YTSpeedmasterController : NSObject 325 | @end 326 | 327 | @interface YTFormattedStringLabel : UILabel 328 | @end 329 | 330 | @interface YTActionSheetHeaderView : UIView 331 | - (void)showHeaderDivider; 332 | @end 333 | 334 | @interface YTActionSheetAction : NSObject 335 | + (instancetype)actionWithTitle:(NSString *)title iconImage:(UIImage *)image style:(NSInteger)style handler:(void (^)(void))handler; 336 | + (instancetype)actionWithTitle:(NSString *)title iconImage:(UIImage *)image secondaryIconImage:(UIImage *)secondaryIconImage accessibilityIdentifier:(NSString *)identifier handler:(void (^)(void))handler; 337 | + (instancetype)actionWithTitle:(NSString *)title titleColor:(UIColor *)titleColor iconImage:(UIImage *)image iconColor:(UIColor *)iconColor disableAutomaticButtonColor:(BOOL)autoColor accessibilityIdentifier:(NSString *)identifier handler:(void (^)(void))handler; 338 | @end 339 | 340 | @interface YTDefaultSheetController : NSObject 341 | - (void)addAction:(YTActionSheetAction *)action; 342 | - (void)presentFromView:(UIView *)view animated:(BOOL)animated completion:(void(^)(void))completion; 343 | - (void)presentFromViewController:(UIViewController *)vc animated:(BOOL)animated completion:(void(^)(void))completion; 344 | - (void)dismissViewControllerAnimated:(BOOL)animated completion:(void(^)(void))completion; 345 | 346 | + (instancetype)sheetControllerWithParentResponder:(id)parentResponder; 347 | + (instancetype)sheetControllerWithParentResponder:(id)parentResponder forcedSheetStyle:(NSInteger)style; 348 | + (instancetype)sheetControllerWithMessage:(NSString *)message delegate:(id)delegate parentResponder:(id)parentResponder; 349 | + (instancetype)sheetControllerWithMessage:(NSString *)message subMessage:(NSString *)subMessage delegate:(id)delegate parentResponder:(id)parentResponder; 350 | @end -------------------------------------------------------------------------------- /Utils/Reachability.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011, Tony Million. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #import "Reachability.h" 29 | 30 | #import 31 | #import 32 | #import 33 | #import 34 | #import 35 | #import 36 | 37 | 38 | NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification"; 39 | 40 | 41 | @interface Reachability () 42 | 43 | @property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef; 44 | @property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue; 45 | @property (nonatomic, strong) id reachabilityObject; 46 | 47 | -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags; 48 | -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags; 49 | 50 | @end 51 | 52 | 53 | static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags) 54 | { 55 | return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c", 56 | #if TARGET_OS_IPHONE 57 | (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-', 58 | #else 59 | 'X', 60 | #endif 61 | (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', 62 | (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', 63 | (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', 64 | (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', 65 | (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', 66 | (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', 67 | (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', 68 | (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-']; 69 | } 70 | 71 | // Start listening for reachability notifications on the current run loop 72 | static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) 73 | { 74 | #pragma unused (target) 75 | 76 | Reachability *reachability = ((__bridge Reachability*)info); 77 | 78 | // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool, 79 | // but what the heck eh? 80 | @autoreleasepool 81 | { 82 | [reachability reachabilityChanged:flags]; 83 | } 84 | } 85 | 86 | 87 | @implementation Reachability 88 | 89 | #pragma mark - Class Constructor Methods 90 | 91 | +(instancetype)reachabilityWithHostName:(NSString*)hostname 92 | { 93 | return [Reachability reachabilityWithHostname:hostname]; 94 | } 95 | 96 | +(instancetype)reachabilityWithHostname:(NSString*)hostname 97 | { 98 | SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]); 99 | if (ref) 100 | { 101 | id reachability = [[self alloc] initWithReachabilityRef:ref]; 102 | 103 | return reachability; 104 | } 105 | 106 | return nil; 107 | } 108 | 109 | +(instancetype)reachabilityWithAddress:(void *)hostAddress 110 | { 111 | SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); 112 | if (ref) 113 | { 114 | id reachability = [[self alloc] initWithReachabilityRef:ref]; 115 | 116 | return reachability; 117 | } 118 | 119 | return nil; 120 | } 121 | 122 | +(instancetype)reachabilityForInternetConnection 123 | { 124 | struct sockaddr_in zeroAddress; 125 | bzero(&zeroAddress, sizeof(zeroAddress)); 126 | zeroAddress.sin_len = sizeof(zeroAddress); 127 | zeroAddress.sin_family = AF_INET; 128 | 129 | return [self reachabilityWithAddress:&zeroAddress]; 130 | } 131 | 132 | +(instancetype)reachabilityForLocalWiFi 133 | { 134 | struct sockaddr_in localWifiAddress; 135 | bzero(&localWifiAddress, sizeof(localWifiAddress)); 136 | localWifiAddress.sin_len = sizeof(localWifiAddress); 137 | localWifiAddress.sin_family = AF_INET; 138 | // IN_LINKLOCALNETNUM is defined in as 169.254.0.0 139 | localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); 140 | 141 | return [self reachabilityWithAddress:&localWifiAddress]; 142 | } 143 | 144 | +(instancetype)reachabilityWithURL:(NSURL*)url 145 | { 146 | id reachability; 147 | 148 | NSString *host = url.host; 149 | BOOL isIpAddress = [self isIpAddress:host]; 150 | 151 | if (isIpAddress) 152 | { 153 | NSNumber *port = url.port ?: [url.scheme isEqualToString:@"https"] ? @(443) : @(80); 154 | 155 | struct sockaddr_in address; 156 | address.sin_len = sizeof(address); 157 | address.sin_family = AF_INET; 158 | address.sin_port = htons([port intValue]); 159 | address.sin_addr.s_addr = inet_addr([host UTF8String]); 160 | 161 | reachability = [self reachabilityWithAddress:&address]; 162 | } 163 | else 164 | { 165 | reachability = [self reachabilityWithHostname:host]; 166 | } 167 | 168 | return reachability; 169 | } 170 | 171 | +(BOOL)isIpAddress:(NSString*)host 172 | { 173 | struct in_addr pin; 174 | return 1 == inet_aton([host UTF8String], &pin); 175 | } 176 | 177 | 178 | // Initialization methods 179 | 180 | -(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref 181 | { 182 | self = [super init]; 183 | if (self != nil) 184 | { 185 | self.reachableOnWWAN = YES; 186 | self.reachabilityRef = ref; 187 | 188 | // We need to create a serial queue. 189 | // We allocate this once for the lifetime of the notifier. 190 | 191 | self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL); 192 | } 193 | 194 | return self; 195 | } 196 | 197 | -(void)dealloc 198 | { 199 | [self stopNotifier]; 200 | 201 | if(self.reachabilityRef) 202 | { 203 | CFRelease(self.reachabilityRef); 204 | self.reachabilityRef = nil; 205 | } 206 | 207 | self.reachableBlock = nil; 208 | self.unreachableBlock = nil; 209 | self.reachabilityBlock = nil; 210 | self.reachabilitySerialQueue = nil; 211 | } 212 | 213 | #pragma mark - Notifier Methods 214 | 215 | // Notifier 216 | // NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD 217 | // - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS. 218 | // INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want) 219 | 220 | -(BOOL)startNotifier 221 | { 222 | // allow start notifier to be called multiple times 223 | if(self.reachabilityObject && (self.reachabilityObject == self)) 224 | { 225 | return YES; 226 | } 227 | 228 | 229 | SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL }; 230 | context.info = (__bridge void *)self; 231 | 232 | if(SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context)) 233 | { 234 | // Set it as our reachability queue, which will retain the queue 235 | if(SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue)) 236 | { 237 | // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves 238 | // woah 239 | self.reachabilityObject = self; 240 | return YES; 241 | } 242 | else 243 | { 244 | #ifdef DEBUG 245 | NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError())); 246 | #endif 247 | 248 | // UH OH - FAILURE - stop any callbacks! 249 | SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); 250 | } 251 | } 252 | else 253 | { 254 | #ifdef DEBUG 255 | NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError())); 256 | #endif 257 | } 258 | 259 | // if we get here we fail at the internet 260 | self.reachabilityObject = nil; 261 | return NO; 262 | } 263 | 264 | -(void)stopNotifier 265 | { 266 | // First stop, any callbacks! 267 | SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); 268 | 269 | // Unregister target from the GCD serial dispatch queue. 270 | SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL); 271 | 272 | self.reachabilityObject = nil; 273 | } 274 | 275 | #pragma mark - reachability tests 276 | 277 | // This is for the case where you flick the airplane mode; 278 | // you end up getting something like this: 279 | //Reachability: WR ct----- 280 | //Reachability: -- ------- 281 | //Reachability: WR ct----- 282 | //Reachability: -- ------- 283 | // We treat this as 4 UNREACHABLE triggers - really apple should do better than this 284 | 285 | #define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) 286 | 287 | -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags 288 | { 289 | BOOL connectionUP = YES; 290 | 291 | if(!(flags & kSCNetworkReachabilityFlagsReachable)) 292 | connectionUP = NO; 293 | 294 | if( (flags & testcase) == testcase ) 295 | connectionUP = NO; 296 | 297 | #if TARGET_OS_IPHONE 298 | if(flags & kSCNetworkReachabilityFlagsIsWWAN) 299 | { 300 | // We're on 3G. 301 | if(!self.reachableOnWWAN) 302 | { 303 | // We don't want to connect when on 3G. 304 | connectionUP = NO; 305 | } 306 | } 307 | #endif 308 | 309 | return connectionUP; 310 | } 311 | 312 | -(BOOL)isReachable 313 | { 314 | SCNetworkReachabilityFlags flags; 315 | 316 | if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 317 | return NO; 318 | 319 | return [self isReachableWithFlags:flags]; 320 | } 321 | 322 | -(BOOL)isReachableViaWWAN 323 | { 324 | #if TARGET_OS_IPHONE 325 | 326 | SCNetworkReachabilityFlags flags = 0; 327 | 328 | if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 329 | { 330 | // Check we're REACHABLE 331 | if(flags & kSCNetworkReachabilityFlagsReachable) 332 | { 333 | // Now, check we're on WWAN 334 | if(flags & kSCNetworkReachabilityFlagsIsWWAN) 335 | { 336 | return YES; 337 | } 338 | } 339 | } 340 | #endif 341 | 342 | return NO; 343 | } 344 | 345 | -(BOOL)isReachableViaWiFi 346 | { 347 | SCNetworkReachabilityFlags flags = 0; 348 | 349 | if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 350 | { 351 | // Check we're reachable 352 | if((flags & kSCNetworkReachabilityFlagsReachable)) 353 | { 354 | #if TARGET_OS_IPHONE 355 | // Check we're NOT on WWAN 356 | if((flags & kSCNetworkReachabilityFlagsIsWWAN)) 357 | { 358 | return NO; 359 | } 360 | #endif 361 | return YES; 362 | } 363 | } 364 | 365 | return NO; 366 | } 367 | 368 | 369 | // WWAN may be available, but not active until a connection has been established. 370 | // WiFi may require a connection for VPN on Demand. 371 | -(BOOL)isConnectionRequired 372 | { 373 | return [self connectionRequired]; 374 | } 375 | 376 | -(BOOL)connectionRequired 377 | { 378 | SCNetworkReachabilityFlags flags; 379 | 380 | if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 381 | { 382 | return (flags & kSCNetworkReachabilityFlagsConnectionRequired); 383 | } 384 | 385 | return NO; 386 | } 387 | 388 | // Dynamic, on demand connection? 389 | -(BOOL)isConnectionOnDemand 390 | { 391 | SCNetworkReachabilityFlags flags; 392 | 393 | if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 394 | { 395 | return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && 396 | (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand))); 397 | } 398 | 399 | return NO; 400 | } 401 | 402 | // Is user intervention required? 403 | -(BOOL)isInterventionRequired 404 | { 405 | SCNetworkReachabilityFlags flags; 406 | 407 | if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 408 | { 409 | return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && 410 | (flags & kSCNetworkReachabilityFlagsInterventionRequired)); 411 | } 412 | 413 | return NO; 414 | } 415 | 416 | 417 | #pragma mark - reachability status stuff 418 | 419 | -(NetworkStatus)currentReachabilityStatus 420 | { 421 | if([self isReachable]) 422 | { 423 | if([self isReachableViaWiFi]) 424 | return ReachableViaWiFi; 425 | 426 | #if TARGET_OS_IPHONE 427 | return ReachableViaWWAN; 428 | #endif 429 | } 430 | 431 | return NotReachable; 432 | } 433 | 434 | -(SCNetworkReachabilityFlags)reachabilityFlags 435 | { 436 | SCNetworkReachabilityFlags flags = 0; 437 | 438 | if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 439 | { 440 | return flags; 441 | } 442 | 443 | return 0; 444 | } 445 | 446 | -(NSString*)currentReachabilityString 447 | { 448 | NetworkStatus temp = [self currentReachabilityStatus]; 449 | 450 | if(temp == ReachableViaWWAN) 451 | { 452 | // Updated for the fact that we have CDMA phones now! 453 | return NSLocalizedString(@"Cellular", @""); 454 | } 455 | if (temp == ReachableViaWiFi) 456 | { 457 | return NSLocalizedString(@"WiFi", @""); 458 | } 459 | 460 | return NSLocalizedString(@"No Connection", @""); 461 | } 462 | 463 | -(NSString*)currentReachabilityFlags 464 | { 465 | return reachabilityFlags([self reachabilityFlags]); 466 | } 467 | 468 | #pragma mark - Callback function calls this method 469 | 470 | -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags 471 | { 472 | if([self isReachableWithFlags:flags]) 473 | { 474 | if(self.reachableBlock) 475 | { 476 | self.reachableBlock(self); 477 | } 478 | } 479 | else 480 | { 481 | if(self.unreachableBlock) 482 | { 483 | self.unreachableBlock(self); 484 | } 485 | } 486 | 487 | if(self.reachabilityBlock) 488 | { 489 | self.reachabilityBlock(self, flags); 490 | } 491 | 492 | // this makes sure the change notification happens on the MAIN THREAD 493 | dispatch_async(dispatch_get_main_queue(), ^{ 494 | [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification 495 | object:self]; 496 | }); 497 | } 498 | 499 | #pragma mark - Debug Description 500 | 501 | - (NSString *) description 502 | { 503 | NSString *description = [NSString stringWithFormat:@"<%@: %p (%@)>", 504 | NSStringFromClass([self class]), self, [self currentReachabilityFlags]]; 505 | return description; 506 | } 507 | 508 | @end 509 | -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Main section */ 2 | "Main" = "主功能"; 3 | 4 | /* Downloading options */ 5 | "Downloading" = "下载器"; 6 | "DownloadManager" = "下载管理器"; 7 | "DownloadManagerDesc" = "将播放器下方的“下载”按钮替换为“下载管理器”,允许下载视频、音频、缩略图和复制视频信息。"; 8 | "PostManager" = "保存帖子信息"; 9 | "PostManagerDesc" = "允许通过长按复制帖子文本并将帖子另存为图片。"; 10 | "SaveProfilePhoto" = "保存个人资料图片"; 11 | "SaveProfilePhotoDesc" = "长按个人资料图片保存到照片应用程序。"; 12 | "CommentManager" = "保存评论信息"; 13 | "CommentManagerDesc" = "允许通过长按复制评论文本并将评论保存为图片。"; 14 | 15 | "YtlButtonPosition" = "下载按钮位置"; 16 | "UnderPlayer" = "播放器下方"; 17 | "Overlay" = "播放界面"; 18 | "Both" = "两者"; 19 | 20 | "PostDownloadAction" = "下载后操作"; 21 | "PostDownloadDesc" = "视频下载成功完成后将执行所选操作。"; 22 | "SaveToPhotos" = "保存到照片"; 23 | "Share" = "分享"; 24 | "Copy" = "复制"; 25 | "Ask" = "询问"; 26 | "DownloadCompleted" = "下载已完成"; 27 | 28 | "PreferredAudio" = "首选音轨"; 29 | "Selected" = "选定"; 30 | "English" = "英语"; 31 | "SelectAudioTrack" = "选择音轨"; 32 | "EnglishNotFound" = "未找到英语音轨"; 33 | 34 | "Audios" = "音频"; 35 | "AudioDRC" = "偏好稳定音量"; 36 | "AudioDRCDesc" = "如果有稳定音量(动态范围压缩)的音频,下载管理器将优先考虑此类音频。"; 37 | 38 | "CaptionsAndThumbnails" = "字幕和缩略图"; 39 | "EmbedThumbnailsToVideos" = "嵌入缩略图"; 40 | "EmbedThumbnailsToVideosDesc" = "将视频的缩略图嵌入为其元数据缩略图。"; 41 | "EmbedCapsToVideos" = "嵌入字幕"; 42 | "EmbedCapsToVideosDesc" = "将选定的字幕嵌入视频。"; 43 | "EmbedAutoGenCaps" = "自动生成/翻译的字幕"; 44 | "EmbedAutoGenCapsDesc" = "将自动生成、翻译和自动翻译的字幕添加到字幕列表。"; 45 | "DownloadCaptions" = "下载字幕"; 46 | "SelectCaption" = "选择字幕"; 47 | "Translated" = "已翻译"; 48 | "TranslatedAutoGen" = "自动翻译"; 49 | 50 | /* Nav bar options */ 51 | "Navbar" = "导航栏"; 52 | "RemoveCast" = "隐藏投射按钮"; 53 | "RemoveCastDesc" = "从导航栏中隐藏投射按钮。"; 54 | "RemoveNotifications" = "隐藏通知按钮"; 55 | "RemoveNotificationsDesc" = "从导航栏中隐藏通知按钮。"; 56 | "RemoveSearch" = "隐藏搜索按钮"; 57 | "RemoveSearchDesc" = "从导航栏中隐藏搜索按钮。"; 58 | "RemoveVoiceSearch" = "隐藏语音搜索按钮"; 59 | "RemoveVoiceSearchDesc" = "从导航栏中隐藏语音搜索按钮。"; 60 | "StickyNavbar" = "固定导航栏"; 61 | "StickyNavbarDesc" = "固定导航栏,使其在向下滚动时保持可见。"; 62 | "NoSubbar" = "隐藏子栏"; 63 | "NoSubbarDesc" = "隐藏导航栏下的子栏(全部、新内容、实时等)。"; 64 | "NoYTLogo" = "删除“YouTube”Logo"; 65 | "NoYTLogoDesc" = "删除导航栏中的“YouTube”Logo。"; 66 | "PremiumYTLogo" = "设置“Premium”Logo"; 67 | "PremiumYTLogoDesc" = "在导航栏中设置“Premium”Logo。"; 68 | 69 | /* Feed options */ 70 | "Feed" = "视频流"; 71 | "RemoveAds" = "移除广告"; 72 | "RemoveAdsDesc" = "删除程序内的广告。"; 73 | "HideShorts" = "隐藏短视频"; 74 | "HideShortsDesc" = "从首页、推荐等隐藏短视频(不适用于观看历史记录)。"; 75 | "KeepSubsShorts" = "订阅中保留短视频"; 76 | "KeepSubsShortsDesc" = "防止从“订阅”标签页中删除短视频。"; 77 | "RemoveCommunityPosts" = "删除社区帖子"; 78 | "RemoveCommunityPostsDesc" = "从视频流中删除社区帖子。"; 79 | "RemoveMixPlaylists" = "删除混合列表"; 80 | "RemoveMixPlaylistsDesc" = "删除由YouTube生成的混合播放列表"; 81 | "RemoveLiveVids" = "删除视频直播"; 82 | "RemoveLiveVidsDesc" = "首页中删除直播视频。"; 83 | "RemoveHorizontalFeeds" = "删除动态提要"; 84 | "RemoveHorizontalFeedsDesc" = "首页中删除所有动态提要(新闻、继续观看、帖子集合等)。"; 85 | "RemoveMoreTopics" = "删除“更多主题”"; 86 | "RemoveMoreTopicsDesc" = "从视频流中删除“更多主题”。"; 87 | "RemovePlayables" = "移除推广游戏"; 88 | "RemovePlayablesDesc" = "从视频流中删除可玩内容(迷你游戏)。"; 89 | "FixAlbums" = "修复封面"; 90 | "FixAlbumsDesc" = "修复来自俄罗斯用户的封面显示问题。"; 91 | 92 | /* Player options */ 93 | "Player" = "播放器"; 94 | "PlaybackQualityOnWiFi" = "WiFi网络播放质量"; 95 | "PlaybackQualityOnWiFiDesc" = "通过 WiFi 进行数据流传输时自动应用所选质量。"; 96 | "PlaybackQualityOnCellular" = "蜂窝网络播放质量"; 97 | "PlaybackQualityOnCellularDesc" = "通过移动数据进行数据流传输时自动应用所选质量。"; 98 | 99 | "PreferredCaptions" = "首选字幕"; 100 | "Original" = "原始"; 101 | "Custom" = "手动选择"; 102 | "CustomAudioTrack" = "已选音轨"; 103 | "CustomAudioTrackDesc" = "指定播放时使用的首选音轨语言(如果可用)。"; 104 | "CustomCaptions" = "已选字幕"; 105 | "CustomCaptionsDesc" = "指定播放时要显示的首选字幕语言(如果可用)"; 106 | "AutoGenCaps" = "自动生成字幕"; 107 | "AutoGenCapsDesc" = "如果找不到所选的字幕,“YouTube Plus”将尝试选择原始字幕的翻译或自动生成的字幕的翻译。"; 108 | 109 | "Player.Interface" = "界面"; 110 | "SpeedControls" = "速度控制"; 111 | "SpeedControlsDesc" = "在播放界面显示速度控制按钮。"; 112 | "MuteButton" = "静音按钮"; 113 | "MuteButtonDesc" = "在播放界面显示“静音”按钮。"; 114 | "LockButton" = "锁定按钮"; 115 | "LockButtonDesc" = "在播放界面显示一个按钮来快速锁定屏幕并切换到全屏模式。"; 116 | "HideAutoplay" = "隐藏自动播放开关"; 117 | "HideAutoplayDesc" = "从播放界面隐藏自动播放开关。"; 118 | "HideSubs" = "隐藏字幕按钮"; 119 | "HideSubsDesc" = "从播放界面隐藏字幕按钮。"; 120 | "HidePrevNext" = "隐藏上一个和下一个按钮"; 121 | "HidePrevNextDesc" = "从播放界面中隐藏上一个和下一个视频按钮。"; 122 | "ReplacePrevNext" = "快进和快退按钮"; 123 | "ReplacePrevNextDesc" = "将上一个和下一个视频按钮替换为快进和快退按钮。"; 124 | "RememberLoopMode" = "记忆循环模式"; 125 | "RememberLoopModeDesc" = "记住播放器菜单中最后选择的循环模式。"; 126 | "FullscreenToTheLeft" = "全屏左旋转"; 127 | "FullscreenToTheLeftDesc" = "点击全屏按钮后,屏幕全屏且向左旋转显示,而不是通常的向右。"; 128 | "PortraitFullscreen" = "竖屏全屏模式"; 129 | "PortraitFullscreenDesc" = "启用竖屏全屏模式支持。"; 130 | "ClassicQuality" = "经典视频质量"; 131 | "ClassicQualityDesc" = "加回经典的视频质量选择菜单。"; 132 | "ExtraSpeedOptions" = "扩展速度选项"; 133 | "ExtraSpeedOptionsDesc" = "在播放器菜单中添加更多视频播放速度的选项。"; 134 | "NoDarkBg" = "删除深色背景"; 135 | "NoDarkBgDesc" = "删除播放界面的深色背景。"; 136 | "NoEndScreenCards" = "隐藏片尾画面"; 137 | "NoEndScreenCardsDesc" = "隐藏视频结尾处的片尾屏幕(缩略图)。"; 138 | "NoAutonavEndScreenCards" = "隐藏自动播放结束画面"; 139 | "NoAutonavEndScreenCardsDesc" = "播放结束后隐藏接下来可播放的内容,禁用此选项也会禁用自动播放。"; 140 | "NoFullscreenActions" = "禁用全屏操作"; 141 | "NoFullscreenActionsDesc" = "在全屏模式下禁用操作面板。"; 142 | "PersistentProgressBar" = "持续进度条"; 143 | "PersistentProgressBarDesc" = "始终在播放器中显示进度条。"; 144 | "RedProgressBar" = "红色进度条"; 145 | "RedProgressBarDesc" = "加回红色进度条。"; 146 | "StockVolumeHUD" = "原生音量HUD"; 147 | "StockVolumeHUDDesc" = "全屏显示系统音量HUD。"; 148 | "NoRelatedVids" = "没有相关视频"; 149 | "NoRelatedVidsDesc" = "通过向上滑动删除播放界面中显示的相关视频。"; 150 | "NoPromotionCards" = "隐藏付费"; 151 | "NoPromotionCardsDesc" = "在付费视频中隐藏“付费内容”。"; 152 | "NoWatermarks" = "隐藏水印"; 153 | "NoWatermarksDesc" = "隐藏播放器的频道水印。"; 154 | "DisableAmbientMode" = "禁用氛围模式"; 155 | "DisableAmbientModeDesc" = "禁用播放器及其下方区域的氛围模式。"; 156 | "VideoEndTime" = "显示播放结束时间"; 157 | "VideoEndTimeDesc" = "将视频播放结束时间添加到播放器栏。"; 158 | "24hrFormat" = "24小时格式"; 159 | "24hrFormatDesc" = "以24小时格式显示结束时间。"; 160 | "NoRelatedWatchNexts" = "隐藏播放器下的所有视频"; 161 | "NoRelatedWatchNextsDesc" = "隐藏播放器下方的所有视频,仅保留视频信息和评论部分。"; 162 | "RemoveInlineComment" = "删除评论"; 163 | "RemoveInlineCommentDesc" = "删除播放器下方的评论板块。"; 164 | "NoSubUnderPlayer" = "删除“订阅”按钮"; 165 | "NoSubUnderPlayerDesc" = "删除播放器下方的“订阅”按钮。"; 166 | "PlayerNoShare" = "删除“分享”按钮"; 167 | "PlayerNoShareDesc" = "删除播放器下方的“分享”按钮。"; 168 | "PlayerNoThanks" = "删除“感谢”按钮"; 169 | "PlayerNoThanksDesc" = "删除播放器下方的“感谢”按钮。"; 170 | "PlayerNoRemix" = "删除“混剪”按钮"; 171 | "PlayerNoRemixDesc" = "删除播放器下方的“混剪”按钮。"; 172 | "PlayerNoDownload" = "删除“下载”按钮"; 173 | "PlayerNoDownloadDesc" = "删除播放器下方的“下载”按钮。"; 174 | "PlayerNoClip" = "删除“剪辑”按钮"; 175 | "PlayerNoClipDesc" = "删除播放器下方的“剪辑”按钮。"; 176 | "PlayerNoSave" = "删除“保存”按钮"; 177 | "PlayerNoSaveDesc" = "删除播放器下方的“保存”按钮。"; 178 | "PlayerNoReport" = "删除“举报”按钮"; 179 | "PlayerNoReportDesc" = "删除播放器下方的“举报”按钮。"; 180 | 181 | "ProgressBarStyle" = "进度条样式"; 182 | "SolidColor" = "纯色"; 183 | "Gradient" = "渐变"; 184 | "MainColor" = "主色"; 185 | "GradientColor" = "渐变颜色"; 186 | "ScrubberColor" = "进度点颜色"; 187 | 188 | "Player.Actions" = "操作"; 189 | "DefaultPlaybackRate" = "默认播放速率"; 190 | "DefaultPlaybackRateDesc" = "覆盖默认播放速度。"; 191 | "BackgroundPlayback" = "后台播放"; 192 | "BackgroundPlaybackDesc" = "启用后台播放。"; 193 | "Miniplayer" = "启用迷你播放器"; 194 | "MiniplayerDesc" = "启用迷你播放器来播放最初不是为其设计的视频,例如针对儿童的视频。"; 195 | "DisableAutoplay" = "禁用自动播放视频"; 196 | "DisableAutoplayDesc" = "打开后防止视频自动播放。"; 197 | "DisableAutoCaptions" = "禁用自动字幕"; 198 | "DisableAutoCaptionsDesc" = "防止自动激活字幕。"; 199 | "NoContentWarning" = "跳过内容警告"; 200 | "NoContentWarningDesc" = "跳过敏感内容警告消息。"; 201 | "NoHints" = "禁用提示"; 202 | "NoHintsDesc" = "禁用播放期间出现在右上角的作者提示。"; 203 | "AutoFullscreen" = "全屏模式"; 204 | "AutoFullscreenDesc" = "自动以全屏模式播放视频。"; 205 | "ExitFullscreen" = "完成后退出全屏模式"; 206 | "ExitFullscreenDesc" = "在视频播放结束时退出全屏模式。"; 207 | 208 | "Player.Gestures" = "手势"; 209 | "CompactToast" = "紧凑型提示"; 210 | "CompactToastDesc" = "显示紧凑胶囊风格的提示,用于提示播放器手势。"; 211 | "LeftSideGesture" = "左侧手势"; 212 | "LeftSideGestureDesc" = "通过在屏幕左侧垂直滑动来调整所选设置。"; 213 | "RightSideGesture" = "右侧手势"; 214 | "RightSideGestureDesc" = "通过在屏幕右侧垂直滑动来调整所选设置。"; 215 | "ActivationAreaWidth" = "手势激活宽度"; 216 | "ActivationAreaWidthDesc" = "此值决定了屏幕左侧和右侧的手势识别区域(以像素为单位)\n\n允许的最大值为屏幕宽度的三分之一。\n\n调整此值有助于防止在尝试“最小化或展开”播放器时意外激活。"; 217 | "HoldToSpeed" = "长按变更速度"; 218 | "HoldToSpeedDesc" = "设置长按播放器触发的播放速度。"; 219 | "AdjustWithFinger" = "调整速度"; 220 | "AdjustWithFingerDesc" = "允许长按播放器并上下滑动手指来调整播放速度。"; 221 | "PreserveSpeed" = "锁定速度"; 222 | "PreserveSpeedDesc" = "手势完成后锁定已调整的速度。"; 223 | "SeekAnywhere" = "滑动控制进度"; 224 | "SeekAnywhereDesc" = "允许通过左右滑动来控制播放进度。"; 225 | "SeekMethod" = "进度方式"; 226 | "SeekMethodDesc" = "独立:在整个视频时长内自由快速拖动进度,仅考虑进度灵敏度。\n\n基于视频时长:拖动进度取决于视频的长度和进度灵敏度。这对于长视频非常有用,可以防止滚动浏览视频的大部分内容。"; 227 | "Independent" = "独立"; 228 | "DurationBased" = "基于视频时长"; 229 | "SeekSensitivity" = "进度灵敏度"; 230 | "TwoFingerTapToPause" = "使用双指暂停"; 231 | "TwoFingerTapToPauseDesc" = "用双指点击屏幕即可“暂停/恢复”播放。"; 232 | "TwoFingerPanToBrightness" = "调整亮度"; 233 | "TwoFingerPanToBrightnessDesc" = "允许使用双指“向上/下”滑动来调整屏幕亮度。"; 234 | "CopyWithTimestamp" = "复制带时间戳的链接"; 235 | "CopyWithTimestampDesc" = "允许通过按下暂停按钮将带有时间戳的链接复制到剪贴板。"; 236 | "PauseOnOverlay" = "覆盖时暂停"; 237 | "PauseOnOverlayDesc" = "当播放器控制按钮出现时暂停播放。"; 238 | "DontSnap2Chapter" = "禁用双击跳转"; 239 | "DontSnap2ChapterDesc" = "禁用通过双击手势跳到下一集。"; 240 | "NoTwoFingerSnapToChapter" = "禁用双指双击"; 241 | "NoTwoFingerSnapToChapterDesc" = "禁用双指双击捕捉手势。"; 242 | "NoFreeZoom" = "禁用自由缩放手势"; 243 | "NoFreeZoomDesc" = "禁用新的自由缩放手势。"; 244 | "NoDoubleTap2Seek" = "禁用双击搜索"; 245 | "NoDoubleTap2SeekDesc" = "禁用双击搜索手势。"; 246 | 247 | /* Shorts options */ 248 | "Shorts" = "短视频"; 249 | "PlaybackMode" = "播放完成动作"; 250 | "Loop" = "循环"; 251 | "ScrollToNext" = "播放下一个"; 252 | "Stop" = "停止"; 253 | "AutoSkipShorts" = "自动播放"; 254 | "ShortsOnlyMode" = "仅短视频模式"; 255 | "ShortsOnlyModeDesc" = "将 YouTube 功能限制为只能观看短视频。"; 256 | "RestrictShorts" = "短视频限流"; 257 | "RestrictShortsDesc" = "将视频流中的短视频数量限制为10-15条。如果想避免无休止地滚动浏览短视频,这很有用。"; 258 | "ShortsProgress" = "启用进度条"; 259 | "ShortsProgressDesc" = "在短视频播放器中显示进度条。"; 260 | "SpeedByLongTap" = "加快短视频播放速度"; 261 | "SpeedByLongTapDesc" = "允许通过长按屏幕的某个部分来加快播放速度。"; 262 | "SpeedLocation" = "激活位置"; 263 | "PinchToFullscreenShorts" = "捏合至全屏"; 264 | "PinchToFullscreenShortsDesc" = "通过捏合和捏合手势管理播放界面,以全屏模式显示短视频。"; 265 | "ShortsToRegular" = "常规短视频"; 266 | "ShortsToRegularDesc" = "像打开普通视频一样打开短视频。"; 267 | "RemoveShortsLive" = "删除视频直播"; 268 | "RemoveShortsLiveDesc" = "从视频流中删除直播视频。"; 269 | 270 | "ShortsInterface" = "界面"; 271 | "HideShortsLogo" = "隐藏短视频 Logo"; 272 | "HideShortsLogoDesc" = "隐藏左上角的短视频 Logo。"; 273 | "HideShortsSearch" = "隐藏搜索按钮"; 274 | "HideShortsSearchDesc" = "从短视频播放器中隐藏搜索按钮。"; 275 | "HideShortsCamera" = "隐藏相机按钮"; 276 | "HideShortsCameraDesc" = "从短视频播放器中隐藏相机按钮。"; 277 | "HideShortsMore" = "隐藏更多(⋮)按钮"; 278 | "HideShortsMoreDesc" = "从短视频播放器中隐藏更多(⋮)按钮 。也可以通过长按屏幕来访问它。"; 279 | 280 | "HideCarouselSub" = "隐藏订阅"; 281 | "HideCarouselSubDesc" = "删除暂停状态下出现的订阅按钮。"; 282 | "HideCarouselLive" = "隐藏直播"; 283 | "HideCarouselLiveDesc" = "删除暂停状态下出现的直播按钮。"; 284 | "HideCarouselTrends" = "隐藏趋势"; 285 | "HideCarouselTrendsDesc" = "删除暂停状态下出现的热门趋势按钮。"; 286 | "HideCarouselShop" = "隐藏购物"; 287 | "HideCarouselShopDesc" = "删除暂停状态下出现的购物按钮。"; 288 | 289 | "HideShortsLike" = "隐藏“赞”按钮"; 290 | "HideShortsLikeDesc" = "从操作栏中删除“赞”按钮。"; 291 | "HideShortsDislike" = "隐藏“踩”按钮"; 292 | "HideShortsDislikeDesc" = "从操作栏中删除“不喜欢”按钮。"; 293 | "HideShortsComments" = "隐藏评论按钮"; 294 | "HideShortsCommentsDesc" = "从操作栏中删除“评论”按钮。"; 295 | "HideShortsShare" = "隐藏分享按钮"; 296 | "HideShortsShareDesc" = "从操作栏中删除分享按钮。"; 297 | "HideShortsRemix" = "删除混剪按钮"; 298 | "HideShortsRemixDesc" = "从操作栏中删除混剪按钮。"; 299 | "HideShortsSuggestion" = "隐藏建议按钮"; 300 | "HideShortsSuggestionDesc" = "删除带有建议的按钮,例如“添加到播放列表”、“超级感谢”等。"; 301 | "HideShortsSubscribe" = "隐藏关注按钮"; 302 | "HideShortsSubscribeDesc" = "删除用户名旁边的“关注”按钮。"; 303 | "HideShortsUsername" = "隐藏用户名"; 304 | "HideShortsUsernameDesc" = "隐藏频道名称。"; 305 | "HideShortsDescription" = "隐藏文案"; 306 | "HideShortsDescriptionDesc" = "隐藏短视频文案。"; 307 | "HideShortsSource" = "隐藏导航按钮"; 308 | "HideShortsSourceDesc" = "删除导航至完整视频或其他短视频的按钮。"; 309 | "HideShortsAudio" = "无音频指示器"; 310 | "HideShortsAudioDesc" = "删除短视频中使用的音频引用指示。"; 311 | 312 | /* Tab bar options */ 313 | "Tabbar" = "标签栏"; 314 | "Startup" = "启动页"; 315 | "FEwhat_to_watch" = "首页"; 316 | "FEexplore" = "探索"; 317 | "FEshorts" = "短视频"; 318 | "FEsubscriptions" = "订阅"; 319 | "FElibrary" = "“我”"; 320 | "FEuploads" = "创建"; 321 | "FEhistory" = "历史"; 322 | "FEpost_home" = "帖子"; 323 | "VLWL" = "稍后观看"; 324 | 325 | "TranslucentBar" = "半透明标签栏"; 326 | "RemoveLabels" = "移除标签"; 327 | "RemoveIndicators" = "移除红点指示"; 328 | 329 | "ActiveTabs" = "活跃的标签页"; 330 | "InactiveTabs" = "隐藏的标签页"; 331 | "HideLibraryFooter" = "长按“首页”标签页可以隐藏或显示“媒体库”标签页。"; 332 | "Warning" = "警告"; 333 | "AtLeastOneTab" = "至少有一个标签页必须保持活跃状态。"; 334 | "TabsCountRestricted" = "最多只能拥有六个活动标签页"; 335 | 336 | /* Interface options */ 337 | "Interface" = "界面项"; 338 | "OledTheme" = "OLED 主题"; 339 | "OledThemeDesc" = "将所有深色变为黑色。"; 340 | "OledKeyboard" = "OLED 键盘"; 341 | "OledKeyboardDesc" = "为深色键盘应用OLED黑色主题。"; 342 | "NoSearchHistory" = "隐藏搜索历史记录"; 343 | "NoSearchHistoryDesc" = "直观地隐藏搜索历史记录和建议。注意:搜索历史记录仍然可以在其他 YouTube 客户端中访问。"; 344 | "StickSortComments" = "固定评论排序"; 345 | "StickSortCommentsDesc" = "固定评论顶部排序功能按钮(热门、时间),滚动时不会消失。"; 346 | "HideSortComments" = "隐藏评论排序"; 347 | "HideSortCommentsDesc" = "隐藏评论排序功能,使它永远不会出现。"; 348 | "PlaylistOldMinibar" = "旧播放列表"; 349 | "PlaylistOldMinibarDesc" = "将新的浮动播放列表面板替换为旧的浮动播放列表面板。"; 350 | "OldYTUI" = "旧版界面"; 351 | "OldYTUIDesc" = "仿冒 YouTube 版本,使其变回旧版界面。"; 352 | "DisableRTL" = "禁用 RTL 格式"; 353 | "DisableRTLDesc" = "对于最初以从右到左(RTL)显示的语言,强制以从左到右(LTR)格式显示文本。"; 354 | 355 | "StartupAnimation" = "启动动画"; 356 | "StartupAnimationDesc" = "显示 YouTube 启动加载动画。"; 357 | 358 | "InterfaceStyle" = "界面样式"; 359 | 360 | "MiniplayerStyle" = "迷你播放器风格"; 361 | "MiniplayerStyleDesc" = "“切换至悬浮模式/从悬浮模式切出”需要重新启动应用程序。"; 362 | "Floating" = "悬浮"; 363 | 364 | "Other" = "其他"; 365 | "NoShareChunk" = "移除分享标识符"; 366 | "NoShareChunkDesc" = "删除分享链接中的“si=identifier”参数;作为“原生分享菜单”选项的不错的替代方案,将继续改进其分享功能。"; 367 | "AutoCheckLinks" = "自动检查剪贴板"; 368 | "AutoCheckLinksDesc" = "每次打开应用程序时,检查剪贴板中是否有与 YouTube 相关的链接。要获得正常运行的功能,请前往 iOS 设置 → YouTube → 从其他应用程序粘贴,然后选择“允许”。"; 369 | 370 | "ContextMenu" = "上下文菜单"; 371 | "NativeShare" = "原生分享菜单"; 372 | "NativeShareDesc" = "使用系统原生分享菜单来分享媒体。"; 373 | "RemoveCommentGuidelines" = "删除指南"; 374 | "RemoveCommentGuidelinesDesc" = "从评论板块删除固定指南。"; 375 | "RemovePlayNext" = "删除“加入队列,接下来就播放”"; 376 | "RemovePlayNextDesc" = "从菜单中删除“加入队列,接下来就播放”选项。"; 377 | "RemoveDownloadMenu" = "删除“下载”"; 378 | "RemoveDownloadMenuDesc" = "从菜单中删除“下载”选项。"; 379 | "RemoveWatchLaterMenu" = "删除“保存到稍后观看”"; 380 | "RemoveWatchLaterMenuDesc" = "从菜单中删除“保存到稍后观看”选项。"; 381 | "RemoveSaveToPlaylistMenu" = "删除“保存到播放列表”"; 382 | "RemoveSaveToPlaylistMenuDesc" = "从菜单中删除“保存到播放列表”选项。"; 383 | "RemoveShareMenu" = "删除“分享”"; 384 | "RemoveShareMenuDesc" = "从菜单中删除“分享”选项。"; 385 | "RemoveNotInterestedMenu" = "删除“不感兴趣”"; 386 | "RemoveNotInterestedMenuDesc" = "从菜单中删除“不感兴趣”选项。"; 387 | "RemoveDontRecommendMenu" = "删除“不推荐此频道”"; 388 | "RemoveDontRecommendMenuDesc" = "从菜单中删除“不推荐此频道”选项。"; 389 | "RemoveFeedbackMenu" = "删除“发送反馈”"; 390 | "RemoveFeedbackMenuDesc" = "从菜单中删除“发送反馈”选项。"; 391 | "RemoveReportMenu" = "删除“举报”"; 392 | "RemoveReportMenuDesc" = "从菜单中删除“举报”选项。"; 393 | "RemoveRemixMenu" = "删除“混剪”"; 394 | "RemoveRemixMenuDesc" = "从菜单中删除“混剪”选项。"; 395 | "RemoveYTMMenu" = "删除“YouTube 音乐”"; 396 | "RemoveYTMMenuDesc" = "从菜单中删除“使用 YouTube 音乐收听”选项。"; 397 | 398 | /* SponsorBlock settings */ 399 | "EnableSponsorBlock" = "启用"; 400 | "EnableSponsorBlockDesc" = "启用SponsorBlock扩展。"; 401 | "SbPlayerButton" = "启用按钮"; 402 | "SbPlayerButtonDesc" = "在播放器中添加 SponsorBlock 按钮。"; 403 | "ShowNotifications" = "显示通知"; 404 | "ShowNotificationsDesc" = "显示自动跳过片段的通知,需要手动跳过的类别的通知会始终显示。"; 405 | "SegmentsInFeedPlayer" = "显示片段颜色"; 406 | "SegmentsInFeedPlayerDesc" = "在播放器的进度条上显示各种类别片段的颜色。"; 407 | "SegmentsInMiniPlayer" = "显示片段颜色(迷你播放器)"; 408 | "SegmentsInMiniPlayerDesc" = "在迷你播放器的进度条上显示各种类别片段的颜色。"; 409 | "SegmentSkipAudio" = "音频通知"; 410 | "SegmentSkipAudioDesc" = "跳过某个片段时播放音频通知。"; 411 | "DurationWithoutSegments" = "显示新的持续时间"; 412 | "DurationWithoutSegmentsDesc" = "显示不包含片段的总时长。"; 413 | 414 | "SkipAlertDuration" = "跳过警报持续时间"; 415 | "UnskipAlertDuration" = "取消跳过警报持续时间"; 416 | 417 | "Segments" = "片段"; 418 | "Sponsor" = "赞助商"; 419 | "SponsorDesc" = "宣传与创作者无直接关系的产品或服务,创作者将以金钱或免费产品的形式获得报酬或补偿。"; 420 | "SponsorColor" = "“赞助商片段”颜色"; 421 | "Intro" = "中场休息/开场动画"; 422 | "IntroDesc" = "这些片段通常出现在视频的开头,包括动画、静帧或剪辑,也可在同一创作者的其他视频中看到。"; 423 | "IntroColor" = "“开场片段”颜色"; 424 | "Endcards" = "片尾/致谢"; 425 | "EndcardsDesc" = "通常在视频片尾或结束时,出现片尾字幕或鸣谢时。"; 426 | "EndcardsColor" = "“片尾片段”颜色"; 427 | "Interaction" = "互动提醒"; 428 | "InteractionDesc" = "明确提醒在任何付费或免费平台上点赞、订阅或与他们互动。"; 429 | "InteractionColor" = "“互动片段”颜色"; 430 | "SelfPromo" = "无偿/自我推销"; 431 | "SelfPromoDesc" = "自我推销:推广与创作者本人直接相关的产品或服务。\n无偿:创作者不会因此次推广而获得任何报酬。"; 432 | "SelfPromoColor" = "“无偿/推销片段”颜色"; 433 | "MusicOfftopic" = "音乐:非音乐片段"; 434 | "MusicOfftopicDesc" = "仅适用于以音乐为主要内容的视频。"; 435 | "MusicOfftopicColor" = "“非音乐片段”颜色"; 436 | "Preview" = "预告/回顾"; 437 | "PreviewDesc" = "展示此视频或系列中其他视频即将发生的集锦内容,所有信息都会在视频的后面重复出现。"; 438 | "PreviewColor" = "“预告片段”颜色"; 439 | "Highlight" = "精彩"; 440 | "HighlightDesc" = "用于突出视频的重点或亮点。"; 441 | "HighlightColor" = "“精彩片段”颜色"; 442 | "Jokes" = "灌水片段/笑话"; 443 | "JokesDesc" = "跑题片段/闲聊笑话,仅是灌水,对理解视频的主要内容无任何作用。"; 444 | "JokesColor" = "“灌水片段”颜色"; 445 | 446 | "Sb.Disable" = "禁用"; 447 | "Sb.Skip" = "自动跳过"; 448 | "Sb.SkipTo" = "跳过片段"; 449 | "Sb.Ask" = "询问"; 450 | "Sb.Display" = "在播放器中显示"; 451 | 452 | "PublicUserID" = "公共用户 ID"; 453 | "PrivateUserID" = "私人用户 ID"; 454 | "TapToReveal" = "轻触显示"; 455 | "Save" = "保存"; 456 | "Error.SbPublicID" = "公共用户 ID 必须正好包含 64 个字符。"; 457 | "Error.SbPrivateID" = "私人(本地)用户 ID 必须至少包含 32 个字符。"; 458 | 459 | "sb_sponsor" = "赞助片段"; 460 | "sb_intro" = "开场片段"; 461 | "sb_outro" = "片尾片段"; 462 | "sb_interaction" = "互动片段"; 463 | "sb_selfpromo" = "推销片段"; 464 | "sb_music_offtopic" = "非音乐片段"; 465 | "sb_preview" = "预告片段"; 466 | "sb_poi_highlight" = "精彩片段"; 467 | "sb_filler" = "灌水片段"; 468 | 469 | "SegmentDetected" = "%@ 检测到\n%@"; 470 | "SegmentSkipped" = "%@ 已被跳过"; 471 | "SkippedToSegment" = "跳过 %@"; 472 | "SkipSegment" = "想跳过该片段吗?"; 473 | "SkipToSegment" = "想跳到精彩部分吗?"; 474 | "Unskip" = "不跳过"; 475 | 476 | /* Developer section */ 477 | "Developer" = "开发者"; 478 | "FollowMe" = "在 X 上关注我"; 479 | "SupportDevelopment" = "支持开发"; 480 | "DonateDesc" = "您的支持对我来说意义重大!"; 481 | "SupportDevelopmentDesc" = "如果您喜欢“YouTube Plus”并愿意支持其开发,可以使用以下任何便捷的方式来赞助。\n感谢❤"; 482 | "VisitGithub" = "Github仓库"; 483 | "VisitGithubDesc" = "为本项目加注星标,请求功能或报告问题。"; 484 | "VisitTelegram" = "电报频道"; 485 | "VisitTelegramDesc" = "随时了解最新的应用程序更新"; 486 | 487 | /* Credits section */ 488 | "Credits" = "信息"; 489 | 490 | "Contributors" = "贡献者"; 491 | "DevContribution" = "开发贡献"; 492 | "SpecialThanks" = "特别感谢"; 493 | "SpecialThanks.Test" = "对插件测试做出了卓越的贡献。"; 494 | 495 | "Localizations" = "本地化翻译"; 496 | "ChineseSimplified" = "中文(简体)本地化"; 497 | "ChineseTraditional" = "中文(繁体)本地化"; 498 | "French" = "法语本地化"; 499 | "Spanish" = "西班牙语本地化"; 500 | "Japanese" = "日语本地化"; 501 | "Vietnamese" = "越南语本地化"; 502 | "Arabic" = "阿拉伯语本地化"; 503 | "Turkish" = "土耳其语本地化"; 504 | "Italian" = "意大利语本地化"; 505 | "Korean" = "韩语本地化"; 506 | "Polish" = "波兰语本地化"; 507 | 508 | "OpenSourceLibs" = "开源库"; 509 | "SupporterWall" = "支持者"; 510 | 511 | "Preferences" = "%@ 配置"; 512 | "ManagePreferences" = "配置管理"; 513 | "ImportPreferences" = "导入偏好设置"; 514 | "PreImportMessage" = "此操作将用所选文件中的设置替换当前设置。\n\n确定要继续吗??"; 515 | "ExportPreferences" = "导出偏好设置"; 516 | "ResetSettings" = "重置“YouTube Plus”设置"; 517 | "ResetMessage" = "此选项会将“YouTube Plus”设置重置为默认值并关闭 YouTube。\n\n确定要继续吗?"; 518 | 519 | "ManageCache" = "缓存管理"; 520 | "ClearCacheAtStart" = "启动时清除缓存"; 521 | "ClearCacheAtStartDesc" = "“YouTube”启动时自动清除缓存。"; 522 | "ClearCache" = "清除缓存"; 523 | 524 | "NoDonationReminder" = "禁用捐赠提醒"; 525 | "NoDonationReminderDesc" = "关闭偶尔显示的捐赠提醒。"; 526 | 527 | "ShortsOnlyWarning" = "确定要激活此模式吗?\n\n在此模式下,将只能观看短视频,且无法执行任何其他操作。\n\n可以通过双指长按禁用“仅短视频模式”。"; 528 | "ShortsModeTurnedOff" = "仅短视频模式已关闭"; 529 | 530 | "AddLibraryTab" = "恢复“我”标签页"; 531 | "RemoveLibraryTab" = "隐藏“我”标签页"; 532 | "LibraryAdded" = "“我”标签页已恢复"; 533 | "LibraryRemoved" = "“我”标签页已隐藏"; 534 | 535 | "Yes" = "是"; 536 | "No" = "不"; 537 | 538 | "Select" = "选择"; 539 | "Default" = "默认"; 540 | "Best" = "最好"; 541 | "Show" = "显示"; 542 | "Disable" = "禁用"; 543 | "Disabled" = "已禁用"; 544 | "PlaybackSpeed" = "播放速度"; 545 | "SpeedPreserved" = "速度锁定于 %@"; 546 | "ResetSpeed" = "重置"; 547 | 548 | "Toast.Brightness" = "亮度"; 549 | "Toast.PlaybackSpeed" = "播放速度"; 550 | "Toast.Volume" = "音量"; 551 | 552 | "SelectAction" = "选择操作"; 553 | "DownloadVideo" = "下载视频"; 554 | "DownloadAudio" = "下载音频"; 555 | "SaveImage" = "保存图片"; 556 | "CopyInformation" = "复制信息"; 557 | "CopyChannelName" = "复制频道名称"; 558 | "CopyTitle" = "复制标题"; 559 | "CopyDescription" = "复制描述"; 560 | "CopyTimestampedLink" = "复制带时间戳的链接"; 561 | "CopyTranscript" = "复制字幕"; 562 | "PlayInExternalPlayer" = "在外部播放器中播放"; 563 | "PlayInSystemPlayer" = "在系统播放器中播放"; 564 | "PlayInInfuse" = "用 Infuse 播放"; 565 | "PlayInVLC" = "用 VLC 播放"; 566 | "PlayerNotFound" = "未找到播放器"; 567 | "OpenAsRegularVideo" = "像普通视频一样打开"; 568 | "CopyPostText" = "复制帖子文本"; 569 | "SaveCurrentImage" = "保存当前图片"; 570 | "ShowCurrentImage" = "显示当前图片"; 571 | "CopyCurrentImage" = "复制当前图片"; 572 | "SavePostAsImage" = "帖子另存为图片"; 573 | "CopyPostAsImage" = "帖子作为图片复制"; 574 | "CopyCommentText" = "复制评论文本"; 575 | "SaveCommentAsImage" = "评论另存为图片"; 576 | "CopyCommentAsImage" = "评论作为图片复制"; 577 | "SaveProfilePicture" = "保存个人资料图片"; 578 | "ShowProfilePicture" = "显示个人头像"; 579 | "CopyProfilePicture" = "复制个人资料图片"; 580 | "DownloadThumbnail" = "保存缩略图"; 581 | "ShowThumbnail" = "显示缩略图"; 582 | "CopyThumbnail" = "复制缩略图"; 583 | "Cancel" = "取消"; 584 | "Cancelled" = "已取消"; 585 | "Copied" = "已复制到剪贴板"; 586 | "Saved" = "已保存到照片"; 587 | "Done" = "完成"; 588 | "NothingToShowInMenu" = "此上下文菜单中没有显示任何内容"; 589 | "Error" = "错误"; 590 | "Error.Clipboard" = "错误,检查剪贴板以获取更多信息。"; 591 | "Error.PathIssue" = "错误,最终生成路径时出现问题。媒体标题有问题?"; 592 | "Error.TryLater" = "媒体正在上传,或者谷歌服务器上的进程正在处理。\n\n请稍后再试。"; 593 | "Error.NoSpace" = "设备上的存储容量不足。\n\n至少需要 %@ 的额外可用容量,可用容量: %@ 。"; 594 | "Error.Multidownloading" = "多重下载功能尚未推出。"; 595 | "Error.FailedToImport" = "无法导入偏好设置。"; 596 | "DownloadingVideo" = "视频下载中"; 597 | "DownloadingAudio" = "音频下载中"; 598 | "ParsingCaptions" = "解析字幕中"; 599 | "ParsingTranscript" = "解析字幕中"; 600 | "Converting" = "转换中"; 601 | "RetryLogin" = "解决方法已激活。\n\n请重试。"; 602 | "LoginInfo" = "成功登录Google帐户后需要重新启动应用程序。"; 603 | 604 | "OpenLink" = "打开链接"; 605 | "LinkDetected" = "检测到与 YouTube 相关的链接。想在 YouTube 中打开它吗?"; 606 | 607 | "SbWhitelist" = "白名单"; 608 | "SbAddToWhitelist" = "添加到白名单"; 609 | "Sb.Whitelisted" = "已添加到白名单"; 610 | "SbRemoveFromWhitelist" = "从白名单中删除"; 611 | "Sb.Whitelist" = "白名单频道"; 612 | "Sb.Channels" = "频道"; 613 | "Sb.ChannelsHere" = "这里显示白名单频道。"; 614 | "SortType" = "排序类型"; 615 | "Sb.Newest" = "最新优先"; 616 | "Sb.Oldest" = "最早优先"; 617 | "Sb.Alphabetical" = "按字母顺序(A-Z)"; 618 | "Sb.AlphabeticalRev" = "按字母反序(Z-A)"; 619 | 620 | "Welcome.Download" = "下载媒体"; 621 | "Welcome.DownloadDesc" = "下载您喜欢的内容,无论是视频、短视频、音频还是个人头像。复制有趣的帖子和评论或将其保存为图片。"; 622 | "Welcome.Content" = "调整界面"; 623 | "Welcome.ContentDesc" = "删除不需要的内容和界面元素。启用真正的 OLED 暗黑模式。"; 624 | "Welcome.Player" = "设置播放器操作"; 625 | "Welcome.PlayerDesc" = "自定义播放器的操作,使用手势控制自动选择质量和播放速度等。"; 626 | "Welcome.More" = "还有更多..."; 627 | "Welcome.MoreDesc" = "“YouTube Plus”包含 50 多种不同的功能选项,包括保存偏好设置和清除缓存等功能。可以在 YouTube 设置下的“YouTube Plus”选项中找到功能设置。"; 628 | "SupportMe" = "支持我"; 629 | "Continue" = "继续"; 630 | 631 | "Conflicts.Detected" = "检测到不兼容的插件"; 632 | "Conflicts.DetectedDesc" = "尽管 YouTube 看似稳定,但“YouTube Plus”的开发人员不建议在同一应用程序中拥有具有类似功能的插件,并且不能保证安全使用。\n\n如果继续使用,则表示您将承担全部风险责任,并同意不再对任何性能相关进行反馈/投诉。"; 633 | "Conflicts.SkipThisVersion" = "不显示此版本"; 634 | "Conflicts.AcceptRisks" = "我接受所有风险"; 635 | "Conflicts.CloseYT" = "关闭 YouTube"; 636 | 637 | "DonationReminder" = "您的支持能让“YouTube Plus”变得更好。\n\n您可以在“YouTube Plus”设置中选择捐赠或选择关闭这些通知。谢谢💜"; 638 | 639 | /* Old localizations (commented out for reference) 640 | "TabIsHidden" = "无法选择隐藏标签页作为启动页。"; 641 | "TabIsStartupTab" = "选定为“启动页”的标签页无法隐藏"; 642 | "PreserveSpeed" = "保持速度"; 643 | "PreserveSpeedDesc" = "手势完成后保持调整后的速度。"; 644 | "sb_poi_highlight" = "精彩片段"; 645 | "SegmentDetected" = "检测到 %@"; 646 | "SegmentSkipped" = "%@ 已被跳过"; 647 | "SkippedToSegment" = "已跳过 %@"; 648 | "SkipSegment" = "跳过"; 649 | "SkipToSegment" = "跳到重点"; 650 | "SpeedPreserved" = "速度保持"; 651 | -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Main section */ 2 | "Main" = "主要"; 3 | 4 | /* Downloading options */ 5 | "Downloading" = "下載"; 6 | "DownloadManager" = "下載管理器"; 7 | "DownloadManagerDesc" = "將播放器下方的\"下載\"按鈕更換為\"下載管理器\",該管理器允許下載影片、音訊、縮圖,和複製影片資訊"; 8 | "PostManager" = "儲存貼文資訊"; 9 | "PostManagerDesc" = "長按可以複製貼文內容或將貼文儲存為圖片"; 10 | "SaveProfilePhoto" = "儲存個人檔案照片"; 11 | "SaveProfilePhotoDesc" = "長按個人檔案照片儲存到照片App"; 12 | "CommentManager" = "儲存留言資訊"; 13 | "CommentManagerDesc" = "長按可以複製留言內容或將留言儲存為圖片"; 14 | 15 | "YtlButtonPosition" = "下載按鈕位置"; 16 | "UnderPlayer" = "播放器下方"; 17 | "Overlay" = "播放介面"; 18 | "Both" = "兩者皆有"; 19 | 20 | "PostDownloadAction" = "下載後動作"; 21 | "PostDownloadDesc" = "影片成功下載完成後,執行選定的動作"; 22 | "SaveToPhotos" = "儲存至照片App"; 23 | "Share" = "分享"; 24 | "Copy" = "複製"; 25 | "Ask" = "詢問"; 26 | "DownloadCompleted" = "下載完成"; 27 | 28 | "PreferredAudio" = "偏好音軌"; 29 | "Selected" = "已選擇"; 30 | "English" = "英文"; 31 | "SelectAudioTrack" = "選擇音軌"; 32 | "EnglishNotFound" = "找不到英文音軌"; 33 | 34 | "Audios" = "音訊"; 35 | "AudioDRC" = "平衡音量"; 36 | "AudioDRCDesc" = "若有平衡音量(動態範圍壓縮)的音訊可用,下載管理器將優先選取。"; 37 | 38 | "CaptionsAndThumbnails" = "字幕與縮圖"; 39 | "EmbedThumbnailsToVideos" = "內嵌縮圖"; 40 | "EmbedThumbnailsToVideosDesc" = "將影片的縮圖內嵌為詮釋資料縮圖"; 41 | "EmbedCapsToVideos" = "嵌入字幕"; 42 | "EmbedCapsToVideosDesc" = "將選定的字幕嵌入影片"; 43 | "EmbedAutoGenCaps" = "自動產生/翻譯字幕"; 44 | "EmbedAutoGenCapsDesc" = "將自動產生、翻譯及自動翻譯的字幕加入到字幕清單中。"; 45 | "DownloadCaptions" = "下載字幕"; 46 | "SelectCaption" = "選擇字幕"; 47 | "Translated" = "已翻譯"; 48 | "TranslatedAutoGen" = "自動翻譯"; 49 | 50 | /* Nav bar options */ 51 | "Navbar" = "頂部導覽列"; 52 | "RemoveCast" = "隱藏投放按鈕"; 53 | "RemoveCastDesc" = "從導覽列隱藏投放按鈕"; 54 | "RemoveNotifications" = "隱藏通知按鈕"; 55 | "RemoveNotificationsDesc" = "從導覽列隱藏通知按鈕"; 56 | "RemoveSearch" = "隱藏搜尋按鈕"; 57 | "RemoveSearchDesc" = "從導覽列隱藏搜尋按鈕"; 58 | "RemoveVoiceSearch" = "隱藏語音搜尋按鈕"; 59 | "RemoveVoiceSearchDesc" = "從導覽列隱藏語音搜尋按鈕"; 60 | "StickyNavbar" = "固定導覽列"; 61 | "StickyNavbarDesc" = "向下滑動時保持可見狀態"; 62 | "NoSubbar" = "隱藏子導覽列"; 63 | "NoSubbarDesc" = "隱藏導覽列下的子導覽列(全部、讓你耳目一新的影片、直播中...等)"; 64 | "NoYTLogo" = "移除YouTube圖示"; 65 | "NoYTLogoDesc" = "移除在左上方導覽列的YouTube圖示"; 66 | "PremiumYTLogo" = "YouTube Premium標誌"; 67 | "PremiumYTLogoDesc" = "左上方導覽列設定為YouTube Premium標誌"; 68 | 69 | /* Feed options */ 70 | "Feed" = "首頁動態"; 71 | "RemoveAds" = "移除廣告"; 72 | "RemoveAdsDesc" = "刪除應用程式內的廣告"; 73 | "HideShorts" = "隱藏Shorts影片"; 74 | "HideShortsDesc" = "從首頁、推薦...等,隱藏Shorts影片(不適用於觀看紀錄)"; 75 | "KeepSubsShorts" = "訂閱內容中保留Shorts"; 76 | "KeepSubsShortsDesc" = "防止從\"訂閱內容\"標籤中移除Shorts影片"; 77 | "RemoveCommunityPosts" = "移除社群貼文"; 78 | "RemoveCommunityPostsDesc" = "從首頁動態移除社群貼文"; 79 | "RemoveMixPlaylists" = "移除合輯播放清單"; 80 | "RemoveMixPlaylistsDesc" = "從首頁移除YouTube生成的合輯播放清單"; 81 | "RemoveLiveVids" = "移除直播影片"; 82 | "RemoveLiveVidsDesc" = "從首頁移除直播影片"; 83 | "RemoveHorizontalFeeds" = "移除橫向動態"; 84 | "RemoveHorizontalFeedsDesc" = "從首頁移除所有橫向動態 (新聞, 繼續觀看, 貼文合輯...等)"; 85 | "RemoveMoreTopics" = "移除\"更多主題\""; 86 | "RemoveMoreTopicsDesc" = "從首頁動態移除\"更多主題\""; 87 | "RemovePlayables" = "移除遊戲角落"; 88 | "RemovePlayablesDesc" = "從動態消息移除遊戲角落 (小遊戲) "; 89 | "FixAlbums" = "修復封面"; 90 | "FixAlbumsDesc" = "為俄羅斯使用者修復封面顯示問題"; 91 | 92 | /* Player options */ 93 | "Player" = "播放器"; 94 | "PlaybackQualityOnWiFi" = "使用 Wi-Fi 時的影片畫質"; 95 | "PlaybackQualityOnWiFiDesc" = "透過 Wi-Fi 連線時自動套用所選畫質"; 96 | "PlaybackQualityOnCellular" = "使用行動網路時的影片畫質"; 97 | "PlaybackQualityOnCellularDesc" = "透過行動網路連線時自動套用所選畫質"; 98 | 99 | "PreferredCaptions" = "偏好字幕"; 100 | "Original" = "原始"; 101 | "Custom" = "手動選擇"; 102 | "CustomAudioTrack" = "選擇音軌"; 103 | "CustomAudioTrackDesc" = "指定播放時優先使用的音軌語言(如果可用)"; 104 | "CustomCaptions" = "選擇字幕"; 105 | "CustomCaptionsDesc" = "指定播放時優先顯示的字幕語言(如果可用)"; 106 | "AutoGenCaps" = "自動產生字幕"; 107 | "AutoGenCapsDesc" = "若找不到選定的字幕,YouTube Plus會嘗試選擇原始字幕的翻譯或自動產生字幕的翻譯版本"; 108 | 109 | "Player.Interface" = "介面"; 110 | "SpeedControls" = "播放速度控制"; 111 | "SpeedControlsDesc" = "在播放介面顯示速度控制按鈕"; 112 | "MuteButton" = "靜音按鈕"; 113 | "MuteButtonDesc" = "顯示一個按鈕,可在影片上控制音量的開啟/關閉"; 114 | "LockButton" = "鎖定按鈕"; 115 | "LockButtonDesc" = "顯示一個按鈕,可快速鎖定覆蓋螢幕並切換至全螢幕模式"; 116 | "HideAutoplay" = "隱藏自動播放開關"; 117 | "HideAutoplayDesc" = "隱藏播放器中的自動播放開關"; 118 | "HideSubs" = "隱藏字幕按鈕"; 119 | "HideSubsDesc" = "隱藏播放器中的字幕按鈕"; 120 | "HidePrevNext" = "隱藏上一部和下一部按鈕"; 121 | "HidePrevNextDesc" = "隱藏播放器中上一部和下一部影片按鈕"; 122 | "ReplacePrevNext" = "取代快轉和倒轉按鈕"; 123 | "ReplacePrevNextDesc" = "將播放器中的上一部和下一部影片按鈕取代為快轉和倒轉按鈕"; 124 | "RememberLoopMode" = "記住循環播放影片"; 125 | "RememberLoopModeDesc" = "記住播放器選單中最後選擇的循環模式"; 126 | "FullscreenToTheLeft" = "向左旋轉進入全螢幕"; 127 | "FullscreenToTheLeftDesc" = "全螢幕模式會將畫面向左旋轉,而非預設的向右旋轉。"; 128 | "PortraitFullscreen" = "直向全螢幕模式"; 129 | "PortraitFullscreenDesc" = "啟用直向全螢幕模式"; 130 | "ClassicQuality" = "舊版本影片畫質"; 131 | "ClassicQualityDesc" = "恢復舊版本選擇影片畫質的方式"; 132 | "ExtraSpeedOptions" = "額外的播放速度選項"; 133 | "ExtraSpeedOptionsDesc" = "在播放速度選單添加更多選項"; 134 | "NoDarkBg" = "移除深色背景"; 135 | "NoDarkBgDesc" = "移除播放器中的深色背景"; 136 | "NoEndScreenCards" = "隱藏片尾懸停影片"; 137 | "NoEndScreenCardsDesc" = "隱藏當影片結束時的懸停影片(縮圖)"; 138 | "NoAutonavEndScreenCards" = "隱藏自動播放結束畫面"; 139 | "NoAutonavEndScreenCardsDesc" = "隱藏播放結束後顯示您可以接著播放什麼的畫面。停用此選項也會停用自動播放"; 140 | "NoFullscreenActions" = "停用全螢幕操作"; 141 | "NoFullscreenActionsDesc" = "在全螢幕模式下停用操作面板"; 142 | "PersistentProgressBar" = "固定進度列"; 143 | "PersistentProgressBarDesc" = "總是在播放器中顯示進度列"; 144 | "RedProgressBar" = "紅色進度列"; 145 | "RedProgressBarDesc" = "恢復紅色的進度列"; 146 | "StockVolumeHUD" = "原生系統音量HUD"; 147 | "StockVolumeHUDDesc" = "全螢幕模式中顯示原生系統音量HUD"; 148 | "NoRelatedVids" = "隱藏相關影片"; 149 | "NoRelatedVidsDesc" = "移除全螢幕模式向上滑動時所出現的相關影片"; 150 | "NoPromotionCards" = "隱藏付費推廣"; 151 | "NoPromotionCardsDesc" = "在付費推廣的影片中隱藏「付費推廣」"; 152 | "NoWatermarks" = "隱藏浮水印"; 153 | "NoWatermarksDesc" = "在播放器中隱藏頻道浮水印"; 154 | "DisableAmbientMode" = "停用微光效果"; 155 | "DisableAmbientModeDesc" = "停用播放器和下方區域的微光效果"; 156 | "VideoEndTime" = "顯示播放結束時間"; 157 | "VideoEndTimeDesc" = "新增影片播放結束時間至播放器欄"; 158 | "24hrFormat" = "24小時制"; 159 | "24hrFormatDesc" = "播放結束時間將以24小時制顯示"; 160 | "NoRelatedWatchNexts" = "隱藏播放器下的所有影片"; 161 | "NoRelatedWatchNextsDesc" = "只留下影片資訊和留言區域"; 162 | "RemoveInlineComment" = "移除留言"; 163 | "RemoveInlineCommentDesc" = "移除播放器下方的留言區塊"; 164 | "NoSubUnderPlayer" = "移除「訂閱」按鈕"; 165 | "NoSubUnderPlayerDesc" = "移除播放器下方的「訂閱」按鈕"; 166 | "PlayerNoShare" = "移除「分享」按鈕"; 167 | "PlayerNoShareDesc" = "移除播放器下方的「分享」按鈕"; 168 | "PlayerNoThanks" = "移除「超級感謝」按鈕"; 169 | "PlayerNoThanksDesc" = "移除播放器下方的「超級感謝」按鈕"; 170 | "PlayerNoRemix" = "移除「Remix」按鈕"; 171 | "PlayerNoRemixDesc" = "移除播放器下方的「Remix」按鈕"; 172 | "PlayerNoDownload" = "移除「下載」按鈕"; 173 | "PlayerNoDownloadDesc" = "移除播放器下方的「下載」按鈕"; 174 | "PlayerNoClip" = "移除「剪輯片段」按鈕"; 175 | "PlayerNoClipDesc" = "移除播放器下方的「剪輯片段」按鈕"; 176 | "PlayerNoSave" = "移除「儲存」按鈕"; 177 | "PlayerNoSaveDesc" = "移除播放器下方的「儲存」按鈕"; 178 | "PlayerNoReport" = "移除「檢舉」按鈕"; 179 | "PlayerNoReportDesc" = "移除播放器下方的「檢舉」按鈕"; 180 | 181 | "ProgressBarStyle" = "進度列樣式"; 182 | "SolidColor" = "純色"; 183 | "Gradient" = "漸層"; 184 | "MainColor" = "主色"; 185 | "GradientColor" = "漸層顏色"; 186 | "ScrubberColor" = "拖曳點顏色"; 187 | 188 | "Player.Actions" = "操作"; 189 | "DefaultPlaybackRate" = "預設播放速度"; 190 | "DefaultPlaybackRateDesc" = "修改預設播放速度"; 191 | "BackgroundPlayback" = "背景播放"; 192 | "BackgroundPlaybackDesc" = "啟用背景播放"; 193 | "Miniplayer" = "啟用迷你播放器"; 194 | "MiniplayerDesc" = "對於原本不支援迷你播放器的影片(例如針對兒童的影片),啟用迷你播放器"; 195 | "DisableAutoplay" = "停用自動播放"; 196 | "DisableAutoplayDesc" = "在打開應用程式後防止自動播放影片"; 197 | "DisableAutoCaptions" = "停用自動字幕"; 198 | "DisableAutoCaptionsDesc" = "防止字幕自動啟用"; 199 | "NoContentWarning" = "略過內容警告"; 200 | "NoContentWarningDesc" = "略過敏感內容警告訊息"; 201 | "NoHints" = "停用提示"; 202 | "NoHintsDesc" = "在播放過程中出現在右上角的作者提示"; 203 | "AutoFullscreen" = "全螢幕模式"; 204 | "AutoFullscreenDesc" = "自動以全螢幕模式播放影片"; 205 | "ExitFullscreen" = "結束時退出全螢幕模式"; 206 | "ExitFullscreenDesc" = "影片播放結束時退出全螢幕模式"; 207 | 208 | "Player.Gestures" = "手勢"; 209 | "CompactToast" = "簡潔提示"; 210 | "CompactToastDesc" = "為播放器操作顯示簡潔風格的提示"; 211 | "LeftSideGesture" = "左邊手勢"; 212 | "LeftSideGestureDesc" = "透過在螢幕左邊垂直滑動來調整選擇的設定"; 213 | "RightSideGesture" = "右邊手勢"; 214 | "RightSideGestureDesc" = "透過在螢幕右邊垂直滑動來調整選擇的設定"; 215 | "ActivationAreaWidth" = "手勢啟動寬度"; 216 | "ActivationAreaWidthDesc" = "此值決定螢幕左右兩側的手勢識別區域(單位:像素)\n\n最大值允許為螢幕寬度的三分之一\n\n調整此設定有助於防止在嘗試最小化或展開播放器時意外啟動"; 217 | "HoldToSpeed" = "按住加速"; 218 | "HoldToSpeedDesc" = "設定長按播放器時觸發的播放速度"; 219 | "AdjustWithFinger" = "調整速度"; 220 | "AdjustWithFingerDesc" = "透過在播放器上長按並上下滑動手指來調整播放速度"; 221 | "PreserveSpeed" = "鎖定速度"; 222 | "PreserveSpeedDesc" = "在手勢完成後鎖定調整後的速度"; 223 | "SeekAnywhere" = "滑動快轉/倒轉"; 224 | "SeekAnywhereDesc" = "允許透過左右滑動來控制播放進度"; 225 | "SeekMethod" = "快轉/倒轉方式"; 226 | "SeekMethodDesc" = "獨立:可以在整部影片內自由快速滑動(取決於快轉/倒轉靈敏度)\n\n基於影片長度:滑動進度取決於影片時間長度和快轉/倒轉靈敏度。這對於長時間影片很有幫助,可以防止滑動時跳過大部分的影片內容。"; 227 | "Independent" = "獨立"; 228 | "DurationBased" = "基於影片長度"; 229 | "SeekSensitivity" = "快轉/倒轉靈敏度"; 230 | "TwoFingerTapToPause" = "使用兩指暫停"; 231 | "TwoFingerTapToPauseDesc" = "兩指點擊螢幕即可\"暫停/恢復\"播放"; 232 | "TwoFingerPanToBrightness" = "調整亮度"; 233 | "TwoFingerPanToBrightnessDesc" = "使用兩指向上或向下滑動來調整螢幕亮度"; 234 | "CopyWithTimestamp" = "複製時間標記連結"; 235 | "CopyWithTimestampDesc" = "透過按下暫停按鈕,將帶有時間標記的連結複製到剪貼簿"; 236 | "PauseOnOverlay" = "覆蓋時暫停"; 237 | "PauseOnOverlayDesc" = "當覆蓋畫面出現時,暫停播放"; 238 | "DontSnap2Chapter" = "停用跳轉到章節"; 239 | "DontSnap2ChapterDesc" = "停用點兩下手勢跳轉到下一集"; 240 | "NoTwoFingerSnapToChapter" = "停用兩指點兩下"; 241 | "NoTwoFingerSnapToChapterDesc" = "停用兩指點兩下跳轉到章節的手勢"; 242 | "NoFreeZoom" = "停用自由縮放手勢"; 243 | "NoFreeZoomDesc" = "停用新的自由缩放手势"; 244 | "NoDoubleTap2Seek" = "停用點兩下快轉功能"; 245 | "NoDoubleTap2SeekDesc" = "停用點兩下手勢進行快轉"; 246 | 247 | /* Shorts options */ 248 | "Shorts" = "Shorts"; 249 | "PlaybackMode" = "播放結束後的動作"; 250 | "Loop" = "循環播放"; 251 | "ScrollToNext" = "播放下一部"; 252 | "Stop" = "停止"; 253 | "AutoSkipShorts" = "連續播放Shorts"; 254 | "ShortsOnlyMode" = "只看Shorts模式"; 255 | "ShortsOnlyModeDesc" = "限制YouTube功能只能觀看Shorts影片"; 256 | "RestrictShorts" = "限制Shorts數量"; 257 | "RestrictShortsDesc" = "將動態中Shorts數量限制在10-15部。可以避免養成無止境瀏覽的習慣"; 258 | "ShortsProgress" = "啟用時間進度列"; 259 | "ShortsProgressDesc" = "在Shorts底部顯示進度列"; 260 | "SpeedByLongTap" = "加快Shorts播放速度"; 261 | "SpeedByLongTapDesc" = "允許透過長按螢幕的某個部分位置來加快播放速度"; 262 | "SpeedLocation" = "觸發位置"; 263 | "PinchToFullscreenShorts" = "捏合切換全螢幕"; 264 | "PinchToFullscreenShortsDesc" = "透過兩指縮放手勢,控制覆蓋層的顯示,讓Shorts以全螢幕模式播放"; 265 | "ShortsToRegular" = "Shorts轉為一般影片"; 266 | "ShortsToRegularDesc" = "將Shorts作為一般影片開啟"; 267 | "RemoveShortsLive" = "移除直播影片"; 268 | "RemoveShortsLiveDesc" = "從首頁動態移除直播影片"; 269 | 270 | "ShortsInterface" = "介面"; 271 | "HideShortsLogo" = "隱藏Shorts圖示"; 272 | "HideShortsLogoDesc" = "左上角Shorts圖示"; 273 | "HideShortsSearch" = "隱藏搜尋按鈕"; 274 | "HideShortsSearchDesc" = "從Shorts中隱藏搜尋按鈕"; 275 | "HideShortsCamera" = "隱藏相機按鈕"; 276 | "HideShortsCameraDesc" = "從Shorts中隱藏相機按鈕"; 277 | "HideShortsMore" = "隱藏更多 (⋮) 按鈕"; 278 | "HideShortsMoreDesc" = "從Shorts中隱藏更多 (⋮) 按鈕,也可以透過長按螢幕來完成"; 279 | 280 | "HideCarouselSub" = "隱藏訂閱"; 281 | "HideCarouselSubDesc" = "移除暫停狀態下出現的訂閱按鈕"; 282 | "HideCarouselLive" = "隱藏直播"; 283 | "HideCarouselLiveDesc" = "移除暫停狀態下出現的直播按鈕"; 284 | "HideCarouselTrends" = "隱藏熱門趨勢"; 285 | "HideCarouselTrendsDesc" = "移除暫停狀態下出現的熱門趨勢按鈕"; 286 | "HideCarouselShop" = "隱藏購物"; 287 | "HideCarouselShopDesc" = "移除暫停狀態下出現的購物按鈕"; 288 | 289 | "HideShortsLike" = "隱藏讚按鈕"; 290 | "HideShortsLikeDesc" = "移除動作列上的讚按鈕"; 291 | "HideShortsDislike" = "隱藏不喜歡按鈕"; 292 | "HideShortsDislikeDesc" = "移除動作列上的不喜歡按鈕"; 293 | "HideShortsComments" = "隱藏留言按鈕"; 294 | "HideShortsCommentsDesc" = "移除動作列上的留言按鈕"; 295 | "HideShortsShare" = "隱藏分享按鈕"; 296 | "HideShortsShareDesc" = "移除動作列上的分享按鈕"; 297 | "HideShortsRemix" = "隱藏Remix按鈕"; 298 | "HideShortsRemixDesc" = "移除動作列上的Remix按鈕"; 299 | "HideShortsSuggestion" = "隱藏建議"; 300 | "HideShortsSuggestionDesc" = "移除建議按鈕,例如新增至播放清單、超級感謝...等"; 301 | "HideShortsSubscribe" = "隱藏訂閱按鈕"; 302 | "HideShortsSubscribeDesc" = "移除使用者名稱旁邊的訂閱按鈕"; 303 | "HideShortsUsername" = "隱藏使用者名稱"; 304 | "HideShortsUsernameDesc" = "移除頻道名稱"; 305 | "HideShortsDescription" = "隱藏描述"; 306 | "HideShortsDescriptionDesc" = "移除Shorts描述"; 307 | "HideShortsSource" = "隱藏來源連結按鈕"; 308 | "HideShortsSourceDesc" = "移除前往至完整影片或另一部Shorts的按鈕"; 309 | "HideShortsAudio" = "隱藏音訊指示器"; 310 | "HideShortsAudioDesc" = "移除Short中顯示所使用的音訊行"; 311 | 312 | /* Tab bar options */ 313 | "Tabbar" = "底部標籤欄"; 314 | "Startup" = "啟動頁面"; 315 | "FEwhat_to_watch" = "首頁"; 316 | "FEexplore" = "探索"; 317 | "FEshorts" = "Shorts"; 318 | "FEsubscriptions" = "訂閱內容"; 319 | "FElibrary" = "個人中心/媒體庫"; 320 | "FEuploads" = "建立"; 321 | "FEhistory" = "觀看紀錄"; 322 | "FEpost_home" = "貼文"; 323 | "VLWL" = "稍後觀看"; 324 | 325 | "TranslucentBar" = "半透明標籤欄"; 326 | "RemoveLabels" = "移除文字"; 327 | "RemoveIndicators" = "刪除標記"; 328 | 329 | "ActiveTabs" = "顯示標籤頁"; 330 | "InactiveTabs" = "隱藏標籤頁"; 331 | "HideLibraryFooter" = "長按首頁標籤可以顯示或隱藏\"個人中心\""; 332 | "Warning" = "警告"; 333 | "AtLeastOneTab" = "必須至少保持一個標籤頁為啟用狀態"; 334 | "TabsCountRestricted" = "最多只能設定顯示六個標籤頁"; 335 | 336 | /* Interface options */ 337 | "Interface" = "介面"; 338 | "OledTheme" = "OLED主題"; 339 | "OledThemeDesc" = "將所有深色改為黑色"; 340 | "OledKeyboard" = "OLED鍵盤"; 341 | "OledKeyboardDesc" = "為深色鍵盤套用OLED黑色主題"; 342 | "NoSearchHistory" = "隱藏搜尋記錄"; 343 | "NoSearchHistoryDesc" = "視覺上隱藏搜尋歷史紀錄和建議。注意:您的搜尋紀錄仍然可在其它YouTube客戶端中存取"; 344 | "StickSortComments" = "固定留言排序"; 345 | "StickSortCommentsDesc" = "將留言排序(熱門、最新)功能固定,這樣在滾動時就不會消失"; 346 | "HideSortComments" = "隱藏留言排序"; 347 | "HideSortCommentsDesc" = "隱藏留言排序(熱門、最新)功能,將永不顯示"; 348 | "PlaylistOldMinibar" = "舊版播放清單"; 349 | "PlaylistOldMinibarDesc" = "將新版的浮動播放清單面板替換為舊版"; 350 | "OldYTUI" = "舊版介面"; 351 | "OldYTUIDesc" = "偽裝YouTube版本,讓介面變回舊版"; 352 | "DisableRTL" = "停用RTL格式"; 353 | "DisableRTLDesc" = "強制將初始顯示從右到左(RTL)格式的語言,改為從左到右(LTR)顯示"; 354 | 355 | "StartupAnimation" = "啟動動畫"; 356 | "StartupAnimationDesc" = "顯示YouTube開啟時的載入動畫"; 357 | 358 | "InterfaceStyle" = "介面風格"; 359 | 360 | "MiniplayerStyle" = "迷你播放器風格"; 361 | "MiniplayerStyleDesc" = "切換到/離開浮動模式,需要重新啟動應用程式。"; 362 | "Floating" = "浮動"; 363 | 364 | "Other" = "Other"; 365 | "NoShareChunk" = "移除分享識別碼"; 366 | "NoShareChunkDesc" = "從分享連結中移除\"si=identifier\"參數。這是一個替代「原生分享選單」的好選擇,因為YouTube不斷改善其分享選單。"; 367 | "AutoCheckLinks" = "自動檢查剪貼簿"; 368 | "AutoCheckLinksDesc" = "每次開啟應用程式時,檢查剪貼簿中的 YouTube 相關連結。\n為確保正常運作,請前往 iOS 設定 → YouTube → 從其他App貼上,並選擇「允許」"; 369 | 370 | "ContextMenu" = "上下文選單"; 371 | "NativeShare" = "原生分享選單"; 372 | "NativeShareDesc" = "使用系統分享選單分享媒體"; 373 | "RemoveCommentGuidelines" = "移除社群規範"; 374 | "RemoveCommentGuidelinesDesc" = "移除留言區置頂的社群規範"; 375 | "RemovePlayNext" = "移除\"加入待播清單接著播放\""; 376 | "RemovePlayNextDesc" = "從選單移除\"加入待播清單接著播放\""; 377 | "RemoveDownloadMenu" = "移除\"下載影片\""; 378 | "RemoveDownloadMenuDesc" = "從選單移除\"下載影片\"選項"; 379 | "RemoveWatchLaterMenu" = "移除\"儲存至「稍後觀看」清單\""; 380 | "RemoveWatchLaterMenuDesc" = "從選單移除\"儲存至「稍後觀看」清單\"選項"; 381 | "RemoveSaveToPlaylistMenu" = "移除\"儲存至播放清單\""; 382 | "RemoveSaveToPlaylistMenuDesc" = "從選單移除\"儲存至播放清單\"選項"; 383 | "RemoveShareMenu" = "移除\"分享\""; 384 | "RemoveShareMenuDesc" = "從選單移除\"分享\"選項"; 385 | "RemoveNotInterestedMenu" = "移除\"不感興趣\""; 386 | "RemoveNotInterestedMenuDesc" = "從選單移除\"不感興趣\"選項"; 387 | "RemoveDontRecommendMenu" = "移除\"不要推薦這個頻道\""; 388 | "RemoveDontRecommendMenuDesc" = "從選單移除\"不要推薦這個頻道\"選項"; 389 | "RemoveFeedbackMenu" = "移除\"提供意見\""; 390 | "RemoveFeedbackMenuDesc" = "從選單移除\"提供意見\"選項"; 391 | "RemoveReportMenu" = "移除\"檢舉\""; 392 | "RemoveReportMenuDesc" = "從選單移除\"檢舉\"選項"; 393 | "RemoveRemixMenu" = "移除\"Remix\""; 394 | "RemoveRemixMenuDesc" = "從選單移除\"Remix\"選項"; 395 | "RemoveYTMMenu" = "移除\"YouTube Music\""; 396 | "RemoveYTMMenuDesc" = "從選單移除\"用 YouTube Music 聽音樂\"選項"; 397 | 398 | /* SponsorBlock settings */ 399 | "EnableSponsorBlock" = "啟用"; 400 | "EnableSponsorBlockDesc" = "SponsorBlock擴充功能"; 401 | "SbPlayerButton" = "顯示按鈕"; 402 | "SbPlayerButtonDesc" = "在播放器中新增 SponsorBlock 按鈕"; 403 | "ShowNotifications" = "顯示通知"; 404 | "ShowNotificationsDesc" = "顯示自動跳過片段的通知。需要手動跳過的類別通知會始終顯示。"; 405 | "SegmentsInFeedPlayer" = "播放器中顯示片段"; 406 | "SegmentsInFeedPlayerDesc" = "在播放器的進度列上顯示彩色片段標記"; 407 | "SegmentsInMiniPlayer" = "迷你播放器中顯示片段"; 408 | "SegmentsInMiniPlayerDesc" = "在迷你播放器的進度列上顯示彩色片段標記"; 409 | "SegmentSkipAudio" = "音訊通知"; 410 | "SegmentSkipAudioDesc" = "跳過片段時播放聲音提示"; 411 | "DurationWithoutSegments" = "顯示新的影片時間"; 412 | "DurationWithoutSegmentsDesc" = "去除片段後的總時間"; 413 | 414 | "SkipAlertDuration" = "跳過通知持續時間"; 415 | "UnskipAlertDuration" = "取消跳過通知持續時間"; 416 | 417 | "Segments" = "片段"; 418 | "Sponsor" = "贊助廣告"; 419 | "SponsorDesc" = "有收錢的工商廣告和直接廣告。不是為了自我推銷或為了其它創作的免費推銷"; 420 | "SponsorColor" = "贊助片段顏色"; 421 | "Intro" = "開頭動畫/中場休息"; 422 | "IntroDesc" = "通常出現在影片開頭的片段,包括動畫、靜態畫面或剪輯,這些片段也會出現在同一創作者的其它影片中"; 423 | "IntroColor" = "開頭動畫/中場休息片段顏色"; 424 | "Endcards" = "結束畫面/鳴謝"; 425 | "EndcardsDesc" = "通常出現在結束畫面或接近結尾的片段,會顯示YouTube結尾資訊卡或鳴謝名單"; 426 | "EndcardsColor" = "結束畫面/鳴謝片段顏色"; 427 | "Interaction" = "互動提醒"; 428 | "InteractionDesc" = "要求觀眾按讚、訂閱或在任何付費&免費平台上與創作者互動(例:點擊影片)"; 429 | "InteractionColor" = "互動提醒片段顏色"; 430 | "SelfPromo" = "自我推廣/無償推廣"; 431 | "SelfPromoDesc" = "自我推廣:創作者推廣自己的產品或服務\n無償推廣:創作者不會因為這個宣傳而得到金錢報酬"; 432 | "SelfPromoColor" = "自我推廣/無償推廣片段顏色"; 433 | "MusicOfftopic" = "音樂:非音樂片段"; 434 | "MusicOfftopicDesc" = "僅適用於以音樂為主要內容的影片"; 435 | "MusicOfftopicColor" = "非音樂片段顏色"; 436 | "Preview" = "預告"; 437 | "PreviewDesc" = "展示即將播放的影片或整系列內容的短片集錦,所有內容都會在後面影片中重複"; 438 | "PreviewColor" = "預告片段顏色"; 439 | "Highlight" = "重點"; 440 | "HighlightDesc" = "用於快速跳轉到影片重點或精華部分"; 441 | "HighlightColor" = "重點片段顏色"; 442 | "Jokes" = "離題閒聊/玩笑"; 443 | "JokesDesc" = "離題閒聊/玩笑僅用於為影片增添趣味或幽默的附加場景,對理解影片的主要內容並非必要。."; 444 | "JokesColor" = "離題閒聊/玩笑片段顏色"; 445 | 446 | "Sb.Disable" = "停用"; 447 | "Sb.Skip" = "自動跳過"; 448 | "Sb.SkipTo" = "跳到片段"; 449 | "Sb.Ask" = "詢問"; 450 | "Sb.Display" = "在播放器中顯示"; 451 | 452 | "PublicUserID" = "公開使用者 ID"; 453 | "PrivateUserID" = "私人使用者 ID"; 454 | "TapToReveal" = "點擊顯示"; 455 | "Save" = "儲存"; 456 | "Error.SbPublicID" = "公開使用者 ID 必須正好包含 64 個字元"; 457 | "Error.SbPrivateID" = "私人(本機)使用者 ID 必須至少包含 32 個字元"; 458 | 459 | "sb_sponsor" = "贊助片段"; 460 | "sb_intro" = "開場片段"; 461 | "sb_outro" = "片尾片段"; 462 | "sb_interaction" = "互動片段"; 463 | "sb_selfpromo" = "自我推廣片段"; 464 | "sb_music_offtopic" = "非音樂片段"; 465 | "sb_preview" = "預覽片段"; 466 | "sb_poi_highlight" = "精彩片段"; 467 | "sb_filler" = "填充片段"; 468 | 469 | "SegmentDetected" = "%@ 偵測到\n%@"; 470 | "SegmentSkipped" = "%@ 已被跳過"; 471 | "SkippedToSegment" = "已跳到 %@"; 472 | "SkipSegment" = "您想跳過這個片段嗎?"; 473 | "SkipToSegment" = "您想跳轉到精彩片段嗎?"; 474 | "Unskip" = "取消跳過"; 475 | 476 | /* Developer section */ 477 | "Developer" = "開發者"; 478 | "FollowMe" = "在X上跟隨我"; 479 | "SupportDevelopment" = "支持開發"; 480 | "DonateDesc" = "您的支持對我來說意義非凡"; 481 | "SupportDevelopmentDesc" = "如果您喜歡YTPlus並且願意支持開發,可以使用以下任何方便的方式支持。\n感謝❤"; 482 | "VisitGithub" = "Github儲存庫"; 483 | "VisitGithubDesc" = "為儲存庫標記星號,提出功能請求或回報問題。"; 484 | "VisitTelegram" = "我的Telegram頻道"; 485 | "VisitTelegramDesc" = "隨時掌握App的最新更新資訊"; 486 | 487 | /* Credits section */ 488 | "Credits" = "貢獻"; 489 | 490 | "Contributors" = "貢獻者"; 491 | "DevContribution" = "對開發的貢獻"; 492 | "SpecialThanks" = "特別感謝"; 493 | "SpecialThanks.Test" = "對插件測試付出了不可或缺的貢獻"; 494 | 495 | "Localizations" = "在地化譯者"; 496 | "ChineseSimplified" = "簡體中文在地化"; 497 | "ChineseTraditional" = "繁體中文在地化"; 498 | "French" = "法語在地化"; 499 | "Spanish" = "西班牙語在地化"; 500 | "Japanese" = "日語在地化"; 501 | "Vietnamese" = "越南語在地化"; 502 | "Arabic" = "阿拉伯語在地化"; 503 | "Turkish" = "土耳其語在地化"; 504 | "Italian" = "義大利語在地化"; 505 | "Korean" = "韓語在地化"; 506 | "Polish" = "波蘭語在地化"; 507 | 508 | "OpenSourceLibs" = "開源函式庫"; 509 | "SupporterWall" = "支持者"; 510 | 511 | "Preferences" = "%@ 偏好設定"; 512 | "ManagePreferences" = "偏好設定管理"; 513 | "ImportPreferences" = "匯入偏好設定"; 514 | "PreImportMessage" = "此項操作會將目前的偏好設定,替換為所選檔案中的偏好設定。\n\n確定要繼續嗎?"; 515 | "ExportPreferences" = "匯出偏好設定"; 516 | "ResetSettings" = "重置YTPlus設定"; 517 | "ResetMessage" = "這個選項會將YTPlus重置為預設值,並關閉Youtube\n\n您確定要繼續嗎?"; 518 | 519 | "ManageCache" = "快取管理"; 520 | "ClearCacheAtStart" = "啟動時清除快取"; 521 | "ClearCacheAtStartDesc" = "開啟Youtube時,自動清除快取"; 522 | "ClearCache" = "清除快取"; 523 | 524 | "NoDonationReminder" = "停用捐款提醒"; 525 | "NoDonationReminderDesc" = "關閉偶爾顯示的捐款提醒"; 526 | 527 | "ShortsOnlyWarning" = "您確定要開啟此模式嗎?\n\n在此模式下,您只能觀看Shorts影片,無法進行其它操作。\n\n您可以在Shorts播放器中使用兩指長按來停用只看Shorts模式。"; 528 | "ShortsModeTurnedOff" = "已關閉「只看Shorts模式」"; 529 | 530 | "AddLibraryTab" = "恢復\"個人中心\"標籤"; 531 | "RemoveLibraryTab" = "移除\"個人中心\"標籤"; 532 | "LibraryAdded" = "\"個人中心\"標籤已恢復"; 533 | "LibraryRemoved" = "\"個人中心\"標籤已移除"; 534 | 535 | "Yes" = "是"; 536 | "No" = "否"; 537 | 538 | "Select" = "選擇"; 539 | "Default" = "預設"; 540 | "Best" = "最佳"; 541 | "Show" = "顯示"; 542 | "Disable" = "停用"; 543 | "Disabled" = "已停用"; 544 | "PlaybackSpeed" = "播放速度"; 545 | "SpeedPreserved" = "速度鎖定在 %@"; 546 | "ResetSpeed" = "重置播放速度"; 547 | 548 | "Toast.Brightness" = "亮度"; 549 | "Toast.PlaybackSpeed" = "播放速度"; 550 | "Toast.Volume" = "音量"; 551 | 552 | "SelectAction" = "選擇動作"; 553 | "DownloadVideo" = "下載影片"; 554 | "DownloadAudio" = "下載音訊"; 555 | "SaveImage" = "儲存圖片"; 556 | "CopyInformation" = "複製資訊"; 557 | "CopyChannelName" = "複製頻道名稱"; 558 | "CopyTitle" = "複製標題"; 559 | "CopyDescription" = "複製說明"; 560 | "CopyTimestampedLink" = "複製含有時間標記的連結"; 561 | "CopyTranscript" = "複製字幕"; 562 | "PlayInExternalPlayer" = "在外部播放器中播放"; 563 | "PlayInSystemPlayer" = "在系統播放器中播放"; 564 | "PlayInInfuse" = "在Infuse中播放"; 565 | "PlayInVLC" = "在VLC中播放"; 566 | "PlayerNotFound" = "找不到播放器"; 567 | "OpenAsRegularVideo" = "像一般影片一樣打開"; 568 | "CopyPostText" = "複製貼文內容"; 569 | "SaveCurrentImage" = "儲存當前圖片"; 570 | "ShowCurrentImage" = "顯示當前圖片"; 571 | "CopyCurrentImage" = "複製當前圖片"; 572 | "SavePostAsImage" = "儲存貼文為圖片"; 573 | "CopyPostAsImage" = "複製貼文為圖片"; 574 | "CopyCommentText" = "複製留言內容"; 575 | "SaveCommentAsImage" = "留言儲存為圖片"; 576 | "CopyCommentAsImage" = "複製留言為圖片"; 577 | "SaveProfilePicture" = "儲存個人檔案照片"; 578 | "ShowProfilePicture" = "顯示個人檔案照片"; 579 | "CopyProfilePicture" = "複製個人檔案照片"; 580 | "DownloadThumbnail" = "儲存影片縮圖"; 581 | "ShowThumbnail" = "顯示影片縮圖"; 582 | "CopyThumbnail" = "複製影片縮圖"; 583 | "Cancel" = "取消"; 584 | "Cancelled" = "已取消"; 585 | "Copied" = "已複製到剪貼簿"; 586 | "Saved" = "已儲存到照片App"; 587 | "Done" = "完成"; 588 | "NothingToShowInMenu" = "這個上下文選單中沒有可顯示的內容"; 589 | "Error" = "發生錯誤"; 590 | "Error.Clipboard" = "錯誤!!檢查剪貼簿獲取更多資訊"; 591 | "Error.PathIssue" = "錯誤!!產生最終路徑時出現問題。媒體標題有問題?"; 592 | "Error.TryLater" = "媒體正在直播或正在Google伺服器上處理中。\n\n請稍後再試"; 593 | "Error.NoSpace" = "裝置儲存空間不足。\n\n至少需要 %@ 的額外可用空間。目前可用空間: %@"; 594 | "Error.Multidownloading" = "暫時不支援批次下載"; 595 | "Error.FailedToImport" = "偏好設定匯入失敗"; 596 | "DownloadingVideo" = "影片下載中..."; 597 | "DownloadingAudio" = "音訊下載中..."; 598 | "ParsingCaptions" = "解析字幕中..."; 599 | "ParsingTranscript" = "解析逐字稿中..."; 600 | "Converting" = "轉檔中..."; 601 | "RetryLogin" = "已啟用登入權限修復\n\n請再次登入"; 602 | "LoginInfo" = "成功登錄Google帳戶後需要重新啟動應用程式"; 603 | 604 | "OpenLink" = "開啟連結"; 605 | "LinkDetected" = "偵測到 YouTube 相關連結。是否要在 YouTube 中開啟?"; 606 | 607 | "SbWhitelist" = "白名單"; 608 | "SbAddToWhitelist" = "新增至白名單"; 609 | "Sb.Whitelisted" = "已新增至白名單"; 610 | "SbRemoveFromWhitelist" = "從白名單中移除"; 611 | "Sb.Whitelist" = "白名單頻道"; 612 | "Sb.Channels" = "頻道"; 613 | "Sb.ChannelsHere" = "白名單頻道將在此顯示"; 614 | "SortType" = "排序方式"; 615 | "Sb.Newest" = "最新優先"; 616 | "Sb.Oldest" = "最舊優先"; 617 | "Sb.Alphabetical" = "依字母順序 (A-Z)"; 618 | "Sb.AlphabeticalRev" = "依字母倒序 (Z-A)"; 619 | 620 | "Welcome.Download" = "下載媒體"; 621 | "Welcome.DownloadDesc" = "下載您喜愛的內容,不論是影片、Shorts、音訊或個人檔案照片。複製有趣的貼文和留言,或將它們儲存為圖片。"; 622 | "Welcome.Content" = "介面調整"; 623 | "Welcome.ContentDesc" = "移除不必要內容和介面元素。啟用真正的OLED深色模式。"; 624 | "Welcome.Player" = "設定播放器"; 625 | "Welcome.PlayerDesc" = "自訂播放器操作,自動選擇畫質和播放速度,使用手勢進行控制。"; 626 | "Welcome.More" = "還有更多..."; 627 | "Welcome.MoreDesc" = "YouTube Plus包含超過50種不同的選項,包括儲存偏好設定和清除快取...等功能。這些功能在YouTube設定下的\"YouTube Plus\""; 628 | "SupportMe" = "支持我"; 629 | "Continue" = "繼續"; 630 | 631 | "Conflicts.Detected" = "偵測到不相容的插件"; 632 | "Conflicts.DetectedDesc" = "儘管應用程式看似穩定,YouTube Plus開發者不建議將功能類似的插件合併在同一個應用程式中,並且無法保證安全使用。\n\n繼續使用此應用程式,表示您將承擔全部風險責任,並同意任何有關於效能的投訴將被忽略。"; 633 | "Conflicts.SkipThisVersion" = "此版本不再顯示"; 634 | "Conflicts.AcceptRisks" = "我接受所有風險"; 635 | "Conflicts.CloseYT" = "關閉YouTube"; 636 | 637 | "DonationReminder" = "您的支持有助於讓YouTube Plus變得更好。\n\n你可以在YouTube Plus的設定裡面,選擇捐款或關閉這些通知。謝謝你💜"; 638 | 639 | /* Old localizations (commented out for reference) 640 | "TabIsHidden" = "無法將隱藏的標籤頁選為啟動頁面"; 641 | "TabIsStartupTab" = "選擇為啟動頁面的標籤,無法隱藏"; 642 | "PreserveSpeed" = "保持速度"; 643 | "PreserveSpeedDesc" = "手勢完成後保持調整後的速度"; 644 | "sb_poi_highlight" = "重點片段"; 645 | "SegmentDetected" = "偵測到 %@"; 646 | "SegmentSkipped" = "%@ 已被跳過"; 647 | "SkippedToSegment" = "跳到 %@"; 648 | "SkipSegment" = "跳過"; 649 | "SkipToSegment" = "跳到重點"; 650 | "SpeedPreserved" = "保持速度"; -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/ja.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Main section */ 2 | "Main" = "メイン"; 3 | 4 | /* Downloading options */ 5 | "Downloading" = "ダウンロード"; 6 | "DownloadManager" = "ダウンロードマネージャー"; 7 | "DownloadManagerDesc" = "プレーヤー下部の [ダウンロード] ボタンの動作をダウンロードマネージャーに置き換えます。これにより、動画、音声、サムネイル画像のダウンロードや動画情報のコピーが可能になります。"; 8 | "PostManager" = "投稿情報を保存"; 9 | "PostManagerDesc" = "長押しでコミュニティ投稿のテキストをコピーしたり、コミュニティ投稿を画像として保存したりできるようになります。"; 10 | "SaveProfilePhoto" = "プロフィール画像を保存"; 11 | "SaveProfilePhotoDesc" = "プロフィール画像を長押しで写真アプリに保存します。"; 12 | "CommentManager" = "コメント情報を保存"; 13 | "CommentManagerDesc" = "長押しでコメントをコピーしたり、コメントを画像として保存したりできるようになります。"; 14 | 15 | "YtlButtonPosition" = "ダウンロードボタンの配置"; 16 | "UnderPlayer" = "プレーヤー下部"; 17 | "Overlay" = "オーバーレイ"; 18 | "Both" = "両方"; 19 | 20 | "PostDownloadAction" = "ダウンロード後の動作"; 21 | "PostDownloadDesc" = "選択した動作は、動画のダウンロードが正常に完了すると実行されます。"; 22 | "SaveToPhotos" = "[写真] アプリに保存"; 23 | "Share" = "共有"; 24 | "Copy" = "コピー"; 25 | "Ask" = "確認"; 26 | "DownloadCompleted" = "ダウンロード完了"; 27 | 28 | "PreferredAudio" = "優先する音声トラック"; 29 | "Selected" = "選択済み"; 30 | "English" = "英語"; 31 | "SelectAudioTrack" = "音声トラックを選択"; 32 | "EnglishNotFound" = "英語の音声トラックが見つかりません"; 33 | 34 | "Audios" = "オーディオ"; 35 | "AudioDRC" = "「一定音量」を優先"; 36 | "AudioDRCDesc" = "ダウンロードマネージャーは、「一定音量」の音声 (ダイナミックレンジコンプレッション) が利用可能な場合、それを優先的に選択します。"; 37 | 38 | "CaptionsAndThumbnails" = "字幕とサムネイル"; 39 | "EmbedThumbnailsToVideos" = "サムネイルを埋め込む"; 40 | "EmbedThumbnailsToVideosDesc" = "動画のサムネイルをメタデータのサムネイルとして埋め込みます。"; 41 | "EmbedCapsToVideos" = "字幕を埋め込む"; 42 | "EmbedCapsToVideosDesc" = "選択したキャプション/字幕を動画に埋め込みます。"; 43 | "EmbedAutoGenCaps" = "自動生成の字幕"; 44 | "EmbedAutoGenCapsDesc" = "自動生成、翻訳、および自動翻訳された字幕を字幕リストに追加します。"; 45 | "DownloadCaptions" = "字幕をダウンロード"; 46 | "SelectCaption" = "キャプション/字幕を選択"; 47 | "Translated" = "翻訳済み"; 48 | "TranslatedAutoGen" = "自動翻訳"; 49 | 50 | /* Nav bar options */ 51 | "Navbar" = "ナビゲーションバー(上部のボタン類)"; 52 | "RemoveCast" = "[キャスト] ボタンを非表示"; 53 | "RemoveCastDesc" = "ナビゲーションバーから [キャスト] ボタンを非表示にします。"; 54 | "RemoveNotifications" = "[通知] ボタンを非表示"; 55 | "RemoveNotificationsDesc" = "ナビゲーションバーから [通知] ボタンを非表示にします。"; 56 | "RemoveSearch" = "[検索] ボタンを非表示"; 57 | "RemoveSearchDesc" = "ナビゲーションバーから [検索] ボタンを非表示にします。"; 58 | "RemoveVoiceSearch" = "音声検索ボタンを非表示"; 59 | "RemoveVoiceSearchDesc" = "ナビゲーションバーから音声検索のボタンを非表示にします。"; 60 | "StickyNavbar" = "ナビゲーションバーを固定"; 61 | "StickyNavbarDesc" = "スクロール中もナビゲーションバーを非表示にせず表示したままにします。"; 62 | "NoSubbar" = "サブバーを非表示"; 63 | "NoSubbarDesc" = "ナビゲーションバーの下にあるサブバー ([すべて]、[音楽]、[ニュース] など) を非表示にします。"; 64 | "NoYTLogo" = "YouTube ロゴを削除"; 65 | "NoYTLogoDesc" = "ナビゲーションバーから YouTube ロゴを非表示にします。"; 66 | "PremiumYTLogo" = "YouTube Premium ロゴに置換"; 67 | "PremiumYTLogoDesc" = "ナビゲーションバーのロゴを「YouTube Premium」に置き換えます。"; 68 | 69 | /* Feed options */ 70 | "Feed" = "フィード"; 71 | "RemoveAds" = "広告を削除"; 72 | "RemoveAdsDesc" = "アプリ内の広告を削除します。"; 73 | "HideShorts" = "ショート動画を非表示"; 74 | "HideShortsDesc" = "ホーム、おすすめなどからショート動画を非表示にします。(再生履歴には適用されません)"; 75 | "KeepSubsShorts" = "登録チャンネルにショートを表示"; 76 | "KeepSubsShortsDesc" = "[登録チャンネル] タブからショート動画を非表示にしないようにします。"; 77 | "RemoveCommunityPosts" = "コミュニティ投稿を削除"; 78 | "RemoveCommunityPostsDesc" = "フィードからコミュニティ投稿を削除します。"; 79 | "RemoveMixPlaylists" = "ミックスリストを削除"; 80 | "RemoveMixPlaylistsDesc" = "YouTubeによって生成されたミックスリストをフィードから削除します。"; 81 | "RemoveLiveVids" = "ライブ動画を削除"; 82 | "RemoveLiveVidsDesc" = "[ホーム] タブからライブ配信を削除します。"; 83 | "RemoveHorizontalFeeds" = "おすすめ欄を削除"; 84 | "RemoveHorizontalFeedsDesc" = "ホームタブからおすすめ欄(もう一度見る、もう一度聴くなど)を削除します。"; 85 | "RemoveMoreTopics" = "その他のトピックを削除"; 86 | "RemoveMoreTopicsDesc" = "フィードから「その他のトピック」を削除します。"; 87 | "RemovePlayables" = "Playablesを削除"; 88 | "RemovePlayablesDesc" = "フィードからPlayables(ミニゲーム)を削除します。"; 89 | "FixAlbums" = "カバーの修正"; 90 | "FixAlbumsDesc" = "ロシアのユーザー向けにカバーの表示を修正します。"; 91 | 92 | /* Player options */ 93 | "Player" = "プレーヤー"; 94 | "PlaybackQualityOnWiFi" = "WiFi での再生画質"; 95 | "PlaybackQualityOnWiFiDesc" = "Wi-Fi経由でストリーミングする際に選択した画質を自動的に適用します。"; 96 | "PlaybackQualityOnCellular" = "モバイルデータ通信での再生画質"; 97 | "PlaybackQualityOnCellularDesc" = "モバイルデータ通信でストリーミングする際に選択した画質を自動的に適用します。"; 98 | 99 | "PreferredCaptions" = "優先する字幕"; 100 | "Original" = "オリジナル"; 101 | "Custom" = "手動で選択"; 102 | "CustomAudioTrack" = "音声トラックを選択"; 103 | "CustomAudioTrackDesc" = "再生時に使用する優先オーディオトラック言語を指定します (利用可能な場合)。"; 104 | "CustomCaptions" = "字幕を選択"; 105 | "CustomCaptionsDesc" = "利用可能な場合は、表示する字幕の言語を指定します。"; 106 | "AutoGenCaps" = "自動生成の字幕"; 107 | "AutoGenCapsDesc" = "選択した字幕が見つからない場合、YouTube Plus はオリジナル字幕の翻訳または自動生成字幕の翻訳を選択します。"; 108 | 109 | "Player.Interface" = "インターフェース"; 110 | "SpeedControls" = "再生速度の調整"; 111 | "SpeedControlsDesc" = "プレーヤー上に再生速度のコントロールボタンを表示します。"; 112 | "MuteButton" = "ミュートボタン"; 113 | "MuteButtonDesc" = "プレーヤー上に音量をミュート/ミュート解除ボタンを表示します。"; 114 | "LockButton" = "ロックボタン"; 115 | "LockButtonDesc" = "オーバーレイ画面を即座にロックし、全画面表示に切り替えるボタンを表示します。"; 116 | "HideAutoplay" = "自動再生スイッチを非表示"; 117 | "HideAutoplayDesc" = "プレーヤー上から自動再生スイッチを非表示にします。"; 118 | "HideSubs" = "字幕ボタンを非表示"; 119 | "HideSubsDesc" = "プレーヤー上から字幕ボタンを非表示にします。"; 120 | "HidePrevNext" = "前へ/次へボタンを非表示"; 121 | "HidePrevNextDesc" = "プレーヤー上から前の動画に戻る/次の動画に進むボタンを非表示にします。"; 122 | "ReplacePrevNext" = "早送り/巻き戻しボタンに置換"; 123 | "ReplacePrevNextDesc" = "プレーヤー上の前の動画に戻る/次の動画に進むボタンを早送り/巻き戻しボタンに置き換えます。"; 124 | "RememberLoopMode" = "ループモードを記憶"; 125 | "RememberLoopModeDesc" = "プレーヤーメニューで最後に選択されたループモードを記憶します。"; 126 | "FullscreenToTheLeft" = "左向きに全画面表示"; 127 | "FullscreenToTheLeftDesc" = "全画面表示を通常の右向きではなく左向きに回転させます。"; 128 | "PortraitFullscreen" = "縦向き全画面表示"; 129 | "PortraitFullscreenDesc" = "縦向きの全画面表示を有効にします。"; 130 | "ClassicQuality" = "旧バージョンの画質選択メニューを有効化"; 131 | "ClassicQualityDesc" = "画質選択メニューを古いバージョンのものに戻します。"; 132 | "ExtraSpeedOptions" = "再生速度の追加オプション"; 133 | "ExtraSpeedOptionsDesc" = "プレーヤーメニューに追加の再生速度オプションを追加します。"; 134 | "NoDarkBg" = "暗い背景を削除"; 135 | "NoDarkBgDesc" = "オーバーレイの暗い背景を削除します。"; 136 | "NoEndScreenCards" = "終了画面のホバーカードを非表示"; 137 | "NoEndScreenCardsDesc" = "動画の終わりに表示される終了画面(おすすめ動画など)を非表示にします。"; 138 | "NoAutonavEndScreenCards" = "自動再生終了画面を非表示"; 139 | "NoAutonavEndScreenCardsDesc" = "再生終了後に表示される、次に再生する動画を非表示にします。このオプションを無効にすると自動再生も無効になります。"; 140 | "NoFullscreenActions" = "全画面表示アクションを無効化"; 141 | "NoFullscreenActionsDesc" = "全画面表示でアクションパネルを無効にします。"; 142 | "PersistentProgressBar" = "永続的なプログレスバー"; 143 | "PersistentProgressBarDesc" = "全画面表示状態でもプログレスバーを表示したままにします。"; 144 | "RedProgressBar" = "赤いプログレスバー"; 145 | "RedProgressBarDesc" = "プログレスバーの色を赤にします。"; 146 | "StockVolumeHUD" = "システムのボリューム HUD"; 147 | "StockVolumeHUDDesc" = "全画面表示状態でも iOS のデフォルトボリューム HUD を使用します。"; 148 | "NoRelatedVids" = "オーバーレイの関連動画を非表示"; 149 | "NoRelatedVidsDesc" = "上にスワイプして表示される関連動画をオーバーレイから削除します。"; 150 | "NoPromotionCards" = "有料プロモーションラベルを非表示"; 151 | "NoPromotionCardsDesc" = "プロモーションが含まれている動画から「プロモーションをみます」のラベルを非表示にします。"; 152 | "NoWatermarks" = "ウォーターマークを非表示"; 153 | "NoWatermarksDesc" = "プレーヤー上からチャンネルのウォーターマークを非表示にします。"; 154 | "DisableAmbientMode" = "アンビエントモードを無効化"; 155 | "DisableAmbientModeDesc" = "プレーヤー内およびその下部領域のアンビエントモードを無効にします。"; 156 | "VideoEndTime" = "再生終了時刻を表示"; 157 | "VideoEndTimeDesc" = "プレーヤーバーに動画の再生終了時刻を追加します。"; 158 | "24hrFormat" = "24 時間表示"; 159 | "24hrFormatDesc" = "終了時刻を 24 時間形式で表示します。"; 160 | "NoRelatedWatchNexts" = "プレーヤー下のすべての動画を非表示"; 161 | "NoRelatedWatchNextsDesc" = "プレーヤー下に表示されるすべての動画を非表示にし、動画情報とコメント欄のみを表示します。"; 162 | "RemoveInlineComment" = "インラインコメントを削除"; 163 | "RemoveInlineCommentDesc" = "プレーヤー下のコメント欄を削除します。"; 164 | "NoSubUnderPlayer" = "[チャンネル登録] ボタンを削除"; 165 | "NoSubUnderPlayerDesc" = "プレーヤー下にある [チャンネル登録] ボタンを削除します。"; 166 | "PlayerNoShare" = "共有ボタンを削除"; 167 | "PlayerNoShareDesc" = "プレーヤー下にある [共有] ボタンを削除します。"; 168 | "PlayerNoThanks" = "Thanks ボタンを削除"; 169 | "PlayerNoThanksDesc" = "プレーヤー下にある [Thanks] ボタンを削除します。"; 170 | "PlayerNoRemix" = "リミックスボタンを削除"; 171 | "PlayerNoRemixDesc" = "プレーヤー下にある [リミックス] ボタンを削除します。"; 172 | "PlayerNoDownload" = "オフラインボタンを削除"; 173 | "PlayerNoDownloadDesc" = "プレーヤー下にある [オフライン] ボタンを削除します。"; 174 | "PlayerNoClip" = "クリップボタンを削除"; 175 | "PlayerNoClipDesc" = "プレーヤー下にある [クリップ] ボタンを削除します。"; 176 | "PlayerNoSave" = "保存ボタンを削除"; 177 | "PlayerNoSaveDesc" = "プレーヤー下にある [保存] ボタンを削除します。"; 178 | "PlayerNoReport" = "報告ボタンを削除"; 179 | "PlayerNoReportDesc" = "プレーヤー下にある [報告] ボタンを削除します。"; 180 | 181 | "ProgressBarStyle" = "プログレスバーのスタイル"; 182 | "SolidColor" = "単色"; 183 | "Gradient" = "グラデーション"; 184 | "MainColor" = "メインの色"; 185 | "GradientColor" = "グラデーションのハイライト"; 186 | "ScrubberColor" = "スクラブの色"; 187 | 188 | "Player.Actions" = "動作"; 189 | "DefaultPlaybackRate" = "デフォルトの再生速度"; 190 | "DefaultPlaybackRateDesc" = "デフォルトの再生速度を上書きします。"; 191 | "BackgroundPlayback" = "バックグラウンド再生"; 192 | "BackgroundPlaybackDesc" = "バックグラウンド再生を有効にします。"; 193 | "Miniplayer" = "ミニプレーヤーを有効化"; 194 | "MiniplayerDesc" = "ミニプレーヤーに対応していない動画(子供向けの動画など)でもミニプレーヤーを有効にします。"; 195 | "DisableAutoplay" = "自動再生を無効化"; 196 | "DisableAutoplayDesc" = "アプリを開いた直後に動画が自動再生されるのを防止します。"; 197 | "DisableAutoCaptions" = "自動字幕を無効化"; 198 | "DisableAutoCaptionsDesc" = "字幕が自動で有効化されるのを防止します。"; 199 | "NoContentWarning" = "年齢制限ダイアログをスキップ"; 200 | "NoContentWarningDesc" = "不適切なコンテンツの警告メッセージをスキップします。"; 201 | "NoHints" = "ヒントを無効化"; 202 | "NoHintsDesc" = "再生中に右上に表示される投稿者のヒントを無効にします。"; 203 | "AutoFullscreen" = "動画を全画面で再生"; 204 | "AutoFullscreenDesc" = "動画を自動的に全画面表示で再生します。"; 205 | "ExitFullscreen" = "再生終了時に全画面表示を終了"; 206 | "ExitFullscreenDesc" = "動画が終了した際に全画面表示を終了します。"; 207 | 208 | "Player.Gestures" = "ジェスチャー"; 209 | "CompactToast" = "コンパクトなトーストを使用"; 210 | "CompactToastDesc" = "プレイヤーのジェスチャー用のコンパクトなスタイルのトーストを表示します。"; 211 | "LeftSideGesture" = "左側のジェスチャー"; 212 | "LeftSideGestureDesc" = "画面の左側を縦にスワイプして選択した設定を調整します。"; 213 | "RightSideGesture" = "右側のジェスチャー"; 214 | "RightSideGestureDesc" = "画面の右側を縦にスワイプして選択した設定を調整します。"; 215 | "ActivationAreaWidth" = "ジェスチャー有効化幅"; 216 | "ActivationAreaWidthDesc" = "この値は、画面左右のジェスチャー認識領域をピクセル単位で決定します。\n\n許可される最大値は画面幅の 3 分の 1 です。\n\nプレーヤーの最小化や拡大を試みる際の誤作動を防ぐために、この設定を調整すると便利です。"; 217 | "HoldToSpeed" = "長押しで再生速度を変更"; 218 | "HoldToSpeedDesc" = "プレーヤーを長押しすることで再生速度を設定します。"; 219 | "AdjustWithFinger" = "ジェスチャーで再生速度を調整"; 220 | "AdjustWithFingerDesc" = "プレーヤーを長押ししながら指を上下に動かすことで再生速度を調整できます。"; 221 | "PreserveSpeed" = "再生速度を維持"; 222 | "PreserveSpeedDesc" = "ジェスチャー終了後も調整された再生速度を維持します。"; 223 | "SeekAnywhere" = "スワイプでシーク"; 224 | "SeekAnywhereDesc" = "左右にスワイプして再生シークを制御できるようにします。"; 225 | "SeekMethod" = "シーク方法"; 226 | "SeekMethodDesc" = "独立型: 動画の全期間にわたって自由に高速スクロールできます。シーク感度のみが適用されます。\n\n期間ベース: スクロールの強度は動画の長さとシーク感度に依存します。長い動画で大きなセクションをスクロールするのを防ぐのに便利です。"; 227 | "Independent" = "独立型"; 228 | "DurationBased" = "期間ベース"; 229 | "SeekSensitivity" = "シークの感度"; 230 | "TwoFingerTapToPause" = "2 本の指で一時停止"; 231 | "TwoFingerTapToPauseDesc" = "2 本の指で画面をタップして再生を一時停止/再開します。"; 232 | "TwoFingerPanToBrightness" = "明るさを調整"; 233 | "TwoFingerPanToBrightnessDesc" = "2 本の指で上下にスワイプして画面の明るさを調整できます。"; 234 | "CopyWithTimestamp" = "タイムスタンプ付きリンクをコピー"; 235 | "CopyWithTimestampDesc" = "一時停止ボタンを押すことで、タイムスタンプ付きリンクをクリップボードにコピーできます。"; 236 | "PauseOnOverlay" = "オーバーレイで一時停止"; 237 | "PauseOnOverlayDesc" = "オーバーレイが表示された場合、再生を一時停止します。"; 238 | "DontSnap2Chapter" = "チャプターへのスナップを無効化"; 239 | "DontSnap2ChapterDesc" = "ダブルタップジェスチャーで次のエピソードへスキップするのを無効にします。"; 240 | "NoTwoFingerSnapToChapter" = "2 本指ダブルタップを無効化"; 241 | "NoTwoFingerSnapToChapterDesc" = "2 本指でダブルタップしてチャプターにスナップするジェスチャーを無効にします。"; 242 | "NoFreeZoom" = "フリーズームジェスチャーを無効化"; 243 | "NoFreeZoomDesc" = "新しいフリーズームジェスチャーを無効にします。"; 244 | "NoDoubleTap2Seek" = "ダブルタップでのシークを無効化"; 245 | "NoDoubleTap2SeekDesc" = "ダブルタップでのシークジェスチャーを無効にします。"; 246 | 247 | /* Shorts options */ 248 | "Shorts" = "ショート"; 249 | "PlaybackMode" = "動画終了後の動作"; 250 | "Loop" = "ループ再生"; 251 | "ScrollToNext" = "次の動画へ自動で遷移"; 252 | "Stop" = "一時停止"; 253 | "AutoSkipShorts" = "ショートを自動スキップ"; 254 | "ShortsOnlyMode" = "ショートのみモード"; 255 | "ShortsOnlyModeDesc" = "YouTube の機能をショートの視聴のみに制限します。\n\n注意:これを有効にすると、他の操作は行えません。"; 256 | "RestrictShorts" = "ショートを制限"; 257 | "RestrictShortsDesc" = "フィードに表示されるショートの数を 10~15 本に制限します。フィードを無限にスクロールする習慣を避けたい場合に便利です。"; 258 | "ShortsProgress" = "プログレスバーを有効化"; 259 | "ShortsProgressDesc" = "ショートのプレーヤー上にプログレスバーを表示します。"; 260 | "SpeedByLongTap" = "ショートの再生速度を上げる"; 261 | "SpeedByLongTapDesc" = "画面の特定の部分を長押しすることで再生速度を上げることができます。"; 262 | "SpeedLocation" = "再生速度の高速化の起動位置"; 263 | "PinchToFullscreenShorts" = "ピンチして全画面表示"; 264 | "PinchToFullscreenShortsDesc" = "ピンチインおよびピンチアウトジェスチャーでオーバーレイの表示/非表示を管理し、ショートを全画面で表示します。"; 265 | "ShortsToRegular" = "通常のプレーヤーでショートを再生"; 266 | "ShortsToRegularDesc" = "ショート動画を通常のプレーヤーで再生します。"; 267 | "RemoveShortsLive" = "ライブ配信を削除"; 268 | "RemoveShortsLiveDesc" = "[ショート] タブからライブ配信を削除します。"; 269 | 270 | "ShortsInterface" = "インターフェース"; 271 | "HideShortsLogo" = "ショートのロゴを非表示"; 272 | "HideShortsLogoDesc" = "左上隅のショートロゴを非表示にします。"; 273 | "HideShortsSearch" = "検索ボタンを非表示"; 274 | "HideShortsSearchDesc" = "ショートのプレーヤー上から検索ボタンを非表示にします。"; 275 | "HideShortsCamera" = "カメラボタンを非表示"; 276 | "HideShortsCameraDesc" = "ショートのプレーヤー上からカメラボタンを非表示にします。"; 277 | "HideShortsMore" = "その他( ⋮ )ボタンを非表示"; 278 | "HideShortsMoreDesc" = "ショートのプレーヤー上からその他( ⋮ )ボタンを非表示にします。画面を長押しでもアクセスも可能です。"; 279 | 280 | "HideCarouselSub" = "チャンネル登録ボタンを非表示"; 281 | "HideCarouselSubDesc" = "一時停止状態で表示される [チャンネル登録] ボタンを削除します。"; 282 | "HideCarouselLive" = "ライブボタンを非表示"; 283 | "HideCarouselLiveDesc" = "一時停止状態で表示される [ライブ] ボタンを削除します。"; 284 | "HideCarouselTrends" = "トレンドボタンを非表示"; 285 | "HideCarouselTrendsDesc" = "一時停止状態で表示される [トレンド] ボタンを削除します。"; 286 | "HideCarouselShop" = "ショップボタンを非表示"; 287 | "HideCarouselShopDesc" = "一時停止状態で表示される [ショップ] ボタンを削除します。"; 288 | 289 | "HideShortsLike" = "高評価ボタンを非表示"; 290 | "HideShortsLikeDesc" = "アクションバーから高評価ボタンを削除します。"; 291 | "HideShortsDislike" = "低評価ボタンを非表示"; 292 | "HideShortsDislikeDesc" = "アクションバーから低評価ボタンを削除します。"; 293 | "HideShortsComments" = "コメントボタンを非表示"; 294 | "HideShortsCommentsDesc" = "アクションバーからコメントボタンを削除します。"; 295 | "HideShortsShare" = "共有ボタンを非表示"; 296 | "HideShortsShareDesc" = "アクションバーから [共有] ボタンを削除します。"; 297 | "HideShortsRemix" = "リミックスボタンを非表示"; 298 | "HideShortsRemixDesc" = "アクションバーから [リミックス] ボタンを削除します。"; 299 | "HideShortsSuggestion" = "提案を非表示"; 300 | "HideShortsSuggestionDesc" = "[再生リストに追加]、[Super Thanks] などの提案ボタンを削除します。"; 301 | "HideShortsSubscribe" = "チャンネル登録ボタンを非表示"; 302 | "HideShortsSubscribeDesc" = "ユーザー名の横にある [チャンネル登録] ボタンを削除します。"; 303 | "HideShortsUsername" = "ユーザー名を非表示"; 304 | "HideShortsUsernameDesc" = "ユーザー名(チャンネル名)を削除します。"; 305 | "HideShortsDescription" = "説明を非表示"; 306 | "HideShortsDescriptionDesc" = "プレーヤー下部の説明を削除します。"; 307 | "HideShortsSource" = "フルの動画へのリンクラベルを非表示"; 308 | "HideShortsSourceDesc" = "フルの動画へのリンクラベルを非表示にします。"; 309 | "HideShortsAudio" = "楽曲のラベルを非表示"; 310 | "HideShortsAudioDesc" = "プレーヤー下部に表示される楽曲のラベルを非表示にします。"; 311 | 312 | /* Tab bar options */ 313 | "Tabbar" = "タブバー"; 314 | "Startup" = "アプリ起動時のページ"; 315 | "FEwhat_to_watch" = "ホーム"; 316 | "FEexplore" = "探索"; 317 | "FEshorts" = "ショート"; 318 | "FEsubscriptions" = "登録チャンネル"; 319 | "FElibrary" = "ライブラリ"; 320 | "FEuploads" = "作成"; 321 | "FEhistory" = "履歴"; 322 | "FEpost_home" = "投稿"; 323 | "VLWL" = "後で見る"; 324 | 325 | "TranslucentBar" = "半透明のタブバー"; 326 | "RemoveLabels" = "タブのラベルを削除"; 327 | "RemoveIndicators" = "タブのインジケーターを削除"; 328 | 329 | "ActiveTabs" = "有効なタブ"; 330 | "InactiveTabs" = "無効なタブ"; 331 | "HideLibraryFooter" = "タブバーの最初のタブを長押しすることで、タブ設定にアクセスすることもできます。"; 332 | "Warning" = "警告"; 333 | "AtLeastOneTab" = "少なくとも 1 つのタブが有効になっている必要があります。"; 334 | "TabsCountRestricted" = "有効にできるタブは最大 6 つまでです。"; 335 | 336 | /* Interface options */ 337 | "Interface" = "インターフェース"; 338 | "OledTheme" = "OLED テーマ"; 339 | "OledThemeDesc" = "すべての暗い色を黒に変えます。"; 340 | "OledKeyboard" = "OLED キーボード"; 341 | "OledKeyboardDesc" = "ダークキーボード用に OLED ブラックテーマを適用します。"; 342 | "NoSearchHistory" = "検索履歴を非表示"; 343 | "NoSearchHistoryDesc" = "検索履歴とサジェストを視覚的に非表示にします。\n\n注意: 検索履歴は他の YouTube クライアントから引き続きアクセス可能です。"; 344 | "StickSortComments" = "コメントヘッダーを固定"; 345 | "StickSortCommentsDesc" = "コメントの並び順ヘッダー(人気順、新しい順)をスクロールしても消えないように固定します。"; 346 | "HideSortComments" = "コメントヘッダーを非表示"; 347 | "HideSortCommentsDesc" = "コメントの並び順ヘッダー(人気順、新しい順)を非表示にします。"; 348 | "PlaylistOldMinibar" = "古い再生リストミニバーを有効化"; 349 | "PlaylistOldMinibarDesc" = "新しいフローティング再生リストパネルを旧バージョンのものに置き換えます。"; 350 | "OldYTUI" = "古い UI"; 351 | "OldYTUIDesc" = "YouTube のバージョンを偽装して、旧バージョンのインターフェースに戻します。"; 352 | "DisableRTL" = "RTL フォーマットを無効化"; 353 | "DisableRTLDesc" = "元々右から左(RTL)で表示される言語のテキストを、左から右(LTR)形式で表示するように強制します。"; 354 | 355 | "StartupAnimation" = "起動時のアニメーションを有効化"; 356 | "StartupAnimationDesc" = "YouTube 起動時の読み込みアニメーションを有効化します。"; 357 | 358 | "InterfaceStyle" = "インターフェースのスタイル"; 359 | 360 | "MiniplayerStyle" = "ミニプレーヤーのスタイル"; 361 | "MiniplayerStyleDesc" = "フローティングモードへの切り替え/終了にはアプリの再起動が必要です。"; 362 | "Floating" = "フローティング"; 363 | 364 | "Other" = "その他"; 365 | "NoShareChunk" = "共有識別子を削除"; 366 | "NoShareChunkDesc" = "共有リンクから「si=identifier」パラメータを削除します。YouTube が共有メニューを継続的に改善しているため、「システムの共有シートに置換」オプションの優れた代替手段となります。"; 367 | "AutoCheckLinks" = "クリップボードの自動確認"; 368 | "AutoCheckLinksDesc" = "アプリを開くたびに、クリップボードに YouTube 関連のリンクが保存されているか確認します。\n正しく機能させるには、iOS の設定 → YouTube → 他のアプリからの貼り付けで「許可」を選択してください。"; 369 | 370 | "ContextMenu" = "コンテキストメニュー"; 371 | "NativeShare" = "システムの共有シートに置換"; 372 | "NativeShareDesc" = "システムの共有シートを使用してメディアを共有します。"; 373 | "RemoveCommentGuidelines" = "ガイドラインを削除"; 374 | "RemoveCommentGuidelinesDesc" = "コメント欄からガイドラインを削除します。"; 375 | "RemovePlayNext" = "[次に再生] を削除"; 376 | "RemovePlayNextDesc" = "メニューから [次に再生] オプションを削除します。"; 377 | "RemoveDownloadMenu" = "[オフライン] を削除"; 378 | "RemoveDownloadMenuDesc" = "メニューから [オフラインへの動画の保存] オプションを削除します。"; 379 | "RemoveWatchLaterMenu" = "[[後で見る] に保存]を削除"; 380 | "RemoveWatchLaterMenuDesc" = "メニューから [[後で見る] に保存] オプションを削除します。"; 381 | "RemoveSaveToPlaylistMenu" = "[再生リストに保存] を削除"; 382 | "RemoveSaveToPlaylistMenuDesc" = "メニューから [再生リストに保存] オプションを削除します。"; 383 | "RemoveShareMenu" = "[共有] を削除"; 384 | "RemoveShareMenuDesc" = "メニューから [共有] オプションを削除します。"; 385 | "RemoveNotInterestedMenu" = "[興味なし] を削除"; 386 | "RemoveNotInterestedMenuDesc" = "メニューから [興味なし] オプションを削除します。"; 387 | "RemoveDontRecommendMenu" = "[チャンネルをおすすめに表示しない] を削除"; 388 | "RemoveDontRecommendMenuDesc" = "メニューから [チャンネルをおすすめに表示しない] オプションを削除します。"; 389 | "RemoveReportMenu" = "[報告] を削除"; 390 | "RemoveReportMenuDesc" = "メニューから [報告] オプションを削除します。"; 391 | "RemoveRemixMenu" = "[リミックス] を削除"; 392 | "RemoveRemixMenuDesc" = "メニューから [リミックス] オプションを削除します。"; 393 | "RemoveYTMMenu" = "[YouTube Music] を非表示"; 394 | "RemoveYTMMenuDesc" = "メニューから [YouTube Music で聴く] オプションをを非表示にします。"; 395 | 396 | /* SponsorBlock settings */ 397 | "EnableSponsorBlock" = "有効化"; 398 | "EnableSponsorBlockDesc" = "SponsorBlock 拡張機能を有効にします。"; 399 | "SbPlayerButton" = "オーバーレイでボタンを表示"; 400 | "SbPlayerButtonDesc" = "プレーヤーオーバーレイに SponsorBlock のボタンを追加します。"; 401 | "ShowNotifications" = "通知を表示"; 402 | "ShowNotificationsDesc" = "自動的にスキップされたセグメントの通知を表示します。手動でスキップする必要があるカテゴリの通知は常に表示されます。"; 403 | "SegmentsInFeedPlayer" = "フィードにセグメントを表示"; 404 | "SegmentsInFeedPlayerDesc" = "フィード内のプレイヤーのプログレスバーに色付きのセグメントを表示します。"; 405 | "SegmentsInMiniPlayer" = "ミニプレーヤーにセグメントを表示"; 406 | "SegmentsInMiniPlayerDesc" = "ミニプレーヤーのプログレスバーに色付きのセグメントを表示します。"; 407 | "SegmentSkipAudio" = "オーディオ通知"; 408 | "SegmentSkipAudioDesc" = "セグメントをスキップした際にオーディオ通知を再生します。"; 409 | "DurationWithoutSegments" = "新しい動画時間を表示"; 410 | "DurationWithoutSegmentsDesc" = "セグメント除いた合計の動画時間を表示します。"; 411 | 412 | "SkipAlertDuration" = "[スキップ] ボタンを表示する時間"; 413 | "UnskipAlertDuration" = "[スキップしない] ボタンを表示する時間"; 414 | 415 | "Segments" = "セグメント"; 416 | "Sponsor" = "スポンサー"; 417 | "SponsorDesc" = "作成者と直接関係のない製品やサービスを宣伝するビデオの一部。作成者は金銭または無料製品の形で支払いまたは報酬を受け取ります。"; 418 | "SponsorColor" = "スポンサーセグメントの色"; 419 | "Intro" = "休憩 / イントロアニメーション"; 420 | "IntroDesc" = "通常、ビデオの冒頭に見られるセグメントで、同じ作成者の他の動画でも見られるアニメーション、静止フレーム、またはクリップが含まれます。"; 421 | "IntroColor" = "イントロのセグメントの色"; 422 | "Endcards" = "エンドカード / クレジット"; 423 | "EndcardsDesc" = "一般的に動画の終盤、クレジットが表示されたりエンドカードが表示されるタイミングです。"; 424 | "EndcardsColor" = "エンドカードのセグメントの色"; 425 | "Interaction" = "動画の間に挿入される告知"; 426 | "InteractionDesc" = "有料または無料プラットフォームにおける「いいね」「登録」「動画クリック」などの明示的なリマインダー"; 427 | "InteractionColor" = "インタラクションのセグメントの色"; 428 | "SelfPromo" = "無報酬 / セルフプロモーション"; 429 | "SelfPromoDesc" = "自己宣伝: クリエイター自身に直接関連する製品やサービスを宣伝するケース\n無報酬: この宣伝に対してクリエイターは報酬を受け取りません"; 430 | "SelfPromoColor" = "セルフプロモーションのセグメントの色"; 431 | "MusicOfftopic" = "音楽ではない区間"; 432 | "MusicOfftopicDesc" = "音楽を主なコンテンツとする動画にのみ使用できます。"; 433 | "MusicOfftopicColor" = "音楽以外の区間セグメントの色"; 434 | "Preview" = "予告"; 435 | "PreviewDesc" = "この動画や他の動画でこのあと起きる内容など、今後再び登場する場面を連続的にまとめたクリップ。"; 436 | "PreviewColor" = "プレビューのセグメントの色"; 437 | "Highlight" = "ハイライト"; 438 | "HighlightDesc" = "動画の要点やハイライトを伝えるために使用されます。"; 439 | "HighlightColor" = "ハイライトのセグメントの色"; 440 | "Jokes" = "繋ぎの話 / 冗談"; 441 | "JokesDesc" = "繋ぎの話/冗談は、動画の本編を理解するのに不要な、単なるつなぎやユーモアのために追加されたシーンにのみ適用されます。"; 442 | "JokesColor" = "ジョークセグメントの色"; 443 | 444 | "Sb.Disable" = "無効化"; 445 | "Sb.Skip" = "自動スキップ"; 446 | "Sb.SkipTo" = "セグメントにスキップ"; 447 | "Sb.Ask" = "スキップするか確認"; 448 | "Sb.Display" = "プレーヤーに表示"; 449 | 450 | "PublicUserID" = "公開ユーザ ID"; 451 | "PrivateUserID" = "プライベートユーザー ID"; 452 | "TapToReveal" = "タップして表示"; 453 | "Save" = "保存"; 454 | "Error.SbPublicID" = "パブリックユーザー ID は 64 文字でなければなりません。"; 455 | "Error.SbPrivateID" = "プライベート (またはローカル) ユーザー ID は少なくとも 32 文字でなければなりません"; 456 | 457 | "sb_sponsor" = "スポンサーセグメント"; 458 | "sb_intro" = "イントロセグメント"; 459 | "sb_outro" = "エンドカードセグメント"; 460 | "sb_interaction" = "インタラクションセグメント"; 461 | "sb_selfpromo" = "自己プロモーションセグメント"; 462 | "sb_music_offtopic" = "余談セグメント"; 463 | "sb_preview" = "プレビューセグメント"; 464 | "sb_poi_highlight" = "ハイライト"; 465 | "sb_filler" = "フィラーセグメント"; 466 | 467 | "SegmentDetected" = "%@ を検出しました。\n%@"; 468 | "SegmentSkipped" = "%@ はスキップされました"; 469 | "SkippedToSegment" = "%@ にジャンプしました。"; 470 | "SkipSegment" = "セグメントをスキップしますか?"; 471 | "SkipToSegment" = "ハイライトにジャンプしますか?"; 472 | "Unskip" = "スキップしない"; 473 | 474 | /* Developer section */ 475 | "Developer" = "開発者"; 476 | "FollowMe" = "𝕏 (旧 Twitter) でフォロー"; 477 | "SupportDevelopment" = "開発を支援"; 478 | "DonateDesc" = "あなたの支援は私にとってとても励みになります!"; 479 | "SupportDevelopmentDesc" = "もし YTPlus を気に入って頂き、開発を支援したい場合は、以下のいずれかの便利な方法でサポートできます。 \nご支援ありがとうございます❤"; 480 | "VisitGithub" = "GitHub リポジトリ"; 481 | "VisitGithubDesc" = "リポジトリにスターを付けたり、機能リクエストや問題報告を行えます"; 482 | "VisitTelegram" = "Telegram チャンネル"; 483 | "VisitTelegramDesc" = "最新のアプリのアップデートを確認できます。"; 484 | 485 | /* Credits section */ 486 | "Credits" = "謝辞"; 487 | 488 | "Contributors" = "貢献者"; 489 | "DevContribution" = "開発への貢献"; 490 | "SpecialThanks" = "特別な感謝"; 491 | "SpecialThanks.Test" = "Tweak テストの貴重な貢献"; 492 | 493 | "Localizations" = "ローカライズへの貢献者"; 494 | "ChineseSimplified" = "中国語(簡体字)"; 495 | "ChineseTraditional" = "中国語(繁体字)"; 496 | "French" = "フランス語"; 497 | "Spanish" = "スペイン語"; 498 | "Japanese" = "日本語"; 499 | "Vietnamese" = "ベトナム語"; 500 | "Arabic" = "アラビア語"; 501 | "Turkish" = "トルコ語"; 502 | "Italian" = "イタリア語"; 503 | "Korean" = "韓国語"; 504 | "Polish" = "ポーランド語"; 505 | 506 | "OpenSourceLibs" = "オープンソースライブラリ"; 507 | "SupporterWall" = "支援者"; 508 | 509 | "Preferences" = "%@ 設定"; 510 | "ManagePreferences" = "設定の管理"; 511 | "ImportPreferences" = "設定をインポート"; 512 | "PreImportMessage" = "この操作により現在の設定が選択したファイルの設定に上書きされます。\n\n続行しますか?"; 513 | "ExportPreferences" = "設定のエクスポート"; 514 | "ResetSettings" = "YTPlus の設定をリセット"; 515 | "ResetMessage" = "この操作により YTPlus の設定がデフォルトにリセットされ、YouTube が終了します。\n\n続行しますか?"; 516 | 517 | "ManageCache" = "キャッシュ管理"; 518 | "ClearCacheAtStart" = "起動時にキャッシュを消去"; 519 | "ClearCacheAtStartDesc" = "起動時に自動的にキャッシュを削除します。"; 520 | "ClearCache" = "キャッシュを削除"; 521 | 522 | "NoDonationReminder" = "寄付のリマインダーを無効化"; 523 | "NoDonationReminderDesc" = "ほとんど表示されない寄付のリマインダーを非表示にします。"; 524 | 525 | "ShortsOnlyWarning" = "このモードを有効にしてもよろしいですか?\n\nこのモードでは、ショート動画の視聴のみが可能で、他の操作は行えません。\n\nショートプレーヤーで 2 本の指で長押しすると、ショート専用モードを無効にできます。"; 526 | "ShortsModeTurnedOff" = "ショートのみモードがオフになりました。"; 527 | 528 | "AddLibraryTab" = "[マイページ] タブを復元"; 529 | "RemoveLibraryTab" = "[マイページ] タブを削除"; 530 | "LibraryAdded" = "[マイページ] タブを復元しました。"; 531 | "LibraryRemoved" = "[マイページ] タブを削除しました。"; 532 | 533 | "Yes" = "はい"; 534 | "No" = "いいえ"; 535 | 536 | "Select" = "選択"; 537 | "Default" = "デフォルト"; 538 | "Best" = "最高"; 539 | "Show" = "表示"; 540 | "Disable" = "無効化"; 541 | "Disabled" = "無効"; 542 | "PlaybackSpeed" = "再生速度"; 543 | "SpeedPreserved" = "再生速度が%@にロックされました。"; 544 | "ResetSpeed" = "リセット"; 545 | 546 | "Toast.Brightness" = "明るさ"; 547 | "Toast.PlaybackSpeed" = "再生速度"; 548 | "Toast.Volume" = "音量"; 549 | 550 | "SelectAction" = "アクションを選択"; 551 | "DownloadVideo" = "動画をダウンロード"; 552 | "DownloadAudio" = "オーディオをダウンロード"; 553 | "SaveImage" = "画像を保存"; 554 | "CopyInformation" = "情報をコピー"; 555 | "CopyChannelName" = "チャンネル名をコピー"; 556 | "CopyTitle" = "タイトルをコピー"; 557 | "CopyDescription" = "説明をコピー"; 558 | "CopyTimestampedLink" = "タイムスタンプ付きのリンクをコピー"; 559 | "CopyTranscript" = "文字起こしをコピー"; 560 | "PlayInExternalPlayer" = "外部プレーヤーで再生"; 561 | "PlayInSystemPlayer" = "システムプレーヤーで再生"; 562 | "PlayInInfuse" = "Infuse で再生"; 563 | "PlayInVLC" = "VLC で再生"; 564 | "PlayerNotFound" = "プレーヤーが見つかりません"; 565 | "OpenAsRegularVideo" = "通常の動画として開く"; 566 | "CopyPostText" = "投稿のテキストをコピー"; 567 | "SaveCurrentImage" = "現在の画像を保存"; 568 | "ShowCurrentImage" = "現在の画像を表示"; 569 | "CopyCurrentImage" = "現在の画像をコピー"; 570 | "SavePostAsImage" = "投稿を画像として保存"; 571 | "CopyPostAsImage" = "投稿を画像としてコピー"; 572 | "CopyCommentText" = "コメントをコピー"; 573 | "SaveCommentAsImage" = "コメントを画像として保存"; 574 | "CopyCommentAsImage" = "コメントを画像としてコピー"; 575 | "SaveProfilePicture" = "プロフィール画像を保存"; 576 | "ShowProfilePicture" = "プロフィール画像を表示"; 577 | "CopyProfilePicture" = "プロフィール画像をコピー"; 578 | "DownloadThumbnail" = "サムネイルを保存"; 579 | "ShowThumbnail" = "サムネイルを表示"; 580 | "CopyThumbnail" = "サムネイルをコピー"; 581 | "Cancel" = "キャンセル"; 582 | "Cancelled" = "キャンセルされました"; 583 | "Copied" = "クリップボードにコピーしました"; 584 | "Saved" = "「写真」アプリに保存"; 585 | "Done" = "完了"; 586 | "NothingToShowInMenu" = "このコンテキストメニューに表示するものはありません"; 587 | "Error" = "エラー"; 588 | "Error.Clipboard" = "エラー: 詳細についてはクリップボードを確認してください。"; 589 | "Error.PathIssue" = "エラー: 最終パスの生成に問題が発生しました。メディアタイトルに問題がある可能性があります。"; 590 | "Error.TryLater" = "メディアはライブ配信中または Google サーバー上での処理完了待ち状態です。\n\n後ほど再度お試しください。"; 591 | "Error.NoSpace" = "デバイスの空き容量が不足しています。\n\n少なくとも %@ の追加空き容量が必要です。使用可能な空き容量: %@"; 592 | "Error.Multidownloading" = "同時ダウンロード機能はまだ利用できません。"; 593 | "Error.FailedToImport" = "設定をインポートできませんでした。"; 594 | "DownloadingVideo" = "動画のダウンロード中"; 595 | "DownloadingAudio" = "オーディオのダウンロード中"; 596 | "ParsingCaptions" = "字幕を解析中"; 597 | "ParsingTranscript" = "トランスクリプトを解析中"; 598 | "Converting" = "変換中"; 599 | "RetryLogin" = "回避策が有効になりました。\n\nもう一度お試しください。"; 600 | "LoginInfo" = "Google アカウントへのログインに成功した後、アプリの再起動が必要です。"; 601 | 602 | "OpenLink" = "リンクを開く"; 603 | "LinkDetected" = "YouTube 関連のリンクが検出されました。YouTube で開きますか?"; 604 | 605 | "SbWhitelist" = "ホワイトリスト"; 606 | "SbAddToWhitelist" = "ホワイトリストに登録"; 607 | "Sb.Whitelisted" = "ホワイトリストに登録しました。"; 608 | "SbRemoveFromWhitelist" = "ホワイトリストから削除"; 609 | "Sb.Whitelist" = "ホワイトリストに登録されたチャンネル"; 610 | "Sb.Channels" = "チャンネル"; 611 | "Sb.ChannelsHere" = "ホワイトリストに登録されたチャンネルがここに表示されます。"; 612 | "SortType" = "並べ替えの種類"; 613 | "Sb.Newest" = "新しい順"; 614 | "Sb.Oldest" = "古い順"; 615 | "Sb.Alphabetical" = "アルファベット順 (A ~ Z)"; 616 | "Sb.AlphabeticalRev" = "アルファベット順 (逆順)"; 617 | 618 | "Welcome.Download" = "メディアのダウンロード"; 619 | "Welcome.DownloadDesc" = "動画、ショート、オーディオ、プロフィール画像など、お気に入りのコンテンツをダウンロードできます。興味深い投稿やコメントをコピーしたり、画像として保存したりできます。"; 620 | "Welcome.Content" = "インターフェースを調整"; 621 | "Welcome.ContentDesc" = "不要なコンテンツやインターフェース要素を削除します。真の OLED ダークモードを有効にします。"; 622 | "Welcome.Player" = "プレーヤーの動作を設定"; 623 | "Welcome.PlayerDesc" = "プレーヤーの動作をカスタマイズし、画質と再生速度を自動選択します。ジェスチャーで操作可能です。"; 624 | "Welcome.More" = "そしてさらに…"; 625 | "Welcome.MoreDesc" = "YouTube Plus には設定の保存やキャッシュの消去など 50 以上の異なるオプションが含まれています。YouTube Plus の設定は YouTube 設定内の YouTube Plus セクションで利用可能です。"; 626 | "SupportMe" = "支援してください"; 627 | "Continue" = "続行"; 628 | 629 | "Conflicts.Detected" = "互換性のない Tweak が検出されました"; 630 | "Conflicts.DetectedDesc" = "アプリの見かけ上の安定性にも関わらず、YouTube Plus の開発者は類似機能を持つ調整を同じアプリ内で併用することは推奨せず、安全な使用を保証できません。\n\n本アプリの使用を継続することで、あなたは全責任を負うことに同意し、パフォーマンスに関する苦情が無視されることに同意したものとみなされます。"; 631 | "Conflicts.SkipThisVersion" = "このバージョンでは表示しない"; 632 | "Conflicts.AcceptRisks" = "すべてのリスクを受け入ます"; 633 | "Conflicts.CloseYT" = "YouTube を閉じる"; 634 | 635 | "DonationReminder" = "皆さんのご支援が YouTube Plus の更なる改善に繋がります。\n\n寄付を行うか、YouTube Plus 設定でこれらの通知を無効にすることもできます。ご支援ありがとうございます💜"; 636 | -------------------------------------------------------------------------------- /layout/Library/Application Support/YTLite.bundle/ko.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Main section */ 2 | "Main" = "메인"; 3 | 4 | /* Downloading options */ 5 | "Downloading" = "다운로드"; 6 | "DownloadManager" = "다운로드 매니저"; 7 | "DownloadManagerDesc" = "플레이어 아래의 \"다운로드\" 버튼 동작을 비디오, 오디오, 썸네일 이미지, 비디오 정보 복사 등을 가능하게 하는 다운로드 매니저로 대체합니다."; 8 | "PostManager" = "게시물 정보 저장"; 9 | "PostManagerDesc" = "길게 탭하여 글의 텍스트를 복사하고 글 이미지를 저장할 수 있습니다."; 10 | "SaveProfilePhoto" = "프로필 사진 저장"; 11 | "SaveProfilePhotoDesc" = "길게 탭하여 프로필 사진을 사진 앱에 저장합니다."; 12 | "CommentManager" = "댓글 정보 저장"; 13 | "CommentManagerDesc" = "길게 탭하여 댓글 텍스트를 복사하고 댓글 이미지를 저장할 수 있습니다."; 14 | 15 | "YtlButtonPosition" = "다운로드 버튼 배치"; 16 | "UnderPlayer" = "플레이어 아래"; 17 | "Overlay" = "오버레이"; 18 | "Both" = "둘 다"; 19 | 20 | "PostDownloadAction" = "다운로드 후 동작"; 21 | "PostDownloadDesc" = "동영상 다운로드가 성공적으로 완료되면 선택된 동작이 수행됩니다."; 22 | "SaveToPhotos" = "사진에 저장"; 23 | "Share" = "공유"; 24 | "Copy" = "Copy"; 25 | "Ask" = "묻기"; 26 | "DownloadCompleted" = "다운로드 완료"; 27 | 28 | "PreferredAudio" = "선호 오디오 트랙"; 29 | "Selected" = "선택됨"; 30 | "English" = "영어"; 31 | "SelectAudioTrack" = "오디오 트랙 선택"; 32 | "EnglishNotFound" = "영어 오디오 트랙을 찾을 수 없음"; 33 | 34 | "Audios" = "오디오"; 35 | "AudioDRC" = "안정적인 볼륨 선호"; 36 | "AudioDRCDesc" = "다운로드 관리자는 안정적인 볼륨(Dynamic Range Compression)을 가진 오디오를 사용할 수 있는 경우, 우선 순위를 지정합니다"; 37 | 38 | "CaptionsAndThumbnails" = "자막 및 썸네일"; 39 | "EmbedThumbnailsToVideos" = "썸네일 포함"; 40 | "EmbedThumbnailsToVideosDesc" = "동영상의 썸네일을 메타데이터 썸네일로 포함"; 41 | "EmbedCapsToVideos" = "자막 포함"; 42 | "EmbedCapsToVideosDesc" = "선택한 자막/부자막을 비디오에 삽입합니다."; 43 | "EmbedAutoGenCaps" = "자동 생성/번역된 자막"; 44 | "EmbedAutoGenCapsDesc" = "자동 생성된 자막, 번역된 자막, 자동 번역된 자막을 자막/부자막 목록에 추가합니다."; 45 | "DownloadCaptions" = "자막 다운로드"; 46 | "SelectCaption" = "자막/부자막 선택"; 47 | "Translated" = "번역됨"; 48 | "TranslatedAutoGen" = "자동 번역됨"; 49 | 50 | /* Nav bar options */ 51 | "Navbar" = "탐색 표시줄"; 52 | "RemoveCast" = "캐스트 버튼 숨기기"; 53 | "RemoveCastDesc" = "탐색 표시줄에서 캐스트 버튼 숨기기"; 54 | "RemoveNotifications" = "알림 버튼 숨기기"; 55 | "RemoveNotificationsDesc" = "탐색 표시줄에서 알림 버튼 숨기기"; 56 | "RemoveSearch" = "검색 버튼 숨기기"; 57 | "RemoveSearchDesc" = "탐색 표시줄에서 검색 버튼 숨기기"; 58 | "RemoveVoiceSearch" = "음성 검색 버튼 숨기기"; 59 | "RemoveVoiceSearchDesc" = "탐색 표시줄에서 음성 검색 버튼 숨기기"; 60 | "StickyNavbar" = "고정 탐색 모음"; 61 | "StickyNavbarDesc" = "아래로 스크롤할 때 탐색 표시줄이 계속 보이도록 고정합니다."; 62 | "NoSubbar" = "하위 모음 숨기기"; 63 | "NoSubbarDesc" = "탐색 표시줄 아래의 하위 모음(전체, 새로운 항목, 라이브 등)을 숨깁니다."; 64 | "NoYTLogo" = "YouTube 로고 제거"; 65 | "NoYTLogoDesc" = "탐색 표시줄의 YouTube 로고 제거"; 66 | "PremiumYTLogo" = "프리미엄 YouTube 로고 설정"; 67 | "PremiumYTLogoDesc" = "탐색 표시줄의 프리미엄 YouTube 로고 설정"; 68 | 69 | /* Feed options */ 70 | "Feed" = "피드"; 71 | "RemoveAds" = "광고 제거"; 72 | "RemoveAdsDesc" = "앱 내 광고 제거"; 73 | "HideShorts" = "Shorts 영상 숨기기"; 74 | "HideShortsDesc" = "홈페이지, 추천 등에서의 Shorts 영상 숨기기"; 75 | "KeepSubsShorts" = "구독 중인 Shorts 영상 유지"; 76 | "KeepSubsShortsDesc" = "구독 탭에서 Shorts를 제거하지 않도록 합니다."; 77 | "RemoveCommunityPosts" = "커뮤니티 게시물 제거"; 78 | "RemoveCommunityPostsDesc" = "피드에서 커뮤니티 게시물 제거"; 79 | "RemoveMixPlaylists" = "믹스 제거"; 80 | "RemoveMixPlaylistsDesc" = "피드에서 YouTube에서 생성된 믹스 재생목록 제거"; 81 | "RemoveLiveVids" = "라이브 비디오 제거"; 82 | "RemoveLiveVidsDesc" = "홈 탭에서 라이브 비디오 제거"; 83 | "RemoveHorizontalFeeds" = "가로 피드 제거"; 84 | "RemoveHorizontalFeedsDesc" = "홈 탭에서 모든 가로 피드(뉴스, 계속 보기, 게시물 모음 등) 제거"; 85 | "RemoveMoreTopics" = "더 많은 주제 제거"; 86 | "RemoveMoreTopicsDesc" = "피드에서 \"추가 주제\"를 제거합니다."; 87 | "RemovePlayables" = "재생 가능 항목 제거"; 88 | "RemovePlayablesDesc" = "피드에서 재생 가능 항목(미니 게임)을 제거합니다."; 89 | "FixAlbums" = "표지 수정"; 90 | "FixAlbumsDesc" = "러시아 사용자의 표지 표시를 수정합니다."; 91 | 92 | /* Player options */ 93 | "Player" = "플레이어"; 94 | "PlaybackQualityOnWiFi" = "WiFi에서의 재생 품질"; 95 | "PlaybackQualityOnWiFiDesc" = "Automatically applies the selected quality when streaming over Wi-Fi"; 96 | "PlaybackQualityOnCellular" = "셀룰러에서의 재생 품질"; 97 | "PlaybackQualityOnCellularDesc" = "Automatically applies the selected quality when streaming over mobile data"; 98 | 99 | "PreferredCaptions" = "선호 자막"; 100 | "Original" = "원본"; 101 | "Custom" = "수동 선택"; 102 | "CustomAudioTrack" = "선택된 오디오 트랙"; 103 | "CustomAudioTrackDesc" = "Specifies the preferred audio track language to use for playback, if available"; 104 | "CustomCaptions" = "선택된 자막"; 105 | "CustomCaptionsDesc" = "Specifies the preferred captions language to display, if available"; 106 | "AutoGenCaps" = "자동 생성 자막"; 107 | "AutoGenCapsDesc" = "선택된 자막이 발견되지 않으면, YouTube Plus는 원본 자막의 번역본이나 자동 생성 자막의 번역본을 선택하려고 시도합니다."; 108 | 109 | "Player.Interface" = "인터페이스"; 110 | "SpeedControls" = "속도 조절"; 111 | "SpeedControlsDesc" = "오버레이에 속도 조절 버튼을 표시합니다."; 112 | "MuteButton" = "음소거 버튼"; 113 | "MuteButtonDesc" = "오버레이에서 음량을 음소거하거나 음소거 해제하는 버튼을 표시합니다."; 114 | "LockButton" = "잠금 버튼"; 115 | "LockButtonDesc" = "오버레이 화면을 빠르게 잠그고 전체 화면 모드로 전환하는 버튼을 표시합니다."; 116 | "HideAutoplay" = "자동 재생 스위치 숨기기"; 117 | "HideAutoplayDesc" = "오버레이에서 자동 재생 스위치 숨기기"; 118 | "HideSubs" = "자막 버튼 숨기기"; 119 | "HideSubsDesc" = "오버레이에서 자막 버튼 숨기기"; 120 | "HidePrevNext" = "이전 및 다음 버튼 숨기기"; 121 | "HidePrevNextDesc" = "오버레이에서 이전 및 다음 비디오 버튼을 숨깁니다."; 122 | "ReplacePrevNext" = "빨리 감기 및 되감기 버튼"; 123 | "ReplacePrevNextDesc" = "오버레이에서 이전 및 다음 비디오 버튼을 빨리 감기 및 되감기 버튼으로 대체합니다."; 124 | "RememberLoopMode" = "반복 모드 기억"; 125 | "RememberLoopModeDesc" = "플레이어 메뉴에서 마지막으로 선택한 반복 모드를 기억합니다."; 126 | "FullscreenToTheLeft" = "왼쪽 회전 시 전체 화면"; 127 | "FullscreenToTheLeftDesc" = "전체 화면 모드는 기기를 일반적인 오른쪽 방향이 아닌 왼쪽 방향으로 회전시킵니다."; 128 | "PortraitFullscreen" = "세로 전체 화면 모드"; 129 | "PortraitFullscreenDesc" = "세로 전체 화면 모드 지원을 활성화합니다."; 130 | "ClassicQuality" = "클래식 비디오 품질"; 131 | "ClassicQualityDesc" = "클래식 비디오 품질 선택 메뉴를 다시 불러옵니다."; 132 | "ExtraSpeedOptions" = "재생 속도 옵션 추가"; 133 | "ExtraSpeedOptionsDesc" = "플레이어 메뉴에 더 많은 비디오 재생 속도 옵션을 추가합니다."; 134 | "NoDarkBg" = "어두운 배경 제거"; 135 | "NoDarkBgDesc" = "오버레이 어두운 배경 제거."; 136 | "NoEndScreenCards" = "최종 화면 호버 카드 숨기기"; 137 | "NoEndScreenCardsDesc" = "동영상 끝부분의 최종 화면(썸네일)을 숨깁니다."; 138 | "NoAutonavEndScreenCards" = "자동 재생 종료 화면 숨기기"; 139 | "NoAutonavEndScreenCardsDesc" = "재생이 끝난 후 다음에 재생할 수 있는 항목을 보여주는 화면을 숨깁니다. 이 옵션을 비활성화하면 자동 재생도 비활성화됩니다."; 140 | "NoFullscreenActions" = "전체 화면 동작 비활성화"; 141 | "NoFullscreenActionsDesc" = "전체 화면 모드에서 동작 패널 비활성화"; 142 | "PersistentProgressBar" = "지속적인 진행률 표시줄"; 143 | "PersistentProgressBarDesc" = "플레이어에서 항상 진행률 표시줄 표시"; 144 | "RedProgressBar" = "빨간색 진행률 표시줄"; 145 | "RedProgressBarDesc" = "빨간색 진행률 표시줄 복원"; 146 | "StockVolumeHUD" = "기본 볼륨 HUD"; 147 | "StockVolumeHUDDesc" = "시스템 볼륨 HUD를 전체 화면으로 표시합니다."; 148 | "NoRelatedVids" = "오버레이 관련 동영상 숨기기"; 149 | "NoRelatedVidsDesc" = "위로 밀어서 오버레이에 표시되는 관련 동영상을 제거합니다."; 150 | "NoPromotionCards" = "유료 프로모션 카드 숨기기"; 151 | "NoPromotionCardsDesc" = "Hides \"Includes Paid Promotions\" card in promotions included videos."; 152 | "NoWatermarks" = "워터마크 숨기기"; 153 | "NoWatermarksDesc" = "플레이어에서 채널 워터마크를 숨깁니다."; 154 | "DisableAmbientMode" = "주변 모드 비활성화"; 155 | "DisableAmbientModeDesc" = "플레이어와 그 아래 영역에서 주변 모드를 비활성화합니다."; 156 | "VideoEndTime" = "재생 종료 시간 표시"; 157 | "VideoEndTimeDesc" = "플레이어 바에 비디오 재생 종료 시간을 추가합니다."; 158 | "24hrFormat" = "24시간 형식"; 159 | "24hrFormatDesc" = "종료 시간을 24시간 형식으로 표시합니다."; 160 | "NoRelatedWatchNexts" = "플레이어 아래의 모든 비디오 숨기기"; 161 | "NoRelatedWatchNextsDesc" = "플레이어 아래의 모든 비디오를 숨기고, 비디오 정보와 코멘트 섹션만 남겨둠"; 162 | "RemoveInlineComment" = "인라인 코멘트 제거"; 163 | "RemoveInlineCommentDesc" = "플레이어 아래의 코멘트 섹션 제거"; 164 | "NoSubUnderPlayer" = "Remove \"Subscribe\" button"; 165 | "NoSubUnderPlayerDesc" = "플레이어 아래의 \"구독\" 버튼을 제거합니다."; 166 | "PlayerNoShare" = "Remove \"Share\" button"; 167 | "PlayerNoShareDesc" = "플레이어 아래의 \"공유\" 버튼을 제거합니다."; 168 | "PlayerNoThanks" = "Remove \"Thanks\" button"; 169 | "PlayerNoThanksDesc" = "플레이어 아래의 \"Thanks\" 버튼을 제거합니다."; 170 | "PlayerNoRemix" = "\"리믹스\" 버튼 제거"; 171 | "PlayerNoRemixDesc" = "리믹스 버튼을 플레이어 밑으로 이동합니다."; 172 | "PlayerNoDownload" = "\"다운로드\" 버튼 제거"; 173 | "PlayerNoDownloadDesc" = "다운로드 버튼을 플레이어 밑으로 이동합니다."; 174 | "PlayerNoClip" = "\"클립\" 버튼 제거"; 175 | "PlayerNoClipDesc" = "플레이어 아래의 \"클립\" 버튼을 제거합니다."; 176 | "PlayerNoSave" = "\"저장\" 버튼 제거"; 177 | "PlayerNoSaveDesc" = "플레이어 아래의 \"저장\" 버튼을 제거합니다."; 178 | "PlayerNoReport" = "\"신고\" 버튼 제거"; 179 | "PlayerNoReportDesc" = "플레이어 아래의 \"신고\" 버튼을 제거합니다."; 180 | 181 | "ProgressBarStyle" = "진행 표시줄 스타일"; 182 | "SolidColor" = "단색"; 183 | "Gradient" = "그라디언트"; 184 | "MainColor" = "기본 색상"; 185 | "GradientColor" = "그라디언트 하이라이트"; 186 | "ScrubberColor" = "스크러버 색상"; 187 | 188 | "Player.Actions" = "액션"; 189 | "DefaultPlaybackRate" = "기본 재생 속도"; 190 | "DefaultPlaybackRateDesc" = "Overrides the default playback speed"; 191 | "BackgroundPlayback" = "배경 재생"; 192 | "BackgroundPlaybackDesc" = "백그라운드 재생 활성화."; 193 | "Miniplayer" = "미니 플레이어 활성화"; 194 | "MiniplayerDesc" = "어린이를 대상으로 하는 비디오와 같이 원래 그렇게 설계되지 않은 비디오에 대해 미니 플레이어를 활성화합니다."; 195 | "DisableAutoplay" = "자동 재생 비디오 비활성화"; 196 | "DisableAutoplayDesc" = "열린 후 비디오 재생 방지."; 197 | "DisableAutoCaptions" = "자동 자막 비활성화"; 198 | "DisableAutoCaptionsDesc" = "자막 자동 활성화 방지"; 199 | "NoContentWarning" = "콘텐츠 경고 건너뛰기"; 200 | "NoContentWarningDesc" = "민감한 콘텐츠 경고 메시지 건너뛰기"; 201 | "NoHints" = "힌트 비활성화"; 202 | "NoHintsDesc" = "재생 도중 오른쪽 상단에 나타나는 작성자 힌트를 비활성화합니다."; 203 | "AutoFullscreen" = "동영상을 전체 화면으로 재생합니다."; 204 | "AutoFullscreenDesc" = "동영상을 전체 화면 모드로 자동 재생합니다."; 205 | "ExitFullscreen" = "완료 시 전체 화면 모드를 종료합니다."; 206 | "ExitFullscreenDesc" = "동영상 재생이 끝날 때 전체 화면 모드를 종료합니다."; 207 | 208 | "Player.Gestures" = "제스처"; 209 | "CompactToast" = "Compact toast"; 210 | "CompactToastDesc" = "Displays a compact-style toast for player gestures"; 211 | "LeftSideGesture" = "왼쪽 제스처"; 212 | "LeftSideGestureDesc" = "Adjusts the selected setting by swiping vertically on the left side of the screen"; 213 | "RightSideGesture" = "오른쪽 제스처"; 214 | "RightSideGestureDesc" = "Adjusts the selected setting by swiping vertically on the right side of the screen"; 215 | "ActivationAreaWidth" = "제스처 활성화 폭"; 216 | "ActivationAreaWidthDesc" = "이 값은 화면의 왼쪽과 오른쪽에 대한 제스처 인식 영역을 픽셀 단위로 결정합니다.\n\n허용되는 최대 값은 화면 너비의 1/3입니다.\n\n이 설정을 조정하면 플레이어를 최소화하거나 확장하려고 할 때 실수로 활성화되는 것을 방지하는 데 유용합니다."; 217 | "HoldToSpeed" = "길게 누르면 속도"; 218 | "HoldToSpeedDesc" = "Sets the playback speed triggered by a long press on the player"; 219 | "AdjustWithFinger" = "제스처로 속도 조정"; 220 | "AdjustWithFingerDesc" = "플레이어를 길게 누르고 손가락을 위아래로 움직여 재생 속도를 조절할 수 있습니다."; 221 | "PreserveSpeed" = "Lock speed"; 222 | "PreserveSpeedDesc" = "Locks at adjusted speed after gesture completion."; 223 | "SeekAnywhere" = "스와이프하여 탐색"; 224 | "SeekAnywhereDesc" = "좌우로 스와이프하여 재생 탐색을 제어할 수 있습니다."; 225 | "SeekMethod" = "탐색 방법"; 226 | "SeekMethodDesc" = "독립: 전체 비디오 재생 시간 동안 자유롭게 빠르게 스크롤할 수 있습니다. 탐색 감도만 고려됩니다.\n\n재생 시간 기반: 스크롤 강도는 비디오의 길이와 탐색 감도에 따라 달라집니다. 긴 비디오의 경우, 비디오의 큰 부분을 스크롤하지 않도록 하는 데 유용할 수 있습니다."; 227 | "Independent" = "독립"; 228 | "DurationBased" = "재생 시간 기반"; 229 | "SeekSensitivity" = "탐색 민감도"; 230 | "TwoFingerTapToPause" = "두 손가락으로 탭하여 일시 정지"; 231 | "TwoFingerTapToPauseDesc" = "두 손가락으로 화면을 탭하여 재생 일시 정지/재개"; 232 | "TwoFingerPanToBrightness" = "밝기 조절"; 233 | "TwoFingerPanToBrightnessDesc" = "두 손가락을 사용하여 위/아래로 밀어서 화면 밝기를 조절할 수 있습니다."; 234 | "CopyWithTimestamp" = "타임스탬프가 있는 링크를 복사합니다"; 235 | "CopyWithTimestampDesc" = "일시정지 버튼을 눌러 타임스탬프가 있는 링크를 클립보드에 복사할 수 있습니다."; 236 | "PauseOnOverlay" = "오버레이에서 일시 정지"; 237 | "PauseOnOverlayDesc" = "오버레이가 나타나면 일시 정지 상태로 재생 설정"; 238 | "DontSnap2Chapter" = "챕터 스냅 기능 비활성화"; 239 | "DontSnap2ChapterDesc" = "두 번 탭 동작으로 다음 에피소드로 건너뛰는 기능 비활성화"; 240 | "NoTwoFingerSnapToChapter" = "두 손가락 두 번 탭 기능 비활성화"; 241 | "NoTwoFingerSnapToChapterDesc" = "두 손가락 두 번 탭으로 챕터로 이동하는 제스처를 비활성화합니다."; 242 | "NoFreeZoom" = "자유 확대/축소 제스처를 비활성화합니다."; 243 | "NoFreeZoomDesc" = "새로운 자유 확대/축소 제스처를 비활성화합니다."; 244 | "NoDoubleTap2Seek" = "두 번 탭으로 탐색하는 제스처를 비활성화합니다."; 245 | "NoDoubleTap2SeekDesc" = "두 번 탭으로 탐색하는 제스처를 비활성화합니다."; 246 | 247 | /* Shorts options */ 248 | "Shorts" = "Shorts"; 249 | "PlaybackMode" = "재생 완료 동작"; 250 | "Loop" = "반복"; 251 | "ScrollToNext" = "다음으로 스크롤"; 252 | "Stop" = "중지"; 253 | "AutoSkipShorts" = "Shorts 자동 건너뛰기"; 254 | "ShortsOnlyMode" = "Shorts 전용 모드"; 255 | "ShortsOnlyModeDesc" = "유튜브 기능을 Shorts만 볼 수 있도록 제한합니다."; 256 | "RestrictShorts" = "Shorts 제한"; 257 | "RestrictShortsDesc" = "피드에 있는 Shorts 수를 10-15개로 제한합니다. 피드를 끝없이 스크롤하는 습관을 피하고 싶을 때 유용합니다."; 258 | "ShortsProgress" = "진행률 표시줄 활성화"; 259 | "ShortsProgressDesc" = "Shorts 오버레이에 진행률 표시줄 표시"; 260 | "SpeedByLongTap" = "Shorts 재생 속도 향상"; 261 | "SpeedByLongTapDesc" = "화면의 특정 부분을 길게 탭하여 재생 속도 향상"; 262 | "SpeedLocation" = "활성화 위치 속도 향상"; 263 | "PinchToFullscreenShorts" = "핀치하여 전체 화면으로 확대"; 264 | "PinchToFullscreenShortsDesc" = "핀치 인 및 핀치 아웃 제스처로 오버레이의 가시성을 관리하여 Shorts를 전체 화면 모드로 표시합니다."; 265 | "ShortsToRegular" = "Shorts 동영상을 일반 동영상으로 전환"; 266 | "ShortsToRegularDesc" = "Shorts 동영상을 일반 동영상으로 엽니다."; 267 | "RemoveShortsLive" = "라이브 비디오 제거"; 268 | "RemoveShortsLiveDesc" = "피드에서 라이브 비디오를 제거합니다"; 269 | 270 | "ShortsInterface" = "인터페이스"; 271 | "HideShortsLogo" = "Shorts 로고 숨기기"; 272 | "HideShortsLogoDesc" = "Shorts 로고를 왼쪽 상단 모서리에 숨깁니다."; 273 | "HideShortsSearch" = "검색 버튼 숨기기"; 274 | "HideShortsSearchDesc" = "Shorts 오버레이에서 검색 버튼을 숨깁니다."; 275 | "HideShortsCamera" = "카메라 버튼 숨기기"; 276 | "HideShortsCameraDesc" = "Shorts 오버레이에서 카메라 버튼 숨기기"; 277 | "HideShortsMore" = "더 보기 (⋮) 버튼 숨기기"; 278 | "HideShortsMoreDesc" = "Shorts 오버레이에서 더 보기 (⋮) 버튼 숨기기. 화면을 길게 누르면 액세스할 수도 있습니다."; 279 | 280 | "HideCarouselSub" = "구독 버튼 숨기기"; 281 | "HideCarouselSubDesc" = "일시 정지 상태에 나타나는 구독 버튼을 제거합니다."; 282 | "HideCarouselLive" = "라이브 버튼 숨기기"; 283 | "HideCarouselLiveDesc" = "일시 정지 상태에 나타나는 라이브 버튼을 제거합니다."; 284 | "HideCarouselTrends" = "트렌드 버튼 숨기기"; 285 | "HideCarouselTrendsDesc" = "일시 정지 상태에 나타나는 트렌드 버튼을 제거합니다."; 286 | "HideCarouselShop" = "Shop 숨기기"; 287 | "HideCarouselShopDesc" = "일시 정지 상태에 나타나는 Shop 버튼을 제거합니다."; 288 | 289 | "HideShortsLike" = "좋아요 버튼 숨기기"; 290 | "HideShortsLikeDesc" = "액션 바에서 좋아요 버튼을 제거합니다."; 291 | "HideShortsDislike" = "싫어요 버튼 숨기기"; 292 | "HideShortsDislikeDesc" = "액션 바에서 싫어요 버튼을 제거합니다."; 293 | "HideShortsComments" = "댓글 버튼 숨기기"; 294 | "HideShortsCommentsDesc" = "액션 바에서 댓글 버튼을 제거합니다."; 295 | "HideShortsShare" = "공유 버튼 없음"; 296 | "HideShortsShareDesc" = "액션 바에서 공유 버튼을 제거합니다."; 297 | "HideShortsRemix" = "리믹스 버튼 없음"; 298 | "HideShortsRemixDesc" = "액션 바에서 리믹스 버튼을 제거합니다."; 299 | "HideShortsSuggestion" = "제안 없음"; 300 | "HideShortsSuggestionDesc" = "재생목록에 추가, 슈퍼 감사 등 제안 버튼을 제거합니다."; 301 | "HideShortsSubscribe" = "팔로우 버튼 없음"; 302 | "HideShortsSubscribeDesc" = "사용자 이름 옆에 있는 팔로우 버튼을 제거합니다."; 303 | "HideShortsUsername" = "사용자 이름 없음"; 304 | "HideShortsUsernameDesc" = "채널 이름 제거"; 305 | "HideShortsDescription" = "설명 없음"; 306 | "HideShortsDescriptionDesc" = "Shorts 설명 제거"; 307 | "HideShortsSource" = "소스 링크 버튼 없음"; 308 | "HideShortsSourceDesc" = "전체 영상 또는 다른 Shorts 영상으로 이동하는 버튼 제거"; 309 | "HideShortsAudio" = "오디오 표시 없음"; 310 | "HideShortsAudioDesc" = "Shorts에 사용된 오디오를 나타내는 줄을 제거합니다."; 311 | 312 | /* Tab bar options */ 313 | "Tabbar" = "탭 바"; 314 | "Startup" = "시작 페이지"; 315 | "FEwhat_to_watch" = "홈"; 316 | "FEexplore" = "탐색"; 317 | "FEshorts" = "Shorts"; 318 | "FEsubscriptions" = "구독"; 319 | "FElibrary" = "라이브러리"; 320 | "FEuploads" = "제작"; 321 | "FEhistory" = "기록"; 322 | "FEpost_home" = "게시물"; 323 | "VLWL" = "나중에 시청하기"; 324 | 325 | "TranslucentBar" = "반투명 탭 바"; 326 | "RemoveLabels" = "탭 라벨 제거"; 327 | "RemoveIndicators" = "탭 표시기 제거"; 328 | 329 | "ActiveTabs" = "활성 탭"; 330 | "InactiveTabs" = "비활성 탭"; 331 | "HideLibraryFooter" = "탭 바의 첫 번째 탭을 길게 누르면 라이브러리 탭을 숨기거나 표시할 수 있습니다."; 332 | "Warning" = "경고"; 333 | "AtLeastOneTab" = "At least one tab must remain active"; 334 | "TabsCountRestricted" = "활성 탭은 최대 6개까지만 가질 수 있습니다"; 335 | 336 | /* Interface options */ 337 | "Interface" = "인터페이스"; 338 | "OledTheme" = "OLED 테마"; 339 | "OledThemeDesc" = "모든 어두운 색을 검은색으로 바꿉니다"; 340 | "OledKeyboard" = "OLED 키보드"; 341 | "OledKeyboardDesc" = "어두운 키보드에 OLED 검은색 테마를 적용합니다"; 342 | "NoSearchHistory" = "검색 기록 숨기기"; 343 | "NoSearchHistoryDesc" = "검색 기록과 제안을 시각적으로 숨깁니다. 참고: 검색 기록은 다른 YouTube 클라이언트에서 계속 액세스할 수 있습니다."; 344 | "StickSortComments" = "댓글 헤더 고정"; 345 | "StickSortCommentsDesc" = "댓글 헤더를 고정하여 스크롤하는 동안 사라지지 않도록 합니다(상단, 최신순)."; 346 | "HideSortComments" = "댓글 헤더 숨기기"; 347 | "HideSortCommentsDesc" = "정렬된 댓글 헤더(상위, 최신)를 숨겨서 표시되지 않도록 합니다."; 348 | "PlaylistOldMinibar" = "이전 재생목록 미니바"; 349 | "PlaylistOldMinibarDesc" = "새로운 플로팅 재생목록 패널을 이전 패널로 대체합니다."; 350 | "OldYTUI" = "구 UI"; 351 | "OldYTUIDesc" = "구 인터페이스로 돌아가도록 YouTube 버전을 스푸핑합니다"; 352 | "DisableRTL" = "RTL 서식 비활성화"; 353 | "DisableRTLDesc" = "Forcefully displays text in left-to-right (LTR) format for languages that are initially displayed in right-to-left (RTL)."; 354 | 355 | "StartupAnimation" = "시작 애니메이션"; 356 | "StartupAnimationDesc" = "YouTube 시작 로딩 애니메이션을 표시합니다."; 357 | 358 | "InterfaceStyle" = "인터페이스 스타일"; 359 | 360 | "MiniplayerStyle" = "미니 플레이어 스타일"; 361 | "MiniplayerStyleDesc" = "플로팅 모드로 전환하거나 플로팅 모드를 종료하려면 앱을 다시 시작해야 합니다."; 362 | "Floating" = "플로팅"; 363 | 364 | "Other" = "Other"; 365 | "NoShareChunk" = "공유 식별자 제거"; 366 | "NoShareChunkDesc" = "공유 링크에서 \"si=identifier\" 매개변수를 제거합니다. YouTube가 공유 메뉴를 계속 개선하고 있으므로, \"네이티브 공유 시트\" 옵션을 대신할 수 있는 좋은 대안입니다."; 367 | "AutoCheckLinks" = "Auto-check clipboard"; 368 | "AutoCheckLinksDesc" = "Check clipboard for YouTube-related links each time the app is opened.\nFor proper functionality, go to iOS Settings → YouTube → Paste from other apps and select \"Allow\""; 369 | 370 | "ContextMenu" = "컨텍스트 메뉴"; 371 | "NativeShare" = "네이티브 공유 시트"; 372 | "NativeShareDesc" = "시스템 공유 시트를 사용하여 미디어를 공유합니다"; 373 | "RemoveCommentGuidelines" = "가이드라인 제거"; 374 | "RemoveCommentGuidelinesDesc" = "댓글 섹션에서 가이드라인을 제거합니다."; 375 | "RemovePlayNext" = "\"다음 대기열에서 재생\" 제거"; 376 | "RemovePlayNextDesc" = "메뉴에서 \"다음 대기열에서 재생\" 옵션을 제거합니다."; 377 | "RemoveDownloadMenu" = "\"다운로드\" 제거"; 378 | "RemoveDownloadMenuDesc" = "메뉴에서 \"다운로드\" 옵션을 제거합니다."; 379 | "RemoveWatchLaterMenu" = "\"나중에 보기 위해 저장\" 제거"; 380 | "RemoveWatchLaterMenuDesc" = "메뉴에서 \"나중에 보기 위해 저장\" 옵션을 제거합니다."; 381 | "RemoveSaveToPlaylistMenu" = "\"재생 목록에 저장\" 제거"; 382 | "RemoveSaveToPlaylistMenuDesc" = "메뉴에서 \"재생목록에 저장\" 옵션을 제거합니다."; 383 | "RemoveShareMenu" = "\"공유\" 제거"; 384 | "RemoveShareMenuDesc" = "메뉴에서 \"공유\" 옵션을 제거합니다."; 385 | "RemoveNotInterestedMenu" = "\"관심 없음\" 제거"; 386 | "RemoveNotInterestedMenuDesc" = "메뉴에서 \"관심 없음\" 옵션을 제거합니다."; 387 | "RemoveDontRecommendMenu" = "\"채널 추천 안 함\" 제거"; 388 | "RemoveDontRecommendMenuDesc" = "메뉴에서 \"채널 추천 안 함\" 옵션을 제거합니다."; 389 | "RemoveReportMenu" = "\"신고\" 제거"; 390 | "RemoveReportMenuDesc" = "메뉴에서 \"신고\" 옵션을 제거합니다."; 391 | "RemoveRemixMenu" = "Remove \"Remix\""; 392 | "RemoveRemixMenuDesc" = "Removes \"Remix\" option from menu."; 393 | "RemoveYTMMenu" = "Remove \"YouTube Music\""; 394 | "RemoveYTMMenuDesc" = "Removes \"Listen with YouTube Music\" option from menu."; 395 | 396 | /* SponsorBlock settings */ 397 | "EnableSponsorBlock" = "활성화"; 398 | "EnableSponsorBlockDesc" = "SponsorBlock 확장 기능을 활성화합니다."; 399 | "SbPlayerButton" = "Display button in overlay"; 400 | "SbPlayerButtonDesc" = "Adds SponsorBlock button in players overlay."; 401 | "ShowNotifications" = "알림 표시"; 402 | "ShowNotificationsDesc" = "자동으로 건너뛰는 세그먼트에 대한 알림을 표시합니다. 수동으로 건너뛰어야 하는 카테고리에 대한 알림은 항상 표시됩니다."; 403 | "SegmentsInFeedPlayer" = "피드에 세그먼트 표시"; 404 | "SegmentsInFeedPlayerDesc" = "피드 플레이어의 진행률 표시줄에 컬러 세그먼트를 표시합니다."; 405 | "SegmentsInMiniPlayer" = "미니 플레이어에 세그먼트를 표시합니다"; 406 | "SegmentsInMiniPlayerDesc" = "미니 플레이어의 진행률 표시줄에 컬러 세그먼트를 표시합니다."; 407 | "SegmentSkipAudio" = "오디오 알림"; 408 | "SegmentSkipAudioDesc" = "세그먼트를 건너뛰면 오디오 알림을 재생합니다."; 409 | "DurationWithoutSegments" = "새로운 지속 시간 표시"; 410 | "DurationWithoutSegmentsDesc" = "세그먼트가 없는 총 지속 시간을 표시합니다."; 411 | 412 | "SkipAlertDuration" = "건너뛰기 알림 지속 시간"; 413 | "UnskipAlertDuration" = "건너뛰기 알림 지속 시간 해제"; 414 | 415 | "Segments" = "세그먼트"; 416 | "Sponsor" = "스폰서"; 417 | "SponsorDesc" = "제작자와 직접적인 관련이 없는 제품이나 서비스를 홍보하는 비디오의 일부. 제작자는 돈이나 무료 제품 등의 형태로 지불이나 보상을 받습니다"; 418 | "SponsorColor" = "스폰서 세그먼트 색상"; 419 | "Intro" = "인터미션/인트로 애니메이션"; 420 | "IntroDesc" = "동영상 시작 부분에 있는 세그먼트로, 애니메이션, 스틸 프레임 또는 클립을 포함하며, 같은 제작자가 만든 다른 동영상에서도 볼 수 있습니다."; 421 | "IntroColor" = "인트로 세그먼트 색상"; 422 | "Endcards" = "엔드카드/크레딧"; 423 | "EndcardsDesc" = "크레딧이 뜰 때나 엔드카드가 표시될 때, 일반적으로 동영상 끝부분 근처에 표시됩니다."; 424 | "EndcardsColor" = "엔드카드 세그먼트 색상"; 425 | "Interaction" = "상호작용 알림"; 426 | "InteractionDesc" = "Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)"; 427 | "InteractionColor" = "상호작용 세그먼트 색상"; 428 | "SelfPromo" = "셀프/무료 프로모션"; 429 | "SelfPromoDesc" = "Self-promo: Promoting a product or service that is directly related to the creator themselves.\nUnpaid:The creator will not receive any payment in exchange for this promotion"; 430 | "SelfPromoColor" = "셀프 프로모션 세그먼트 색상"; 431 | "MusicOfftopic" = "음악: 음악이 아닌 섹션"; 432 | "MusicOfftopicDesc" = "음악이 주요 콘텐츠인 비디오에만 사용됩니다."; 433 | "MusicOfftopicColor" = "음악이 아닌 부분의 색상"; 434 | "Preview" = "미리보기"; 435 | "PreviewDesc" = "이 비디오 또는 시리즈의 다른 비디오에서 앞으로 나올 내용을 보여주는 클립 모음으로, 모든 정보가 비디오의 뒷부분에서 반복됩니다."; 436 | "PreviewColor" = "미리보기 부분의 색상"; 437 | "Highlight" = "하이라이트"; 438 | "HighlightDesc" = "비디오의 요점 또는 하이라이트를 강조하는 데 사용됩니다."; 439 | "HighlightColor" = "하이라이트 세그먼트 색상"; 440 | "Jokes" = "벗어난 주제/농담"; 441 | "JokesDesc" = "벗어난 주제/농담은 비디오의 주요 내용을 이해하는 데 필요하지 않은 주제 또는 유머를 위해 추가된 벗어난 장면에만 사용됩니다."; 442 | "JokesColor" = "농담 부분 색상"; 443 | 444 | "Sb.Disable" = "비활성화"; 445 | "Sb.Skip" = "자동 건너뛰기"; 446 | "Sb.SkipTo" = "부분으로 건너뛰기"; 447 | "Sb.Ask" = "묻기"; 448 | "Sb.Display" = "플레이어에 표시"; 449 | 450 | "PublicUserID" = "Public UserID"; 451 | "PrivateUserID" = "Private UserID"; 452 | "TapToReveal" = "Tap to reveal"; 453 | "Save" = "Save"; 454 | "Error.SbPublicID" = "The public user ID must contain exactly 64 characters"; 455 | "Error.SbPrivateID" = "The private (local) user ID must contain at least 32 characters"; 456 | 457 | "sb_sponsor" = "후원 부분"; 458 | "sb_intro" = "인트로 세그먼트"; 459 | "sb_outro" = "엔드카드 세그먼트"; 460 | "sb_interaction" = "상호작용 세그먼트"; 461 | "sb_selfpromo" = "셀프 프로모션 세그먼트"; 462 | "sb_music_offtopic" = "오프토픽 세그먼트"; 463 | "sb_preview" = "프리뷰 세그먼트"; 464 | "sb_poi_highlight" = "Highlight"; 465 | "sb_filler" = "벗어난 주제/농담 세그먼트"; 466 | 467 | "SegmentDetected" = "%@ detected.\n%@"; 468 | "SegmentSkipped" = "%@ has been skipped"; 469 | "SkippedToSegment" = "Jumped to %@"; 470 | "SkipSegment" = "Would you like to skip the segment?"; 471 | "SkipToSegment" = "Would you like to jump to the highlight?"; 472 | "Unskip" = "건너뛰기 해제"; 473 | 474 | /* Developer section */ 475 | "Developer" = "개발자"; 476 | "FollowMe" = "X에서 나를 팔로우하세요"; 477 | "SupportDevelopment" = "개발 지원"; 478 | "DonateDesc" = "여러분의 지원은 저에게 큰 힘이 됩니다"; 479 | "SupportDevelopmentDesc" = "YTPlus를 좋아하고 개발을 지원하고자 하신다면, 아래의 편리한 방법 중 하나를 선택하여 지원하실 수 있습니다. 감사합니다❤"; 480 | "VisitGithub" = "Github 저장소"; 481 | "VisitGithubDesc" = "저장소를 별표 표시하거나, 기능 요청을 하거나, 문제를 보고하세요"; 482 | "VisitTelegram" = "내 텔레그램 채널"; 483 | "VisitTelegramDesc" = "최신 앱 업데이트에 대한 정보를 받아 보세요"; 484 | 485 | /* Credits section */ 486 | "Credits" = "크레딧"; 487 | 488 | "Contributors" = "기여자"; 489 | "DevContribution" = "개발 기여"; 490 | "SpecialThanks" = "특별 감사"; 491 | "SpecialThanks.Test" = "조정 테스트에 대한 귀중한 기여"; 492 | 493 | "Localizations" = "현지화 작성자"; 494 | "ChineseSimplified" = "중국어 간체 현지화"; 495 | "ChineseTraditional" = "중국어 번체 현지화"; 496 | "French" = "프랑스어 현지화"; 497 | "Spanish" = "스페인어 현지화"; 498 | "Japanese" = "일본어 현지화"; 499 | "Vietnamese" = "베트남어 현지화"; 500 | "Arabic" = "아랍어 현지화"; 501 | "Turkish" = "터키어 현지화"; 502 | "Italian" = "이탈리아어 현지화"; 503 | "Korean" = "한국어 현지화"; 504 | "Polish" = "폴란드어 현지화"; 505 | 506 | "OpenSourceLibs" = "오픈 소스 라이브러리"; 507 | "SupporterWall" = "서포터"; 508 | 509 | "Preferences" = "%@ 환경 설정"; 510 | "ManagePreferences" = "환경 설정 관리"; 511 | "ImportPreferences" = "환경 설정 가져오기"; 512 | "PreImportMessage" = "이 작업은 현재 환경 설정을 선택한 파일의 환경 설정으로 대체합니다.\n\n계속하시겠습니까?"; 513 | "ExportPreferences" = "환경 설정 내보내기"; 514 | "ResetSettings" = "기본 설정 복원"; 515 | "ResetMessage" = "이 작업은 YTPlus 설정을 기본 설정으로 재설정하고 YouTube를 닫습니다.\n\n계속하시겠습니까?"; 516 | 517 | "ManageCache" = "캐시 관리"; 518 | "ClearCacheAtStart" = "시작 시 캐시 지우기"; 519 | "ClearCacheAtStartDesc" = "시작 시 자동으로 캐시를 지웁니다."; 520 | "ClearCache" = "캐시 지우기"; 521 | 522 | "NoDonationReminder" = "기부 알림 비활성화"; 523 | "NoDonationReminderDesc" = "거의 표시되지 않는 기부 알림을 끕니다."; 524 | 525 | "ShortsOnlyWarning" = "이 모드를 활성화하시겠습니까?\n\n이 모드에서는 Shorts 동영상만 볼 수 있고 다른 작업은 할 수 없습니다.\n\nShorts만 보기 모드를 해제하려면 Shorts 플레이어에서 두 손가락을 길게 누르세요."; 526 | "ShortsModeTurnedOff" = "Shorts Only Mode has been turned off"; 527 | 528 | "AddLibraryTab" = "사용자 탭 복원"; 529 | "RemoveLibraryTab" = "사용자 탭 제거"; 530 | "LibraryAdded" = "사용자 탭이 복원되었습니다"; 531 | "LibraryRemoved" = "사용자 탭이 제거되었습니다"; 532 | 533 | "Yes" = "예"; 534 | "No" = "아니오"; 535 | 536 | "Select" = "선택"; 537 | "Default" = "기본"; 538 | "Best" = "최상"; 539 | "Show" = "표시"; 540 | "Disable" = "비활성화"; 541 | "Disabled" = "비활성화됨"; 542 | "PlaybackSpeed" = "재생 속도"; 543 | "SpeedPreserved" = "Speed locked at %@"; 544 | "ResetSpeed" = "재설정"; 545 | 546 | "Toast.Brightness" = "밝기"; 547 | "Toast.PlaybackSpeed" = "재생 속도"; 548 | "Toast.Volume" = "볼륨"; 549 | 550 | "SelectAction" = "선택 작업"; 551 | "DownloadVideo" = "비디오 다운로드"; 552 | "DownloadAudio" = "오디오 다운로드"; 553 | "SaveImage" = "이미지 저장"; 554 | "CopyInformation" = "정보 복사"; 555 | "CopyChannelName" = "채널 이름 복사"; 556 | "CopyTitle" = "제목 복사"; 557 | "CopyDescription" = "설명 복사"; 558 | "CopyTimestampedLink" = "타임스탬프가 있는 링크 복사"; 559 | "CopyTranscript" = "대본 복사"; 560 | "PlayInExternalPlayer" = "외부 플레이어에서 재생"; 561 | "PlayInSystemPlayer" = "시스템 플레이어에서 재생"; 562 | "PlayInInfuse" = "Infuse에서 재생"; 563 | "PlayInVLC" = "VLC에서 재생"; 564 | "PlayerNotFound" = "플레이어가 발견되지 않음"; 565 | "OpenAsRegularVideo" = "일반 비디오로 열기"; 566 | "CopyPostText" = "게시물 텍스트 복사"; 567 | "SaveCurrentImage" = "현재 이미지 저장"; 568 | "ShowCurrentImage" = "현재 이미지 표시"; 569 | "CopyCurrentImage" = "현재 이미지 복사"; 570 | "SavePostAsImage" = "게시물을 이미지로 저장"; 571 | "CopyPostAsImage" = "게시물을 이미지로 복사"; 572 | "CopyCommentText" = "댓글 텍스트 복사"; 573 | "SaveCommentAsImage" = "댓글을 이미지로 저장"; 574 | "CopyCommentAsImage" = "댓글을 이미지로 복사"; 575 | "SaveProfilePicture" = "프로필 사진 저장"; 576 | "ShowProfilePicture" = "프로필 사진 표시"; 577 | "CopyProfilePicture" = "프로필 사진 복사"; 578 | "DownloadThumbnail" = "썸네일 저장"; 579 | "ShowThumbnail" = "썸네일 표시"; 580 | "CopyThumbnail" = "썸네일 복사"; 581 | "Cancel" = "취소"; 582 | "Cancelled" = "취소됨"; 583 | "Copied" = "클립보드에 복사됨"; 584 | "Saved" = "사진에 저장됨"; 585 | "Done" = "완료"; 586 | "NothingToShowInMenu" = "이 컨텍스트 메뉴에 표시할 항목 없음"; 587 | "Error" = "오류"; 588 | "Error.Clipboard" = "오류. 자세한 정보는 클립보드에서 확인하십시오"; 589 | "Error.PathIssue" = "최종 경로 생성 문제. 미디어 제목에 문제가 있습니까?"; 590 | "Error.TryLater" = "미디어가 라이브 상태이거나 Google 서버에서 처리 중입니다. 완료될 때까지 기다려 주세요. 나중에 다시 시도해 주세요."; 591 | "Error.NoSpace" = "장치에 공간이 부족합니다. 최소 %@의 추가 여유 공간이 필요합니다. 사용 가능한 여유 공간: %@"; 592 | "Error.Multidownloading" = "다중 다운로드는 아직 사용할 수 없습니다."; 593 | "Error.FailedToImport" = "환경 설정을 가져오지 못했습니다"; 594 | "DownloadingVideo" = "동영상 다운로드 중"; 595 | "DownloadingAudio" = "오디오 다운로드 중"; 596 | "ParsingCaptions" = "캡션 분석 중"; 597 | "ParsingTranscript" = "대본 분석 중"; 598 | "Converting" = "변환 중"; 599 | "RetryLogin" = "해결책이 활성화되었습니다. 다시 시도해 주세요."; 600 | "LoginInfo" = "App restart required after successful signing into Google account"; 601 | 602 | "OpenLink" = "Open link"; 603 | "LinkDetected" = "A YouTube-related link was detected. Would you like to open it in YouTube?"; 604 | 605 | "SbWhitelist" = "Whitelist"; 606 | "SbAddToWhitelist" = "Add to the whitelist"; 607 | "Sb.Whitelisted" = "Added to the whitelist"; 608 | "SbRemoveFromWhitelist" = "Remove from the whitelist"; 609 | "Sb.Whitelist" = "Whitelisted channels"; 610 | "Sb.Channels" = "Channels"; 611 | "Sb.ChannelsHere" = "Whitelisted channels appear here"; 612 | "SortType" = "Sort type"; 613 | "Sb.Newest" = "Newest first"; 614 | "Sb.Oldest" = "Oldest first"; 615 | "Sb.Alphabetical" = "Alphabetical (A-Z)"; 616 | "Sb.AlphabeticalRev" = "Reverse (Z-A)"; 617 | 618 | "Welcome.Download" = "미디어 다운로드"; 619 | "Welcome.DownloadDesc" = "좋아하는 콘텐츠를 다운로드하세요. 동영상, 단편, 오디오, 프로필 사진 등 무엇이든 가능합니다. 흥미로운 게시물과 댓글을 복사하거나 이미지로 저장하세요"; 620 | "Welcome.Content" = "인터페이스 조정"; 621 | "Welcome.ContentDesc" = "원치 않는 콘텐츠와 인터페이스 요소를 제거하세요. 진정한 OLED 다크 모드를 활성화하세요"; 622 | "Welcome.Player" = "플레이어 동작 설정"; 623 | "Welcome.PlayerDesc" = "Сustomize the player's behavior, auto-select quality and playback speed. Control using gestures"; 624 | "Welcome.More" = "그리고 더 많은 기능..."; 625 | "Welcome.MoreDesc" = "YouTube Plus includes over 50 different options, including features like saving preferences and clearing cache. Settings are available in the YouTube Plus section under YouTube settings"; 626 | "SupportMe" = "저를 지원해 주세요"; 627 | "Continue" = "계속"; 628 | 629 | "Conflicts.Detected" = "호환되지 않는 조정 기능 발견"; 630 | "Conflicts.DetectedDesc" = "앱의 명백한 안정성에도 불구하고, YouTube Plus의 개발자는 동일한 앱에서 유사한 기능을 가진 조정 기능을 결합하는 것을 권장하지 않으며 안전한 사용을 보장할 수 없습니다.\n\n앱을 계속 사용함으로써, 사용자는 모든 책임을 지고 성능에 대한 불만 사항은 무시된다는 데 동의합니다."; 631 | "Conflicts.SkipThisVersion" = "이 버전에 대해서는 표시하지 마세요"; 632 | "Conflicts.AcceptRisks" = "모든 위험을 받아들입니다"; 633 | "Conflicts.CloseYT" = "YouTube를 닫습니다"; 634 | 635 | "DonationReminder" = "여러분의 지원이 YouTube Plus를 더욱 발전시키는 데 도움이 됩니다.\n\nYouTube Plus 설정에서 이 알림을 활성화하거나 비활성화할 수 있습니다. 감사합니다💜"; 636 | 637 | /* Old localizations (commented out for reference) 638 | "TabIsHidden" = "숨겨진 탭은 시작 페이지로 선택할 수 없습니다"; 639 | "TabIsStartupTab" = "시작 페이지로 선택된 탭은 숨길 수 없습니다"; 640 | "PreserveSpeed" = "속도 유지"; 641 | "PreserveSpeedDesc" = "제스처가 완료된 후에도 조정된 속도를 유지합니다."; 642 | "sb_poi_highlight" = "하이라이트 세그먼트"; 643 | "SegmentDetected" = "%@가 감지됨"; 644 | "SegmentSkipped" = "%@가 건너뛰어짐"; 645 | "SkippedToSegment" = "%@로 건너뛰어짐"; 646 | "SkipSegment" = "건너뛰기"; 647 | "SkipToSegment" = "강조하기 위해"; 648 | "SpeedPreserved" = "속도 유지"; --------------------------------------------------------------------------------