feat(playback): recommend recovery actions (#1374)

* docs(playback): design recovery recommendations

* docs(playback): plan recovery recommendations

* refactor(playback): extract diagnostic utilities

* feat(playback): define recovery recommendation contracts

* feat(playback): rank recovery recommendations

* feat(playback): track session recovery attempts

* feat(playback): identify content recovery sessions

* feat(ui): add ranked playback diagnostic panel

* feat(playback): switch temporarily to recommended players

* test(playback): cover temporary player recommendation

* test(playback): verify recommendation capability guards

* docs(playback): document recovery recommendations

* fix(playback): keep recovery keys credential-free

* fix(playback): remove derived tracking ownership

* fix(playback): preserve distinct recovery fallbacks

* fix(playback): reset resume for new sources

* fix(playback): preserve desktop recovery guidance

* docs(playback): clarify recovery policy exceptions

* fix(playback): reject stale progress updates

* fix(playback): keep protected recovery guidance neutral

* test(playback): cover stale progress output

* fix(playback): neutralize protected diagnostic copy

* fix(playback): harden runtime guidance ownership

* fix(playback): stabilize recovery application ownership

* fix(ci): classify playback util coverage

* fix(e2e): preserve playback fixture bytes
This commit is contained in:
4gray authored and GitHub committed 2026-08-08 01:04:39 +02:00
1 parent 5e4f2ca3dd
commit fd96b85c19
176 files changed
+15228 -1908

No files matched your search

@@ -1,6 +1,10 @@
import { createServer, Server } from 'http';
import { readFileSync } from 'fs';
import { basename, join } from 'path';
import type {
ExternalPlayerName,
PlayerContentInfo,
} from '@iptvnator/shared/interfaces';
import {
channelItemByTitle,
closeElectronApp,
@@ -19,7 +23,47 @@ import {
* context). Uses the shared offline fixtures from apps/web-e2e/src/fixtures.
*/
const FIXTURE_DIR = join(workspaceRoot, 'apps/web-e2e/src/fixtures/dash');
const DASH_FIXTURE_DIR = join(workspaceRoot, 'apps/web-e2e/src/fixtures/dash');
const PLAYBACK_FIXTURE_DIR = join(
workspaceRoot,
'apps/web-e2e/src/fixtures/playback'
);
type PlaybackFixture = {
readonly contentType: string;
readonly path: string;
};
const FIXTURE_FILES: ReadonlyMap<string, PlaybackFixture> = new Map([
[
'clearkey.mpd',
{
contentType: 'application/dash+xml',
path: join(DASH_FIXTURE_DIR, 'clearkey.mpd'),
},
],
[
'clearkey-video.mp4',
{
contentType: 'video/mp4',
path: join(DASH_FIXTURE_DIR, 'clearkey-video.mp4'),
},
],
[
'clearkey-audio.mp4',
{
contentType: 'video/mp4',
path: join(DASH_FIXTURE_DIR, 'clearkey-audio.mp4'),
},
],
[
'unsupported.mkv',
{
contentType: 'video/matroska',
path: join(PLAYBACK_FIXTURE_DIR, 'unsupported.mkv'),
},
],
]);
const CLEARKEY_KID = '00112233445566778899aabbccddeeff';
const CLEARKEY_KEY = 'ffeeddccbbaa99887766554433221100';
@@ -29,31 +73,33 @@ type DashFixtureServer = {
origin: string;
};
/** Serves the DASH fixture directory with HTTP Range support (Shaka fetches
* init segments and the sidx via byte ranges). */
/** Serves the explicit offline fixture allowlist with HTTP Range support
* (Shaka fetches init segments and the sidx via byte ranges). */
async function startDashFixtureServer(): Promise<DashFixtureServer> {
const server: Server = createServer((request, response) => {
const pathname = (request.url ?? '').split('?')[0];
const fileName = basename(pathname);
const fixture = FIXTURE_FILES.get(fileName);
if (!fixture) {
response.writeHead(404);
response.end('not found');
return;
}
let body: Buffer;
try {
body = readFileSync(join(FIXTURE_DIR, fileName));
body = readFileSync(fixture.path);
} catch {
response.writeHead(404);
response.end('not found');
return;
}
const contentType = fileName.endsWith('.mpd')
? 'application/dash+xml'
: 'video/mp4';
const range = /bytes=(\d+)-(\d+)?/.exec(
request.headers.range ?? ''
);
const range = /bytes=(\d+)-(\d+)?/.exec(request.headers.range ?? '');
if (!range) {
response.writeHead(200, {
'Content-Type': contentType,
'Content-Type': fixture.contentType,
'Accept-Ranges': 'bytes',
'Access-Control-Allow-Origin': '*',
'Content-Length': body.length,
});
response.end(body);
@@ -64,8 +110,9 @@ async function startDashFixtureServer(): Promise<DashFixtureServer> {
const end = range[2] ? Number(range[2]) : body.length - 1;
const chunk = body.subarray(start, end + 1);
response.writeHead(206, {
'Content-Type': contentType,
'Content-Type': fixture.contentType,
'Accept-Ranges': 'bytes',
'Access-Control-Allow-Origin': '*',
'Content-Range': `bytes ${start}-${end}/${body.length}`,
'Content-Length': chunk.length,
});
@@ -106,6 +153,8 @@ function buildDashPlaylist(origin: string): string {
'#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha',
'#KODIPROP:inputstream.adaptive.license_key=https://license.example.com/wv',
`${origin}/clearkey.mpd`,
'#EXTINF:-1 tvg-id="unsupported-mkv" group-title="DASH",Unsupported MKV',
`${origin}/unsupported.mkv`,
].join('\n');
}
@@ -122,13 +171,179 @@ async function importDashPlaylistFromText(
await waitForM3uCatalog(app.mainWindow);
}
test('@electron @dash ClearKey DASH plays inline and unsupported DRM surfaces a diagnostic', async ({
type ExternalPlayerIpcArguments = [
url: string,
title: string,
thumbnail: string | undefined,
userAgent: string | undefined,
referer: string | undefined,
origin: string | undefined,
contentInfo: PlayerContentInfo | undefined,
startTime: number | undefined,
headers: Record<string, string> | undefined,
];
type CapturedExternalPlayerLaunch = {
args: ExternalPlayerIpcArguments;
player: ExternalPlayerName;
};
type PlaybackRecommendationCaptureSnapshot = {
completed: number;
launches: CapturedExternalPlayerLaunch[];
released: boolean;
};
type PlaybackRecommendationCaptureState =
PlaybackRecommendationCaptureSnapshot & {
releaseFirstResponse: (() => void) | undefined;
waitForFirstResponse: Promise<void>;
};
async function installPlaybackRecommendationLaunchCapture(
app: LaunchedElectronApp
): Promise<void> {
await app.electronApp.evaluate(({ ipcMain }) => {
let releaseFirstResponse: (() => void) | undefined;
const waitForFirstResponse = new Promise<void>((resolve) => {
releaseFirstResponse = resolve;
});
const state: PlaybackRecommendationCaptureState = {
completed: 0,
launches: [],
released: false,
releaseFirstResponse,
waitForFirstResponse,
};
const globalRef = globalThis as typeof globalThis & {
__playbackRecommendationCapture?: PlaybackRecommendationCaptureState;
};
globalRef.__playbackRecommendationCapture = state;
const captureLaunch =
(player: ExternalPlayerName) =>
async (
_event: unknown,
url: string,
title: string,
thumbnail?: string,
userAgent?: string,
referer?: string,
origin?: string,
contentInfo?: PlayerContentInfo,
startTime?: number,
headers?: Record<string, string>
) => {
const invocation = state.launches.push({
args: [
url,
title,
thumbnail,
userAgent,
referer,
origin,
contentInfo,
startTime,
headers,
],
player,
});
if (invocation === 1 && !state.released) {
await state.waitForFirstResponse;
}
state.completed += 1;
const now = new Date().toISOString();
return {
canClose: false,
id: `e2e-recommended-${player}-${invocation}`,
player,
startedAt: now,
status: 'opened',
streamUrl: url,
thumbnail: thumbnail ?? null,
title,
updatedAt: now,
};
};
ipcMain.removeHandler('OPEN_MPV_PLAYER');
ipcMain.removeHandler('OPEN_VLC_PLAYER');
ipcMain.handle('OPEN_MPV_PLAYER', captureLaunch('mpv'));
ipcMain.handle('OPEN_VLC_PLAYER', captureLaunch('vlc'));
});
}
async function getPlaybackRecommendationCapture(
app: LaunchedElectronApp
): Promise<PlaybackRecommendationCaptureSnapshot> {
return app.electronApp.evaluate(() => {
const globalRef = globalThis as typeof globalThis & {
__playbackRecommendationCapture?: PlaybackRecommendationCaptureState;
};
const capture = globalRef.__playbackRecommendationCapture;
if (!capture) {
throw new Error(
'Playback recommendation capture is not installed.'
);
}
return {
completed: capture.completed,
launches: capture.launches,
released: capture.released,
};
});
}
async function releasePlaybackRecommendationCapture(
app: LaunchedElectronApp
): Promise<void> {
await app.electronApp.evaluate(() => {
const globalRef = globalThis as typeof globalThis & {
__playbackRecommendationCapture?: PlaybackRecommendationCaptureState;
};
const capture = globalRef.__playbackRecommendationCapture;
if (!capture || capture.released) {
return;
}
capture.released = true;
capture.releaseFirstResponse?.();
capture.releaseFirstResponse = undefined;
});
}
test('@electron @dash ClearKey DASH filters DRM fallback and eligible MKV opens in MPV', async ({
dataDir,
}) => {
const fixtureServer = await startDashFixtureServer();
const app = await launchElectronApp(dataDir);
try {
const unsupportedFixtureResponse = await app.mainWindow.evaluate(
async (url) => {
const response = await fetch(url);
const body = await response.text();
return {
body,
bodyBytes: new TextEncoder().encode(body).byteLength,
contentLength: response.headers.get('content-length'),
contentType: response.headers.get('content-type'),
rendererProtocol: window.location.protocol,
status: response.status,
};
},
`${fixtureServer.origin}/unsupported.mkv`
);
expect(unsupportedFixtureResponse).toEqual({
body: 'This fixture intentionally declares Matroska without playable media bytes.\n',
bodyBytes: 75,
contentLength: '75',
contentType: 'video/matroska',
rendererProtocol: 'file:',
status: 200,
});
await importDashPlaylistFromText(
app,
buildDashPlaylist(fixtureServer.origin)
@@ -160,12 +375,124 @@ test('@electron @dash ClearKey DASH plays inline and unsupported DRM surfaces a
await channelItemByTitle(app.mainWindow, 'Widevine DASH')
.first()
.click();
const banner = app.mainWindow.getByTestId(
'playback-diagnostic-banner'
);
const banner = app.mainWindow.getByTestId('playback-diagnostic-banner');
await expect(banner).toBeVisible({ timeout: 15_000 });
await expect(banner).toContainText(/encrypted or DRM-protected/i);
await expect(
banner.locator('[data-test-id="playback-fallback-mpv"]')
).toHaveCount(0);
await expect(
banner.locator('[data-test-id="playback-fallback-vlc"]')
).toHaveCount(0);
await expect(
banner.locator('[data-test-id^="playback-recommendation-"]')
).toHaveCount(0);
const widevineDetails = banner.locator(
'[data-test-id="playback-diagnostic-details"]'
);
await widevineDetails.locator('summary').click();
await expect(widevineDetails).toContainText('drm-or-encryption');
await installPlaybackRecommendationLaunchCapture(app);
await channelItemByTitle(app.mainWindow, 'Unsupported MKV')
.first()
.click();
await expect(banner).toContainText(
/container is likely unsupported by the browser player/i,
{ timeout: 15_000 }
);
const mkvDetails = banner.locator(
'[data-test-id="playback-diagnostic-details"]'
);
await mkvDetails.locator('summary').click();
await expect(mkvDetails).toContainText('unsupported-container');
const mpvFallback = banner.locator(
'[data-test-id="playback-fallback-mpv"]'
);
const vlcFallback = banner.locator(
'[data-test-id="playback-fallback-vlc"]'
);
await expect(mpvFallback).toBeVisible();
await expect(vlcFallback).toBeVisible();
await expect(mpvFallback).toHaveClass(
/web-player-diagnostic__player-card--primary/
);
await expect(vlcFallback).not.toHaveClass(
/web-player-diagnostic__player-card--primary/
);
const expectedLaunches = [
{
args: [
`${fixtureServer.origin}/unsupported.mkv`,
'Unsupported MKV',
'',
'',
'',
undefined,
undefined,
undefined,
undefined,
],
player: 'mpv',
},
] satisfies CapturedExternalPlayerLaunch[];
expect(await getPlaybackRecommendationCapture(app)).toEqual({
completed: 0,
launches: [],
released: false,
});
await mpvFallback.click();
await expect
.poll(() => getPlaybackRecommendationCapture(app), {
timeout: 10_000,
})
.toEqual({
completed: 0,
launches: expectedLaunches,
released: false,
});
expect(
(await getPlaybackRecommendationCapture(app)).launches.filter(
({ player }) => player === 'vlc'
)
).toHaveLength(0);
await expect(mpvFallback).toHaveCount(0);
await expect(vlcFallback).toHaveClass(
/web-player-diagnostic__player-card--primary/
);
await releasePlaybackRecommendationCapture(app);
await expect
.poll(() => getPlaybackRecommendationCapture(app), {
timeout: 10_000,
})
.toEqual({
completed: 1,
launches: expectedLaunches,
released: true,
});
await app.mainWindow.evaluate(
() =>
new Promise<void>((resolve) => {
requestAnimationFrame(() =>
requestAnimationFrame(() => resolve())
);
})
);
expect(await getPlaybackRecommendationCapture(app)).toEqual({
completed: 1,
launches: expectedLaunches,
released: true,
});
await expect(mpvFallback).toHaveCount(0);
await expect(vlcFallback).toHaveClass(
/web-player-diagnostic__player-card--primary/
);
} finally {
await releasePlaybackRecommendationCapture(app).catch(() => undefined);
await closeElectronApp(app);
await fixtureServer.close();
}
+3
View File
@@ -2,6 +2,9 @@ import playwright from 'eslint-plugin-playwright';
import baseConfig from '../../eslint.config.mjs';
export default [
{
ignores: ['**/fixtures/playback/corrupt.ts'],
},
playwright.configs['flat/recommended'],
...baseConfig,
{
+9
View File
@@ -150,4 +150,13 @@ test('@web @m3u @dash unsupported DRM shows the encryption diagnostic', async ({
const banner = page.locator('[data-test-id="playback-diagnostic-banner"]');
await expect(banner).toBeVisible({ timeout: 15_000 });
await expect(banner).toContainText(/encrypted or DRM-protected/i);
await expect(
banner.locator('[data-test-id="playback-fallback-mpv"]')
).toHaveCount(0);
await expect(
banner.locator('[data-test-id="playback-fallback-vlc"]')
).toHaveCount(0);
await expect(
banner.locator('[data-test-id^="playback-recommendation-"]')
).toHaveCount(0);
});
@@ -0,0 +1 @@
This is intentionally not an MPEG transport stream segment.
@@ -0,0 +1,7 @@
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:1
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:1,
corrupt.ts
#EXT-X-ENDLIST
@@ -0,0 +1 @@
This fixture intentionally declares Matroska without playable media bytes.
@@ -0,0 +1,141 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import type { Page } from '@playwright/test';
import { expect, test } from './fixtures';
const FIXTURE_DIR = join(__dirname, 'fixtures/playback');
const FIXTURE_HOST = 'https://playback-fixture.local';
const FATAL_HLS_PLAYLIST = [
'#EXTM3U',
'#EXTINF:-1 tvg-id="fatal-hls" group-title="Playback",Fatal HLS',
`${FIXTURE_HOST}/fatal-media.m3u8`,
].join('\n');
const PLAYBACK_FIXTURES = new Map([
[
'/fatal-media.m3u8',
{
body: readFileSync(join(FIXTURE_DIR, 'fatal-media.m3u8')),
contentType: 'application/vnd.apple.mpegurl',
},
],
[
'/corrupt.ts',
{
body: readFileSync(join(FIXTURE_DIR, 'corrupt.ts')),
contentType: 'video/mp2t',
},
],
]);
test.use({
launchOptions: {
args: ['--autoplay-policy=no-user-gesture-required'],
},
serviceWorkers: 'block',
});
test.skip(
({ browserName }) => browserName !== 'chromium',
'HLS recovery coverage targets Chromium'
);
async function servePlaybackFixtures(page: Page): Promise<void> {
await page.route(`${FIXTURE_HOST}/**`, async (route) => {
const fixture = PLAYBACK_FIXTURES.get(
new URL(route.request().url()).pathname
);
if (!fixture) {
await route.fulfill({
status: 404,
contentType: 'text/plain',
body: 'not found',
});
return;
}
await route.fulfill({
status: 200,
contentType: fixture.contentType,
body: fixture.body,
});
});
}
async function openSettings(page: Page): Promise<void> {
await page.getByRole('link', { name: 'Open settings' }).click();
await page.waitForURL(/\/workspace\/settings$/);
await expect(
page.getByRole('button', { name: 'Back', exact: true })
).toBeVisible();
}
async function selectAndSaveHtml5(page: Page): Promise<void> {
const playerSelect = page.locator('[data-test-id="select-video-player"]');
await playerSelect.click();
await page
.getByRole('option', { name: 'HTML5 video player', exact: true })
.click();
const saveButton = page.getByRole('button', { name: 'Save changes' });
await saveButton.click();
await expect(saveButton).toBeDisabled();
}
async function importFatalHlsPlaylist(page: Page): Promise<void> {
await page.getByRole('button', { name: 'Add playlist' }).click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await dialog.getByRole('radio', { name: /Raw m3u text/i }).click();
await dialog
.getByLabel('Insert m3u(8) playlist as text')
.fill(FATAL_HLS_PLAYLIST);
await Promise.all([
page.waitForURL(/\/workspace\/playlists\/.+\/all$/),
dialog.getByRole('button', { name: 'Import', exact: true }).click(),
]);
await expect(page.getByText('1 channel')).toBeVisible();
}
test('@web @m3u @playback temporarily switches to the recommended player', async ({
page,
}) => {
await servePlaybackFixtures(page);
await page.goto('/');
await openSettings(page);
await selectAndSaveHtml5(page);
await page.getByRole('button', { name: 'Back', exact: true }).click();
await page.waitForURL(/\/workspace\/dashboard$/);
await importFatalHlsPlaylist(page);
await page.getByText('1. Fatal HLS', { exact: true }).click();
const banner = page.locator('[data-test-id="playback-diagnostic-banner"]');
const videoJsRecommendation = page.locator(
'[data-test-id="playback-recommendation-videojs"]'
);
await expect(banner).toBeVisible({ timeout: 15_000 });
await expect(
banner.locator('[data-test-id="playback-diagnostic-details"]')
).toContainText(
/HLS\.js[\s\S]*type=mediaError[\s\S]*details=fragParsingError[\s\S]*disposition=fatal/
);
await expect(videoJsRecommendation).toBeVisible();
await expect(videoJsRecommendation).toHaveClass(
/web-player-diagnostic__player-card--primary/
);
await videoJsRecommendation.click();
await expect(page.locator('app-vjs-player')).toBeVisible();
await openSettings(page);
await page.reload();
await expect(page).toHaveURL(/\/workspace\/settings$/);
const persistedPlayerSelect = page.locator(
'[data-test-id="select-video-player"]'
);
await expect(persistedPlayerSelect).toBeVisible();
await expect(persistedPlayerSelect).toBeEnabled();
await expect(persistedPlayerSelect).toHaveText('HTML5 video player');
});
+2 -1
View File
@@ -17,5 +17,6 @@
"playwright.config.ts",
"src/**/*.d.ts",
"src/**/*.e2e.ts"
]
],
"exclude": ["src/fixtures/playback/corrupt.ts"]
}
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "مؤقت لهذا العنصر؛ سيبقى المشغل المحفوظ دون تغيير",
"REASON_RETRY_TRANSIENT_FAILURE": "أعد المحاولة بنفس المشغل بعد فشل مؤقت في التحميل",
"REASON_RETRY_UNKNOWN_FAILURE": "أعد المحاولة لأن الخطأ لم يحدد مشغلًا آخر متوافقًا",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "جرّب مصدرًا آخر متاحًا للمحتوى نفسه",
"REASON_DIFFERENT_ENGINE_FAMILY": "يستخدم هذا المشغل محرك تشغيل مختلفًا في المتصفح",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "تدعم المشغلات الأصلية مزيدًا من برامج الترميز والحاويات",
"REASON_EXTERNAL_BROWSER_ACCESS": "قد يتجاوز المشغل الأصلي قيود الوصول في المتصفح",
"REASON_COMPATIBLE_DRM_PATH": "هذا الهدف متوافق مع بيانات التشفير المتاحة",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "مؤقت غير لهاد المحتوى؛ المشغل المحفوظ غيبقى بلا تغيير",
"REASON_RETRY_TRANSIENT_FAILURE": "عاود جرّب نفس المشغل من بعد مشكل مؤقت فالتحميل",
"REASON_RETRY_UNKNOWN_FAILURE": "عاود جرّب حيث الخطأ ما حدّد حتى مشغل آخر متوافق",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "جرّب مصدر آخر متوفر لنفس المحتوى",
"REASON_DIFFERENT_ENGINE_FAMILY": "هاد المشغل كيستعمل محرك تشغيل مختلف فالمتصفح",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "المشغلات الأصلية كتدعم كوديكات وحاويات أكثر",
"REASON_EXTERNAL_BROWSER_ACCESS": "يقدر مشغل أصلي يتجاوز قيود الولوج ديال المتصفح",
"REASON_COMPATIBLE_DRM_PATH": "هاد الهدف متوافق مع بيانات التشفير المتوفرة",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "Часова толькі для гэтага элемента; захаваны плэер не зменіцца",
"REASON_RETRY_TRANSIENT_FAILURE": "Паўтарыць у тым жа плэеры пасля часовага збою загрузкі",
"REASON_RETRY_UNKNOWN_FAILURE": "Паўтарыць, бо памылка не вызначыла іншы сумяшчальны плэер",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Паспрабаваць іншую даступную крыніцу таго ж змесціва",
"REASON_DIFFERENT_ENGINE_FAMILY": "Гэты плэер выкарыстоўвае іншы рухавік прайгравання ў браўзеры",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Сістэмныя плэеры падтрымліваюць больш кодэкаў і кантэйнераў",
"REASON_EXTERNAL_BROWSER_ACCESS": "Сістэмны плэер можа абысці абмежаванні доступу браўзера",
"REASON_COMPATIBLE_DRM_PATH": "Гэтая мэта сумяшчальная з даступнымі данымі шыфравання",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Nach einem vorübergehenden Ladefehler denselben Player erneut versuchen",
"REASON_RETRY_UNKNOWN_FAILURE": "Erneut versuchen, da der Fehler keinen anderen kompatiblen Player erkennen ließ",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Eine andere verfügbare Quelle für denselben Inhalt ausprobieren",
"REASON_DIFFERENT_ENGINE_FAMILY": "Dieser Player verwendet eine andere Browser-Wiedergabe-Engine",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Native Player unterstützen mehr Codecs und Container",
"REASON_EXTERNAL_BROWSER_ACCESS": "Ein nativer Player kann Zugriffsbeschränkungen des Browsers umgehen",
"REASON_COMPATIBLE_DRM_PATH": "Dieses Ziel ist mit den verfügbaren Verschlüsselungsdaten kompatibel",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "Προσωρινά για αυτό το στοιχείο· το αποθηκευμένο πρόγραμμα αναπαραγωγής δεν αλλάζει",
"REASON_RETRY_TRANSIENT_FAILURE": "Δοκιμάστε ξανά το ίδιο πρόγραμμα αναπαραγωγής μετά από μια προσωρινή αποτυχία φόρτωσης",
"REASON_RETRY_UNKNOWN_FAILURE": "Δοκιμάστε ξανά, επειδή το σφάλμα δεν εντόπισε άλλο συμβατό πρόγραμμα αναπαραγωγής",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Δοκιμάστε μια άλλη διαθέσιμη πηγή για το ίδιο περιεχόμενο",
"REASON_DIFFERENT_ENGINE_FAMILY": "Αυτό το πρόγραμμα αναπαραγωγής χρησιμοποιεί διαφορετική μηχανή αναπαραγωγής του προγράμματος περιήγησης",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Τα εγγενή προγράμματα αναπαραγωγής υποστηρίζουν περισσότερους κωδικοποιητές και περιέκτες",
"REASON_EXTERNAL_BROWSER_ACCESS": "Ένα εγγενές πρόγραμμα αναπαραγωγής μπορεί να παρακάμψει περιορισμούς πρόσβασης του προγράμματος περιήγησης",
"REASON_COMPATIBLE_DRM_PATH": "Αυτός ο στόχος είναι συμβατός με τα διαθέσιμα δεδομένα κρυπτογράφησης",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Retry the same player after a temporary loading failure",
"REASON_RETRY_UNKNOWN_FAILURE": "Retry because the failure did not identify another compatible player",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Try another available source for the same content",
"REASON_DIFFERENT_ENGINE_FAMILY": "This player uses a different browser playback engine",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Native players support more codecs and containers",
"REASON_EXTERNAL_BROWSER_ACCESS": "A native player may avoid browser access restrictions",
"REASON_COMPATIBLE_DRM_PATH": "This target is compatible with the available encryption data",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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á",
"REASON_RETRY_TRANSIENT_FAILURE": "Reintentar con el mismo reproductor tras un fallo temporal de carga",
"REASON_RETRY_UNKNOWN_FAILURE": "Reintentar porque el error no identificó otro reproductor compatible",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Probar otra fuente disponible para el mismo contenido",
"REASON_DIFFERENT_ENGINE_FAMILY": "Este reproductor usa un motor de reproducción distinto del navegador",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Los reproductores nativos admiten más códecs y contenedores",
"REASON_EXTERNAL_BROWSER_ACCESS": "Un reproductor nativo puede evitar las restricciones de acceso del navegador",
"REASON_COMPATIBLE_DRM_PATH": "Este destino es compatible con los datos de cifrado disponibles",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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é",
"REASON_RETRY_TRANSIENT_FAILURE": "Réessayer avec le même lecteur après un échec temporaire de chargement",
"REASON_RETRY_UNKNOWN_FAILURE": "Réessayer, car l’erreur n’a identifié aucun autre lecteur compatible",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Essayer une autre source disponible pour le même contenu",
"REASON_DIFFERENT_ENGINE_FAMILY": "Ce lecteur utilise un autre moteur de lecture du navigateur",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Les lecteurs natifs prennent en charge davantage de codecs et de conteneurs",
"REASON_EXTERNAL_BROWSER_ACCESS": "Un lecteur natif peut contourner les restrictions d’accès du navigateur",
"REASON_COMPATIBLE_DRM_PATH": "Cette cible est compatible avec les données de chiffrement disponibles",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "A böngészőben működő lejátszó a jelzett titkosítási vagy kulcshiba miatt nem tudja folytatni a lejátszást. Ha a szolgáltató DRM-védelmet alkalmaz, a külső lejátszás is sikertelen lehet."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Ugyanannak a lejátszónak az újrapróbálása ideiglenes betöltési hiba után",
"REASON_RETRY_UNKNOWN_FAILURE": "Újrapróbálás, mert a hiba nem azonosított más kompatibilis lejátszót",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Másik elérhető forrás kipróbálása ugyanahhoz a tartalomhoz",
"REASON_DIFFERENT_ENGINE_FAMILY": "Ez a lejátszó más böngészős lejátszómotort használ",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "A natív lejátszók több kodeket és konténert támogatnak",
"REASON_EXTERNAL_BROWSER_ACCESS": "Egy natív lejátszó megkerülheti a böngésző hozzáférési korlátozásait",
"REASON_COMPATIBLE_DRM_PATH": "Ez a cél kompatibilis az elérhető titkosítási adatokkal",
"ACTION_OPEN_MPV": "Megnyitás MPV-ben",
"ACTION_OPEN_VLC": "Megnyitás VLC-ben",
"ACTION_OPEN_MPV_HINT": "beállított lejátszó",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Riprova con lo stesso lettore dopo un errore temporaneo di caricamento",
"REASON_RETRY_UNKNOWN_FAILURE": "Riprova perché l’errore non ha identificato un altro lettore compatibile",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Prova un’altra fonte disponibile per lo stesso contenuto",
"REASON_DIFFERENT_ENGINE_FAMILY": "Questo lettore usa un motore di riproduzione del browser diverso",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "I lettori nativi supportano più codec e contenitori",
"REASON_EXTERNAL_BROWSER_ACCESS": "Un lettore nativo può evitare le restrizioni di accesso del browser",
"REASON_COMPATIBLE_DRM_PATH": "Questa destinazione è compatibile con i dati di crittografia disponibili",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "この項目にのみ一時的に適用され、保存済みのプレーヤーは変更されません",
"REASON_RETRY_TRANSIENT_FAILURE": "一時的な読み込みエラーの後、同じプレーヤーで再試行します",
"REASON_RETRY_UNKNOWN_FAILURE": "エラーから別の互換プレーヤーを特定できなかったため、再試行します",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "同じコンテンツで利用可能な別のソースを試します",
"REASON_DIFFERENT_ENGINE_FAMILY": "このプレーヤーは別のブラウザー再生エンジンを使用します",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "ネイティブプレーヤーはより多くのコーデックとコンテナに対応しています",
"REASON_EXTERNAL_BROWSER_ACCESS": "ネイティブプレーヤーならブラウザーのアクセス制限を回避できる場合があります",
"REASON_COMPATIBLE_DRM_PATH": "この対象は利用可能な暗号化データに対応しています",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "이 항목에만 임시로 적용되며 저장된 플레이어는 변경되지 않습니다",
"REASON_RETRY_TRANSIENT_FAILURE": "일시적인 로드 실패 후 같은 플레이어로 다시 시도합니다",
"REASON_RETRY_UNKNOWN_FAILURE": "오류에서 다른 호환 플레이어를 확인할 수 없어 다시 시도합니다",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "같은 콘텐츠에 사용 가능한 다른 소스를 시도합니다",
"REASON_DIFFERENT_ENGINE_FAMILY": "이 플레이어는 다른 브라우저 재생 엔진을 사용합니다",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "네이티브 플레이어는 더 많은 코덱과 컨테이너를 지원합니다",
"REASON_EXTERNAL_BROWSER_ACCESS": "네이티브 플레이어는 브라우저 접근 제한을 피할 수 있습니다",
"REASON_COMPATIBLE_DRM_PATH": "이 대상은 사용 가능한 암호화 데이터와 호환됩니다",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Dezelfde speler opnieuw proberen na een tijdelijke laadfout",
"REASON_RETRY_UNKNOWN_FAILURE": "Opnieuw proberen omdat de fout geen andere compatibele speler heeft vastgesteld",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Een andere beschikbare bron voor dezelfde inhoud proberen",
"REASON_DIFFERENT_ENGINE_FAMILY": "Deze speler gebruikt een andere afspeelengine in de browser",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Systeemeigen spelers ondersteunen meer codecs en containers",
"REASON_EXTERNAL_BROWSER_ACCESS": "Een systeemeigen speler kan toegangsbeperkingen van de browser omzeilen",
"REASON_COMPATIBLE_DRM_PATH": "Dit doel is compatibel met de beschikbare versleutelingsgegevens",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Ponów próbę w tym samym odtwarzaczu po tymczasowym błędzie wczytywania",
"REASON_RETRY_UNKNOWN_FAILURE": "Ponów próbę, ponieważ błąd nie wskazał innego zgodnego odtwarzacza",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Wypróbuj inne dostępne źródło tej samej treści",
"REASON_DIFFERENT_ENGINE_FAMILY": "Ten odtwarzacz używa innego silnika odtwarzania w przeglądarce",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Natywne odtwarzacze obsługują więcej kodeków i kontenerów",
"REASON_EXTERNAL_BROWSER_ACCESS": "Natywny odtwarzacz może ominąć ograniczenia dostępu przeglądarki",
"REASON_COMPATIBLE_DRM_PATH": "Ten cel jest zgodny z dostępnymi danymi szyfrowania",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Tentar novamente com o mesmo reprodutor após uma falha temporária de carregamento",
"REASON_RETRY_UNKNOWN_FAILURE": "Tentar novamente porque o erro não identificou outro reprodutor compatível",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Experimentar outra fonte disponível para o mesmo conteúdo",
"REASON_DIFFERENT_ENGINE_FAMILY": "Este reprodutor usa um mecanismo de reprodução diferente no navegador",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Os reprodutores nativos oferecem suporte a mais codecs e contêineres",
"REASON_EXTERNAL_BROWSER_ACCESS": "Um reprodutor nativo pode contornar as restrições de acesso do navegador",
"REASON_COMPATIBLE_DRM_PATH": "Este destino é compatível com os dados de criptografia disponíveis",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"DESCRIPTION": "Запрос может быть заблокирован CORS, mixed content или требованиями провайдера/прокси к заголовкам. MPV или VLC часто обходят такие ограничения браузерного плеера.",
"PWA_DESCRIPTION": "Запрос может быть заблокирован CORS, mixed content или требованиями провайдера/прокси к заголовкам. PWA не может запускать внешние плееры напрямую: нажмите «Скопировать URL потока» и откройте его вручную в MPV, VLC, IINA или другом плеере."
},
"UNTRANSFERABLE_DESCRIPTION": "Для этого защищённого потока требуются настройки воспроизведения, которые нельзя передать вместе с URL-адресом потока.",
"DRM_OR_ENCRYPTION": {
"TITLE": "Поток может быть зашифрован или защищен DRM",
"DESCRIPTION": "Браузерный плеер не может продолжить из-за ошибки ключа или шифрования. Внешний плеер тоже может не помочь, если требуется DRM провайдера."
@@ -561,6 +562,17 @@
},
"NATIVE_FALLBACK_TITLE": "Откройте поток во внешнем плеере",
"INLINE_FAILURE_TITLE": "Скопируйте URL или повторите попытку",
"UNTRANSFERABLE_FAILURE_TITLE": "Не удалось продолжить защищённое воспроизведение",
"RECOMMENDATIONS_LABEL": "Рекомендуемые действия для восстановления",
"ACTION_TRY_PLAYER": "Попробовать {{player}}",
"ACTION_TRY_PLAYER_HINT": "Временно только для этого элемента; сохранённый плеер не изменится",
"REASON_RETRY_TRANSIENT_FAILURE": "Повторить в том же плеере после временной ошибки загрузки",
"REASON_RETRY_UNKNOWN_FAILURE": "Повторить, поскольку ошибка не указала другой совместимый плеер",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Попробовать другой доступный источник того же контента",
"REASON_DIFFERENT_ENGINE_FAMILY": "Этот плеер использует другой движок воспроизведения в браузере",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Нативные плееры поддерживают больше кодеков и контейнеров",
"REASON_EXTERNAL_BROWSER_ACCESS": "Нативный плеер может обойти ограничения доступа браузера",
"REASON_COMPATIBLE_DRM_PATH": "Эта цель совместима с доступными данными шифрования",
"ACTION_OPEN_MPV": "Открыть в MPV",
"ACTION_OPEN_VLC": "Открыть в VLC",
"ACTION_OPEN_MPV_HINT": "настроенный плеер",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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",
"REASON_RETRY_TRANSIENT_FAILURE": "Geçici bir yükleme hatasından sonra aynı oynatıcıyla yeniden deneyin",
"REASON_RETRY_UNKNOWN_FAILURE": "Hata başka bir uyumlu oynatıcı belirlemediği için yeniden deneyin",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "Aynı içerik için kullanılabilir başka bir kaynak deneyin",
"REASON_DIFFERENT_ENGINE_FAMILY": "Bu oynatıcı farklı bir tarayıcı oynatma motoru kullanır",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "Yerel oynatıcılar daha fazla codec bileşenini ve kapsayıcıyı destekler",
"REASON_EXTERNAL_BROWSER_ACCESS": "Yerel bir oynatıcı tarayıcı erişim kısıtlamalarını aşabilir",
"REASON_COMPATIBLE_DRM_PATH": "Bu hedef kullanılabilir şifreleme verileriyle uyumludur",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "仅临时用于此项目;已保存的播放器不会更改",
"REASON_RETRY_TRANSIENT_FAILURE": "临时加载失败后使用同一播放器重试",
"REASON_RETRY_UNKNOWN_FAILURE": "重试,因为该错误未能确定其他兼容的播放器",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "为同一内容尝试其他可用源",
"REASON_DIFFERENT_ENGINE_FAMILY": "此播放器使用不同的浏览器播放引擎",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "原生播放器支持更多编解码器和容器",
"REASON_EXTERNAL_BROWSER_ACCESS": "原生播放器可以避开浏览器访问限制",
"REASON_COMPATIBLE_DRM_PATH": "此目标与可用的加密数据兼容",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",
+12
View File
@@ -551,6 +551,7 @@
"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."
},
"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",
"DESCRIPTION": "The browser player cannot continue with the reported encryption/key error. External playback may still fail if provider DRM is required."
@@ -561,6 +562,17 @@
},
"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": "僅暫時套用於此項目;已儲存的播放器不會變更",
"REASON_RETRY_TRANSIENT_FAILURE": "暫時載入失敗後使用相同的播放器重試",
"REASON_RETRY_UNKNOWN_FAILURE": "重試,因為此錯誤未能識別其他相容的播放器",
"REASON_ALTERNATIVE_SOURCE_AVAILABLE": "為相同內容嘗試其他可用來源",
"REASON_DIFFERENT_ENGINE_FAMILY": "此播放器使用不同的瀏覽器播放引擎",
"REASON_EXTERNAL_CODEC_OR_CONTAINER_SUPPORT": "原生播放器支援更多編解碼器和容器",
"REASON_EXTERNAL_BROWSER_ACCESS": "原生播放器可以避開瀏覽器存取限制",
"REASON_COMPATIBLE_DRM_PATH": "此目標與可用的加密資料相容",
"ACTION_OPEN_MPV": "Open in MPV",
"ACTION_OPEN_VLC": "Open in VLC",
"ACTION_OPEN_MPV_HINT": "configured player",