fix(playback): keep protected recovery guidance neutral

This commit is contained in:
4gray committed 2026-08-04 21:27:34 +02:00
1 parent b6bf9a7bb7
commit 63d2a11663
27 files changed
+183 -42

No files matched your search

+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "إجراءات الاسترداد الموصى بها",
"ACTION_TRY_PLAYER": "جرّب {{player}}",
"ACTION_TRY_PLAYER_HINT": "مؤقت لهذا العنصر؛ سيبقى المشغل المحفوظ دون تغيير",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "إجراءات الاسترجاع المقترحة",
"ACTION_TRY_PLAYER": "جرّب {{player}}",
"ACTION_TRY_PLAYER_HINT": "مؤقت غير لهاد المحتوى؛ المشغل المحفوظ غيبقى بلا تغيير",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Рэкамендаваныя дзеянні для аднаўлення",
"ACTION_TRY_PLAYER": "Паспрабаваць {{player}}",
"ACTION_TRY_PLAYER_HINT": "Часова толькі для гэтага элемента; захаваны плэер не зменіцца",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Empfohlene Wiederherstellungsaktionen",
"ACTION_TRY_PLAYER": "{{player}} ausprobieren",
"ACTION_TRY_PLAYER_HINT": "Nur vorübergehend für diesen Inhalt; der gespeicherte Player bleibt unverändert",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Προτεινόμενες ενέργειες ανάκτησης",
"ACTION_TRY_PLAYER": "Δοκιμή του {{player}}",
"ACTION_TRY_PLAYER_HINT": "Προσωρινά για αυτό το στοιχείο· το αποθηκευμένο πρόγραμμα αναπαραγωγής δεν αλλάζει",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Recommended recovery actions",
"ACTION_TRY_PLAYER": "Try {{player}}",
"ACTION_TRY_PLAYER_HINT": "Temporary for this item; your saved player stays unchanged",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Acciones de recuperación recomendadas",
"ACTION_TRY_PLAYER": "Probar {{player}}",
"ACTION_TRY_PLAYER_HINT": "Temporal para este elemento; el reproductor guardado no cambiará",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Actions de récupération recommandées",
"ACTION_TRY_PLAYER": "Essayer {{player}}",
"ACTION_TRY_PLAYER_HINT": "Temporaire pour cet élément ; votre lecteur enregistré reste inchangé",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "A böngészőben működő lejátszó nem tudott hozzáférni ehhez az adatfolyamhoz",
"DESCRIPTION": "A kérést CORS-korlátozás, vegyes tartalom, illetve a szolgáltató fejléc- vagy proxykorlátozásai akadályozhatják. Az MPV vagy a VLC gyakran képes megkerülni a böngészőben működő lejátszó hozzáférési korlátait.",
"PWA_DESCRIPTION": "A kérést CORS-korlátozás, vegyes tartalom, illetve a szolgáltató fejléc- vagy proxykorlátozásai akadályozhatják. A PWA nem tud közvetlenül külső lejátszót indítani; válassza az Adatfolyam URL-címének másolása műveletet, majd nyissa meg kézzel MPV-ben, VLC-ben, IINA-ban vagy más lejátszóban."
"PWA_DESCRIPTION": "A kérést CORS-korlátozás, vegyes tartalom, illetve a szolgáltató fejléc- vagy proxykorlátozásai akadályozhatják. A PWA nem tud közvetlenül külső lejátszót indítani; válassza az Adatfolyam URL-címének másolása műveletet, majd nyissa meg kézzel MPV-ben, VLC-ben, IINA-ban vagy más lejátszóban.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "Az adatfolyam titkosított vagy DRM-védelemmel ellátott lehet",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Nyissa meg inkább külső lejátszóban",
"INLINE_FAILURE_TITLE": "Másolja ki az URL-címet, vagy próbálja újra",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Ajánlott helyreállítási műveletek",
"ACTION_TRY_PLAYER": "A(z) {{player}} kipróbálása",
"ACTION_TRY_PLAYER_HINT": "Csak ennél az elemnél ideiglenes; a mentett lejátszó változatlan marad",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Azioni di ripristino consigliate",
"ACTION_TRY_PLAYER": "Prova {{player}}",
"ACTION_TRY_PLAYER_HINT": "Temporaneo per questo elemento; il lettore salvato resta invariato",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "推奨される復旧操作",
"ACTION_TRY_PLAYER": "{{player}} を試す",
"ACTION_TRY_PLAYER_HINT": "この項目にのみ一時的に適用され、保存済みのプレーヤーは変更されません",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "권장 복구 작업",
"ACTION_TRY_PLAYER": "{{player}} 사용해 보기",
"ACTION_TRY_PLAYER_HINT": "이 항목에만 임시로 적용되며 저장된 플레이어는 변경되지 않습니다",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Aanbevolen herstelacties",
"ACTION_TRY_PLAYER": "{{player}} proberen",
"ACTION_TRY_PLAYER_HINT": "Tijdelijk voor dit item; je opgeslagen speler blijft ongewijzigd",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Zalecane działania odzyskiwania",
"ACTION_TRY_PLAYER": "Wypróbuj {{player}}",
"ACTION_TRY_PLAYER_HINT": "Tymczasowo dla tego elementu; zapisany odtwarzacz pozostanie bez zmian",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Ações de recuperação recomendadas",
"ACTION_TRY_PLAYER": "Experimentar {{player}}",
"ACTION_TRY_PLAYER_HINT": "Temporário para este item; o reprodutor salvo permanece inalterado",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "Браузерный плеер не получил доступ к потоку",
"DESCRIPTION": "Запрос может быть заблокирован CORS, mixed content или требованиями провайдера/прокси к заголовкам. MPV или VLC часто обходят такие ограничения браузерного плеера.",
"PWA_DESCRIPTION": "Запрос может быть заблокирован CORS, mixed content или требованиями провайдера/прокси к заголовкам. PWA не может запускать внешние плееры напрямую: нажмите «Скопировать URL потока» и откройте его вручную в MPV, VLC, IINA или другом плеере."
"PWA_DESCRIPTION": "Запрос может быть заблокирован CORS, mixed content или требованиями провайдера/прокси к заголовкам. PWA не может запускать внешние плееры напрямую: нажмите «Скопировать URL потока» и откройте его вручную в MPV, VLC, IINA или другом плеере.",
"UNTRANSFERABLE_DESCRIPTION": "Для этого защищённого потока требуются настройки воспроизведения, которые нельзя передать вместе с URL-адресом потока."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "Поток может быть зашифрован или защищен DRM",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Откройте поток во внешнем плеере",
"INLINE_FAILURE_TITLE": "Скопируйте URL или повторите попытку",
"UNTRANSFERABLE_FAILURE_TITLE": "Не удалось продолжить защищённое воспроизведение",
"RECOMMENDATIONS_LABEL": "Рекомендуемые действия для восстановления",
"ACTION_TRY_PLAYER": "Попробовать {{player}}",
"ACTION_TRY_PLAYER_HINT": "Временно только для этого элемента; сохранённый плеер не изменится",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "Önerilen kurtarma işlemleri",
"ACTION_TRY_PLAYER": "{{player}} ile dene",
"ACTION_TRY_PLAYER_HINT": "Bu öğe için geçicidir; kayıtlı oynatıcınız değişmeden kalır",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "推荐的恢复操作",
"ACTION_TRY_PLAYER": "尝试 {{player}}",
"ACTION_TRY_PLAYER_HINT": "仅临时用于此项目;已保存的播放器不会更改",
+3 -1
View File
@@ -549,7 +549,8 @@
"BROWSER_ACCESS_ERROR": {
"TITLE": "The browser player could not access this stream",
"DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. MPV or VLC can often bypass browser-player access limits.",
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player."
"PWA_DESCRIPTION": "The request may be blocked by CORS, mixed content, or provider header/proxy restrictions. The PWA cannot launch external players directly; use the Copy stream URL action and open it manually in MPV, VLC, IINA, or another player.",
"UNTRANSFERABLE_DESCRIPTION": "This protected stream requires playback configuration that cannot be transferred with the stream URL."
},
"DRM_OR_ENCRYPTION": {
"TITLE": "This stream may be encrypted or DRM-protected",
@@ -561,6 +562,7 @@
},
"NATIVE_FALLBACK_TITLE": "Open it in a native player instead",
"INLINE_FAILURE_TITLE": "Copy the URL or try again",
"UNTRANSFERABLE_FAILURE_TITLE": "Protected playback could not continue",
"RECOMMENDATIONS_LABEL": "建議的復原操作",
"ACTION_TRY_PLAYER": "嘗試 {{player}}",
"ACTION_TRY_PLAYER_HINT": "僅暫時套用於此項目;已儲存的播放器不會變更",
@@ -147,6 +147,7 @@ describe('PlaybackDiagnosticPanelComponent', () => {
fixture.componentRef.setInput('recommendations', []);
fixture.componentRef.setInput('playback', PLAYBACK);
fixture.componentRef.setInput('supportsManagedExternalPlayers', false);
fixture.componentRef.setInput('playbackExternallyTransferable', true);
});
it('applies the component host style from the actual panel stylesheet', () => {
@@ -496,12 +497,16 @@ describe('PlaybackDiagnosticPanelComponent', () => {
);
});
it('does not infer external recovery copy for DRM without a ranked external target', () => {
it('uses a neutral headline for untransferable DRM without a ranked external target', () => {
fixture.componentRef.setInput('diagnostic', {
...DIAGNOSTIC,
code: PlaybackDiagnosticCode.DrmOrEncryption,
});
fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
fixture.componentRef.setInput(
'playbackExternallyTransferable',
false
);
fixture.componentRef.setInput('recommendations', [
recommendation('alternative-source', { priority: 'primary' }),
]);
@@ -509,7 +514,7 @@ describe('PlaybackDiagnosticPanelComponent', () => {
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain(
'PLAYBACK_DIAGNOSTICS.INLINE_FAILURE_TITLE'
'PLAYBACK_DIAGNOSTICS.UNTRANSFERABLE_FAILURE_TITLE'
);
expect(fixture.nativeElement.textContent).not.toContain(
'PLAYBACK_DIAGNOSTICS.NATIVE_FALLBACK_TITLE'
@@ -60,6 +60,7 @@ export class PlaybackDiagnosticPanelComponent {
input.required<readonly PlaybackRecommendation[]>();
readonly playback = input.required<ResolvedPortalPlayback>();
readonly supportsManagedExternalPlayers = input.required<boolean>();
readonly playbackExternallyTransferable = input.required<boolean>();
readonly alternativeSources = input<readonly VodSourceDescriptor[]>([]);
readonly pending = input(false);
@@ -80,11 +81,14 @@ export class PlaybackDiagnosticPanelComponent {
readonly hasExternalPlayerRecommendation = computed(() =>
this.recommendations().some(isExternalPlayerRecommendation)
);
readonly diagnosticHeadlineKey = computed(() =>
this.hasExternalPlayerRecommendation()
? 'PLAYBACK_DIAGNOSTICS.NATIVE_FALLBACK_TITLE'
: 'PLAYBACK_DIAGNOSTICS.INLINE_FAILURE_TITLE'
);
readonly diagnosticHeadlineKey = computed(() => {
if (this.hasExternalPlayerRecommendation()) {
return 'PLAYBACK_DIAGNOSTICS.NATIVE_FALLBACK_TITLE';
}
return this.playbackExternallyTransferable()
? 'PLAYBACK_DIAGNOSTICS.INLINE_FAILURE_TITLE'
: 'PLAYBACK_DIAGNOSTICS.UNTRANSFERABLE_FAILURE_TITLE';
});
readonly getDiagnosticTitleKey = getDiagnosticTitleKey;
readonly getDiagnosticMeta = getDiagnosticMeta;
@@ -102,7 +106,8 @@ export class PlaybackDiagnosticPanelComponent {
getDiagnosticDescriptionKey(issue: PlaybackDiagnostic): string {
return getDiagnosticDescriptionKey(
issue,
this.supportsManagedExternalPlayers()
this.supportsManagedExternalPlayers(),
this.playbackExternallyTransferable()
);
}
@@ -43,17 +43,50 @@ describe('playback diagnostic view formatters', () => {
);
});
it('uses external recommendation presence for browser-access copy', () => {
it.each([
{
runtime: 'desktop',
supportsManagedExternalPlayers: true,
externallyTransferable: true,
expected:
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.DESCRIPTION',
},
{
runtime: 'PWA',
supportsManagedExternalPlayers: false,
externallyTransferable: true,
expected:
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.PWA_DESCRIPTION',
},
{
runtime: 'desktop with protected playback',
supportsManagedExternalPlayers: true,
externallyTransferable: false,
expected:
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.UNTRANSFERABLE_DESCRIPTION',
},
{
runtime: 'PWA with protected playback',
supportsManagedExternalPlayers: false,
externallyTransferable: false,
expected:
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.UNTRANSFERABLE_DESCRIPTION',
},
])('uses $runtime browser-access copy', ({
supportsManagedExternalPlayers,
externallyTransferable,
expected,
}) => {
const browserIssue: PlaybackDiagnostic = {
...issue,
code: PlaybackDiagnosticCode.BrowserAccessError,
};
expect(getDiagnosticDescriptionKey(browserIssue, true)).toBe(
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.DESCRIPTION'
);
expect(getDiagnosticDescriptionKey(browserIssue, false)).toBe(
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.PWA_DESCRIPTION'
);
expect(
getDiagnosticDescriptionKey(
browserIssue,
supportsManagedExternalPlayers,
externallyTransferable
)
).toBe(expected);
});
});
@@ -15,8 +15,16 @@ export function getDiagnosticTitleKey(issue: PlaybackDiagnostic): string {
export function getDiagnosticDescriptionKey(
issue: PlaybackDiagnostic,
supportsManagedExternalPlayers: boolean
supportsManagedExternalPlayers: boolean,
playbackExternallyTransferable: boolean
): string {
if (
issue.code === PlaybackDiagnosticCode.BrowserAccessError &&
!playbackExternallyTransferable
) {
return 'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.UNTRANSFERABLE_DESCRIPTION';
}
if (
issue.code === PlaybackDiagnosticCode.BrowserAccessError &&
!supportsManagedExternalPlayers
@@ -18,7 +18,7 @@ export function createWebPlayerRecommendations(options: {
readonly binding: PlaybackBinding | null;
readonly attemptedTargets: ReadonlySet<PlaybackRecommendationTarget>;
readonly managedExternalPlayersAvailable: boolean;
readonly playback: ResolvedPortalPlayback;
readonly playbackExternallyTransferable: boolean;
readonly isLive: boolean;
readonly alternativeSourceCount: number;
}): readonly PlaybackRecommendation[] {
@@ -26,7 +26,6 @@ export function createWebPlayerRecommendations(options: {
return [];
}
const sourceKind = resolvePlaybackSourceKind(options.diagnostic);
const drm = options.playback.drm;
return recommendPlaybackRecovery({
diagnostic: options.diagnostic,
activeTarget: options.binding.target,
@@ -39,13 +38,21 @@ export function createWebPlayerRecommendations(options: {
source: {
kind: sourceKind,
isLive: options.isLive,
drm: drm ? 'untransferable' : 'none',
externalTransferable: !drm,
drm: options.playbackExternallyTransferable
? 'none'
: 'untransferable',
externalTransferable: options.playbackExternallyTransferable,
},
alternativeSourceCount: options.alternativeSourceCount,
});
}
export function isPlaybackExternallyTransferable(
playback: ResolvedPortalPlayback
): boolean {
return playback.drm === undefined;
}
export function toVideoPlayer(target: InlinePlaybackPlayer): VideoPlayer {
switch (target) {
case InlinePlaybackPlayer.VideoJs:
@@ -101,6 +101,7 @@
[recommendations]="recommendations()"
[playback]="resolvedPlayback()"
[supportsManagedExternalPlayers]="supportsManagedExternalPlayers"
[playbackExternallyTransferable]="playbackExternallyTransferable()"
[alternativeSources]="alternativeSources()"
[pending]="recoveryPending()"
(retryRequested)="retryPlayback()"
@@ -328,6 +328,44 @@ describe('WebPlayerViewComponent', () => {
);
});
it('uses neutral browser-access guidance when DRM cannot be transferred', () => {
runtimeCapabilities.supportsManagedExternalPlayers = true;
fixture.componentRef.setInput('playback', {
streamUrl: 'https://provider.example/protected.mpd',
title: 'Protected stream',
drm: {
licenseType: 'clearkey',
supported: true,
clearKeys: {
'00112233445566778899aabbccddeeff':
'ffeeddccbbaa99887766554433221100',
},
},
});
fixture.detectChanges();
emitPlaybackIssue(createBrowserAccessDiagnostic());
fixture.detectChanges();
const banner = fixture.debugElement.query(
By.css('[data-test-id="playback-diagnostic-banner"]')
);
expect(banner.nativeElement.textContent).toContain(
'PLAYBACK_DIAGNOSTICS.UNTRANSFERABLE_FAILURE_TITLE'
);
expect(banner.nativeElement.textContent).toContain(
'PLAYBACK_DIAGNOSTICS.BROWSER_ACCESS_ERROR.UNTRANSFERABLE_DESCRIPTION'
);
expect(
banner.query(
By.css(
'[data-test-id="playback-fallback-mpv"], [data-test-id="playback-fallback-vlc"]'
)
)
).toBeNull();
});
it('renders only sanitized structured HLS evidence in technical details', () => {
const issue = createStructuredHlsDiagnostic();
@@ -1004,7 +1042,8 @@ describe('WebPlayerViewComponent', () => {
function getDiagnosticDescriptionKey(issue: PlaybackDiagnostic): string {
return resolveDiagnosticDescriptionKey(
issue,
runtimeCapabilities.supportsManagedExternalPlayers
runtimeCapabilities.supportsManagedExternalPlayers,
true
);
}
});
@@ -54,6 +54,7 @@ import {
import { resolveWebPlayerMediaTitle } from './web-player-playback-state';
import {
createWebPlayerRecommendations,
isPlaybackExternallyTransferable,
toInlinePlaybackPlayer,
toVideoPlayer,
} from './web-player-recovery-policy';
@@ -178,6 +179,9 @@ export class WebPlayerViewComponent implements OnDestroy {
readonly resolvedMediaTitle = computed(() =>
resolveWebPlayerMediaTitle(this.mediaTitle(), this.resolvedPlayback())
);
readonly playbackExternallyTransferable = computed(() =>
isPlaybackExternallyTransferable(this.resolvedPlayback())
);
readonly recordingFolder = computed(
() => this.settings()?.recordingFolder ?? ''
);
@@ -196,7 +200,8 @@ export class WebPlayerViewComponent implements OnDestroy {
attemptedTargets: this.recoverySession.attemptedTargets(),
managedExternalPlayersAvailable:
this.runtime.supportsManagedExternalPlayers,
playback: this.resolvedPlayback(),
playbackExternallyTransferable:
this.playbackExternallyTransferable(),
isLive: this.resolvedIsLive(),
alternativeSourceCount: this.alternativeSources().length,
});