diff --git a/apps/electron-backend/src/app/events/player.events.spec.ts b/apps/electron-backend/src/app/events/player.events.spec.ts index d8d2e71b4..e04241c92 100644 --- a/apps/electron-backend/src/app/events/player.events.spec.ts +++ b/apps/electron-backend/src/app/events/player.events.spec.ts @@ -35,8 +35,10 @@ import { } from '../services/store.service'; import { buildExternalPlayerSpawnSpec, + buildPlayerArgsWithCustomArguments, buildVlcEnqueueCommands, isRunningInFlatpak, + parseExternalPlayerArguments, parseVlcRcPlaybackState, parseVlcRcNumericResponse, resolveExternalPlayerLaunchContext, @@ -67,21 +69,25 @@ function getIpcMainHandler(channel: string): (...args: unknown[]) => unknown { describe('player.events Flatpak launch helpers', () => { it('detects Flatpak only on Linux when /.flatpak-info exists', () => { - expect(isRunningInFlatpak(createPathExists(['/.flatpak-info']), 'linux')).toBe( - true - ); - expect(isRunningInFlatpak(createPathExists(['/.flatpak-info']), 'darwin')).toBe( - false - ); + expect( + isRunningInFlatpak(createPathExists(['/.flatpak-info']), 'linux') + ).toBe(true); + expect( + isRunningInFlatpak(createPathExists(['/.flatpak-info']), 'darwin') + ).toBe(false); expect(isRunningInFlatpak(createPathExists([]), 'linux')).toBe(false); }); it('keeps direct Linux player launching outside Flatpak', () => { - const launchContext = resolveExternalPlayerLaunchContext('mpv', undefined, { - platform: 'linux', - isFlatpak: false, - pathExists: createPathExists(['/usr/local/bin/mpv']), - }); + const launchContext = resolveExternalPlayerLaunchContext( + 'mpv', + undefined, + { + platform: 'linux', + isFlatpak: false, + pathExists: createPathExists(['/usr/local/bin/mpv']), + } + ); const spawnSpec = buildExternalPlayerSpawnSpec(launchContext, [ '--ytdl=no', 'https://example.com/stream.m3u8', @@ -102,11 +108,15 @@ describe('player.events Flatpak launch helpers', () => { }); it('builds Flatpak host launches with bare player names by default', () => { - const launchContext = resolveExternalPlayerLaunchContext('vlc', undefined, { - platform: 'linux', - isFlatpak: true, - pathExists: createPathExists(['/usr/bin/vlc']), - }); + const launchContext = resolveExternalPlayerLaunchContext( + 'vlc', + undefined, + { + platform: 'linux', + isFlatpak: true, + pathExists: createPathExists(['/usr/bin/vlc']), + } + ); const spawnSpec = buildExternalPlayerSpawnSpec(launchContext, [ '--extraintf=rc', 'https://example.com/stream.m3u8', @@ -199,6 +209,38 @@ describe('player.events Flatpak launch helpers', () => { }); }); + it('parses custom player arguments as one argument per non-empty line', () => { + expect( + parseExternalPlayerArguments( + ' --screen=1\n\n--geometry=1280x720\r\n --hwdec=auto-safe ' + ) + ).toEqual(['--screen=1', '--geometry=1280x720', '--hwdec=auto-safe']); + }); + + it('treats missing custom player arguments as no arguments', () => { + expect(parseExternalPlayerArguments(undefined)).toEqual([]); + expect(parseExternalPlayerArguments(' \n ')).toEqual([]); + }); + + it('adds custom player arguments before IPTVnator runtime arguments', () => { + expect( + buildPlayerArgsWithCustomArguments( + '--screen=1\n--geometry=1280x720', + [ + '--ytdl=no', + '--force-media-title=News', + 'https://example.com/stream.m3u8', + ] + ) + ).toEqual([ + '--screen=1', + '--geometry=1280x720', + '--ytdl=no', + '--force-media-title=News', + 'https://example.com/stream.m3u8', + ]); + }); + it('disables MPV reuse and socket bridging only in Flatpak', () => { expect(shouldReuseMpvInstance(true, true)).toBe(false); expect(shouldUseMpvSocketBridge(true)).toBe(false); @@ -315,9 +357,7 @@ describe('buildVlcEnqueueCommands', () => { origin: 'https://origin.example', }); - expect(commands[1]).toContain( - ':http-referrer=https://origin.example' - ); + expect(commands[1]).toContain(':http-referrer=https://origin.example'); }); it('appends a seek command when startTime is provided', () => { diff --git a/apps/electron-backend/src/app/events/player.events.ts b/apps/electron-backend/src/app/events/player.events.ts index 93c7522d6..20aea4bcd 100644 --- a/apps/electron-backend/src/app/events/player.events.ts +++ b/apps/electron-backend/src/app/events/player.events.ts @@ -7,9 +7,11 @@ import { } from 'shared-interfaces'; import App from '../app'; import { + MPV_PLAYER_ARGUMENTS, MPV_PLAYER_PATH, MPV_REUSE_INSTANCE, store, + VLC_PLAYER_ARGUMENTS, VLC_PLAYER_PATH, VLC_REUSE_INSTANCE, } from '../services/store.service'; @@ -43,7 +45,10 @@ interface ExternalPlaybackSnapshot { function sendExternalPlayerSessionUpdate(session: ExternalPlayerSession) { if (App.mainWindow && !App.mainWindow.isDestroyed()) { - App.mainWindow.webContents.send(EXTERNAL_PLAYER_SESSION_UPDATE, session); + App.mainWindow.webContents.send( + EXTERNAL_PLAYER_SESSION_UPDATE, + session + ); } } @@ -202,6 +207,28 @@ export function buildExternalPlayerSpawnSpec( }; } +export function parseExternalPlayerArguments( + value: string | string[] | null | undefined +): string[] { + if (Array.isArray(value)) { + return value.map((argument) => argument.trim()).filter(Boolean); + } + + return ( + value + ?.split(/\r?\n/) + .map((argument) => argument.trim()) + .filter(Boolean) ?? [] + ); +} + +export function buildPlayerArgsWithCustomArguments( + customArguments: string | string[] | null | undefined, + playerArgs: string[] +): string[] { + return [...parseExternalPlayerArguments(customArguments), ...playerArgs]; +} + export function shouldReuseMpvInstance( requestedReuseInstance: boolean, isFlatpak: boolean = isRunningInFlatpak() @@ -504,8 +531,10 @@ function isStalkerDirectStreamProfile( const icyMetaData = headers['Icy-MetaData'] ?? headers['icy-metadata']; const userAgent = headers['User-Agent'] ?? headers['user-agent']; - return String(icyMetaData).trim() === '1' && - String(userAgent).trim().toLowerCase() === 'ksplayer'; + return ( + String(icyMetaData).trim() === '1' && + String(userAgent).trim().toLowerCase() === 'ksplayer' + ); } function startPositionPolling( @@ -592,9 +621,7 @@ async function getVlcProperty(port: number, command: string): Promise { } async function getVlcPlaybackState(port: number): Promise { - return parseVlcRcPlaybackState( - await getVlcCommandResponse(port, 'status') - ); + return parseVlcRcPlaybackState(await getVlcCommandResponse(port, 'status')); } async function getVlcPlaybackSnapshot( @@ -661,7 +688,10 @@ function startVlcPositionPolling( } // Helper function to send command to MPV via IPC -function sendMpvCommand(command: string, args: Array): Promise { +function sendMpvCommand( + command: string, + args: Array +): Promise { return new Promise((resolve, reject) => { if (!mpvSocketPath) { reject(new Error('No MPV socket path available')); @@ -715,6 +745,7 @@ ipcMain.handle( getMpvPath({ isFlatpak }), { isFlatpak } ); + const customMpvArguments = store.get(MPV_PLAYER_ARGUMENTS, ''); const requestedReuseInstance = store.get(MPV_REUSE_INSTANCE, false); const reuseInstance = shouldReuseMpvInstance( requestedReuseInstance, @@ -760,6 +791,8 @@ ipcMain.handle( headerCount: headerFields.length, hasContentInfo: Boolean(contentInfo), startTime: startTime ?? null, + customArgumentCount: + parseExternalPlayerArguments(customMpvArguments).length, }); // If reuse is enabled and there's an existing process, try to use it @@ -810,15 +843,18 @@ ipcMain.handle( 'Successfully loaded new URL in existing MPV instance' ); - externalPlayerSessions.attachCloser(session.id, async () => { - try { - await sendMpvCommand('quit', []); - } catch { - if (mpvProcess && !mpvProcess.killed) { - mpvProcess.kill(); + externalPlayerSessions.attachCloser( + session.id, + async () => { + try { + await sendMpvCommand('quit', []); + } catch { + if (mpvProcess && !mpvProcess.killed) { + mpvProcess.kill(); + } } } - }); + ); // Seek if startTime provided if (startTime) { @@ -904,7 +940,7 @@ ipcMain.handle( await new Promise((resolve, reject) => { const spawnSpec = buildExternalPlayerSpawnSpec( mpvLaunchContext, - args + buildPlayerArgsWithCustomArguments(customMpvArguments, args) ); const proc = spawn(spawnSpec.command, spawnSpec.args, { shell: false, @@ -1114,10 +1150,8 @@ ipcMain.handle( getVlcPath({ isFlatpak }), { isFlatpak } ); - const requestedReuseInstance = store.get( - VLC_REUSE_INSTANCE, - false - ); + const customVlcArguments = store.get(VLC_PLAYER_ARGUMENTS, ''); + const requestedReuseInstance = store.get(VLC_REUSE_INSTANCE, false); const reuseInstance = shouldReuseVlcInstance( requestedReuseInstance, isFlatpak @@ -1155,6 +1189,8 @@ ipcMain.handle( hasOrigin: Boolean(effectiveOrigin), hasContentInfo: Boolean(contentInfo), startTime: startTime ?? null, + customArgumentCount: + parseExternalPlayerArguments(customVlcArguments).length, }); // Try to drive an already-running VLC via its RC port instead of @@ -1316,7 +1352,10 @@ ipcMain.handle( const spawnVlc = (playerArgs: string[], isRetry = false) => { const spawnSpec = buildExternalPlayerSpawnSpec( vlcLaunchContext, - playerArgs + buildPlayerArgsWithCustomArguments( + customVlcArguments, + playerArgs + ) ); const trackProcess = reuseInstance && !isRetry; const proc = spawn(spawnSpec.command, spawnSpec.args, { @@ -1338,8 +1377,8 @@ ipcMain.handle( const markVlcSessionClosed = () => { if ( - externalPlayerSessions.getSession(session.id)?.status === - 'closed' + externalPlayerSessions.getSession(session.id) + ?.status === 'closed' ) { return; } @@ -1375,27 +1414,30 @@ ipcMain.handle( ); }; - externalPlayerSessions.attachCloser(session.id, async () => { - await flushVlcPlaybackPosition(); - if (!proc.killed) { - proc.kill(); + externalPlayerSessions.attachCloser( + session.id, + async () => { + await flushVlcPlaybackPosition(); + if (!proc.killed) { + proc.kill(); + } } - }); + ); // Start polling if we have port and content info and NOT retrying (RC disabled on retry) - if (!isRetry && rcPort > 0 && contentInfo) { - startVlcPositionPolling( - rcPort, - contentInfo, - session.id, - (snapshot) => { - lastVlcSnapshot = snapshot; - }, - () => { - markVlcSessionClosed(); - } - ); - } + if (!isRetry && rcPort > 0 && contentInfo) { + startVlcPositionPolling( + rcPort, + contentInfo, + session.id, + (snapshot) => { + lastVlcSnapshot = snapshot; + }, + () => { + markVlcSessionClosed(); + } + ); + } // Capture stdout if (proc.stdout) { diff --git a/apps/electron-backend/src/app/events/settings.events.ts b/apps/electron-backend/src/app/events/settings.events.ts index 322d5720f..2216cd691 100644 --- a/apps/electron-backend/src/app/events/settings.events.ts +++ b/apps/electron-backend/src/app/events/settings.events.ts @@ -1,7 +1,9 @@ import { ipcMain } from 'electron'; import { + MPV_PLAYER_ARGUMENTS, MPV_REUSE_INSTANCE, store, + VLC_PLAYER_ARGUMENTS, VLC_REUSE_INSTANCE, } from '../services/store.service'; import { httpServer } from '../server/http-server'; @@ -12,9 +14,42 @@ export default class SettingsEvents { } } +function normalizeExternalPlayerArgumentsForStore(value: unknown): string { + if (Array.isArray(value)) { + return value + .map((argument) => String(argument).trim()) + .filter(Boolean) + .join('\n'); + } + + if (typeof value !== 'string') { + return ''; + } + + return value + .split(/\r?\n/) + .map((argument) => argument.trim()) + .filter(Boolean) + .join('\n'); +} + ipcMain.handle('SETTINGS_UPDATE', (_event, arg) => { console.log('Received SETTINGS_UPDATE with data:', arg); + if (arg.mpvPlayerArguments !== undefined) { + store.set( + MPV_PLAYER_ARGUMENTS, + normalizeExternalPlayerArgumentsForStore(arg.mpvPlayerArguments) + ); + } + + if (arg.vlcPlayerArguments !== undefined) { + store.set( + VLC_PLAYER_ARGUMENTS, + normalizeExternalPlayerArgumentsForStore(arg.vlcPlayerArguments) + ); + } + // Only set values that are defined if (arg.mpvReuseInstance !== undefined) { store.set(MPV_REUSE_INSTANCE, arg.mpvReuseInstance); @@ -25,9 +60,13 @@ ipcMain.handle('SETTINGS_UPDATE', (_event, arg) => { } // Handle remote control settings - if (arg.remoteControl !== undefined || arg.remoteControlPort !== undefined) { + if ( + arg.remoteControl !== undefined || + arg.remoteControlPort !== undefined + ) { const enabled = arg.remoteControl ?? store.get('remoteControl', false); - const port = arg.remoteControlPort ?? store.get('remoteControlPort', 8765); + const port = + arg.remoteControlPort ?? store.get('remoteControlPort', 8765); // Save to store if (arg.remoteControl !== undefined) { diff --git a/apps/electron-backend/src/app/services/store.service.ts b/apps/electron-backend/src/app/services/store.service.ts index d83b3e607..d1e01ec23 100644 --- a/apps/electron-backend/src/app/services/store.service.ts +++ b/apps/electron-backend/src/app/services/store.service.ts @@ -3,14 +3,18 @@ import { getElectronConfigDirectory } from 'database'; export const WINDOW_BOUNDS = 'WINDOW_BOUNDS'; export const MPV_PLAYER_PATH = 'MPV_PLAYER_PATH'; +export const MPV_PLAYER_ARGUMENTS = 'MPV_PLAYER_ARGUMENTS'; export const VLC_PLAYER_PATH = 'VLC_PLAYER_PATH'; +export const VLC_PLAYER_ARGUMENTS = 'VLC_PLAYER_ARGUMENTS'; export const MPV_REUSE_INSTANCE = 'MPV_REUSE_INSTANCE'; export const VLC_REUSE_INSTANCE = 'VLC_REUSE_INSTANCE'; export type StoreType = { [WINDOW_BOUNDS]: Electron.Rectangle; [MPV_PLAYER_PATH]: string; + [MPV_PLAYER_ARGUMENTS]: string; [VLC_PLAYER_PATH]: string; + [VLC_PLAYER_ARGUMENTS]: string; [MPV_REUSE_INSTANCE]: boolean; [VLC_REUSE_INSTANCE]: boolean; }; diff --git a/apps/web/src/app/app.component.spec.ts b/apps/web/src/app/app.component.spec.ts index 7b0d95088..1eca36f97 100644 --- a/apps/web/src/app/app.component.spec.ts +++ b/apps/web/src/app/app.component.spec.ts @@ -44,8 +44,10 @@ const DEFAULT_SETTINGS: Settings = { showExternalPlaybackBar: true, theme: Theme.SystemTheme, mpvPlayerPath: '', + mpvPlayerArguments: '', mpvReuseInstance: false, vlcPlayerPath: '', + vlcPlayerArguments: '', vlcReuseInstance: false, remoteControl: false, remoteControlPort: 8765, diff --git a/apps/web/src/app/settings/settings-playback-section.component.html b/apps/web/src/app/settings/settings-playback-section.component.html index 76494e5e6..f04b57a83 100644 --- a/apps/web/src/app/settings/settings-playback-section.component.html +++ b/apps/web/src/app/settings/settings-playback-section.component.html @@ -174,6 +174,38 @@ +
+
+

{{ 'SETTINGS.MPV_PLAYER_ARGUMENTS_LABEL' | translate }}

+

+ {{ + 'SETTINGS.MPV_PLAYER_ARGUMENTS_DESCRIPTION' | translate + }} +

+
+
+ + {{ + 'SETTINGS.MPV_PLAYER_ARGUMENTS' | translate + }} + + {{ + 'SETTINGS.EXTERNAL_PLAYER_ARGUMENTS_HINT' | translate + }} + +
+
+

{{ 'SETTINGS.MPV_REUSE_INSTANCE_LABEL' | translate }}

@@ -210,6 +242,38 @@
+
+
+

{{ 'SETTINGS.VLC_PLAYER_ARGUMENTS_LABEL' | translate }}

+

+ {{ + 'SETTINGS.VLC_PLAYER_ARGUMENTS_DESCRIPTION' | translate + }} +

+
+
+ + {{ + 'SETTINGS.VLC_PLAYER_ARGUMENTS' | translate + }} + + {{ + 'SETTINGS.EXTERNAL_PLAYER_ARGUMENTS_HINT' | translate + }} + +
+
+

{{ 'SETTINGS.VLC_REUSE_INSTANCE_LABEL' | translate }}

diff --git a/apps/web/src/app/settings/settings-playback-section.component.spec.ts b/apps/web/src/app/settings/settings-playback-section.component.spec.ts index 77fefc620..eb95fd76a 100644 --- a/apps/web/src/app/settings/settings-playback-section.component.spec.ts +++ b/apps/web/src/app/settings/settings-playback-section.component.spec.ts @@ -226,6 +226,46 @@ describe('SettingsPlaybackSectionComponent', () => { ) ).toBeNull(); }); + + it('shows MPV command-line arguments only when MPV is selected', () => { + fixture.componentRef.setInput('form', createForm(VideoPlayer.MPV)); + fixture.componentRef.setInput('isDesktop', true); + fixture.detectChanges(); + + expect( + fixture.nativeElement.querySelector( + '[data-test-id="mpv-player-arguments-setting"]' + ) + ).not.toBeNull(); + expect( + fixture.nativeElement.querySelector( + '[data-test-id="vlc-player-arguments-setting"]' + ) + ).toBeNull(); + expect(fixture.nativeElement.textContent).toContain( + 'SETTINGS.MPV_PLAYER_ARGUMENTS_LABEL' + ); + }); + + it('shows VLC command-line arguments only when VLC is selected', () => { + fixture.componentRef.setInput('form', createForm(VideoPlayer.VLC)); + fixture.componentRef.setInput('isDesktop', true); + fixture.detectChanges(); + + expect( + fixture.nativeElement.querySelector( + '[data-test-id="vlc-player-arguments-setting"]' + ) + ).not.toBeNull(); + expect( + fixture.nativeElement.querySelector( + '[data-test-id="mpv-player-arguments-setting"]' + ) + ).toBeNull(); + expect(fixture.nativeElement.textContent).toContain( + 'SETTINGS.VLC_PLAYER_ARGUMENTS_LABEL' + ); + }); }); function createForm(player = VideoPlayer.VideoJs): FormGroup { @@ -235,8 +275,10 @@ function createForm(player = VideoPlayer.VideoJs): FormGroup { openStreamOnDoubleClick: new FormControl(false), showExternalPlaybackBar: new FormControl(true), mpvPlayerPath: new FormControl(''), + mpvPlayerArguments: new FormControl(''), mpvReuseInstance: new FormControl(false), vlcPlayerPath: new FormControl(''), + vlcPlayerArguments: new FormControl(''), vlcReuseInstance: new FormControl(false), recordingFolder: new FormControl(''), }); diff --git a/apps/web/src/app/settings/settings.component.scss b/apps/web/src/app/settings/settings.component.scss index 18481594d..5fcd5c475 100644 --- a/apps/web/src/app/settings/settings.component.scss +++ b/apps/web/src/app/settings/settings.component.scss @@ -211,6 +211,30 @@ justify-content: stretch; } +.setting-item--external-player-arguments { + grid-template-columns: 1fr; + gap: 10px; + + .setting-item__control { + justify-content: stretch; + align-items: stretch; + } + + mat-form-field { + width: 100%; + } + + textarea { + min-height: 86px; + resize: vertical; + font-family: + 'JetBrains Mono', 'SFMono-Regular', Menlo, Monaco, Consolas, + monospace; + font-size: 0.84rem; + line-height: 1.45; + } +} + .theme-switcher { width: min(100%, 540px); display: grid; diff --git a/apps/web/src/app/settings/settings.component.spec.ts b/apps/web/src/app/settings/settings.component.spec.ts index 85e16e460..488c5f96d 100644 --- a/apps/web/src/app/settings/settings.component.spec.ts +++ b/apps/web/src/app/settings/settings.component.spec.ts @@ -76,8 +76,10 @@ const DEFAULT_SETTINGS = { showExternalPlaybackBar: true, theme: Theme.SystemTheme, mpvPlayerPath: '', + mpvPlayerArguments: '', mpvReuseInstance: false, vlcPlayerPath: '', + vlcPlayerArguments: '', vlcReuseInstance: false, remoteControl: false, remoteControlPort: 8765, @@ -953,4 +955,31 @@ describe('SettingsComponent', () => { expect(setMpvPlayerPath).toHaveBeenCalledWith(''); expect(setVlcPlayerPath).toHaveBeenCalledWith(''); }); + + it('saves external player command-line arguments with the settings payload', async () => { + const mockStore = settingsStore as unknown as MockSettingsStore; + mockStore.updateSettings.mockResolvedValue(undefined); + const updateSettings = jest.spyOn(window.electron, 'updateSettings'); + + component.settingsForm.patchValue({ + mpvPlayerArguments: '--screen=1\n--geometry=1280x720', + vlcPlayerArguments: '--qt-fullscreen-screennumber=1', + }); + + component.onSubmit(); + await fixture.whenStable(); + + expect(mockStore.updateSettings).toHaveBeenCalledWith( + expect.objectContaining({ + mpvPlayerArguments: '--screen=1\n--geometry=1280x720', + vlcPlayerArguments: '--qt-fullscreen-screennumber=1', + }) + ); + expect(updateSettings).toHaveBeenCalledWith( + expect.objectContaining({ + mpvPlayerArguments: '--screen=1\n--geometry=1280x720', + vlcPlayerArguments: '--qt-fullscreen-screennumber=1', + }) + ); + }); }); diff --git a/apps/web/src/app/settings/settings.component.ts b/apps/web/src/app/settings/settings.component.ts index b8f83ab0b..b1d417f21 100644 --- a/apps/web/src/app/settings/settings.component.ts +++ b/apps/web/src/app/settings/settings.component.ts @@ -187,8 +187,10 @@ export class SettingsComponent implements OnInit, OnDestroy { showExternalPlaybackBar: true, theme: Theme.SystemTheme, mpvPlayerPath: '', + mpvPlayerArguments: '', mpvReuseInstance: false, vlcPlayerPath: '', + vlcPlayerArguments: '', vlcReuseInstance: false, remoteControl: false, remoteControlPort: [ @@ -465,7 +467,21 @@ export class SettingsComponent implements OnInit, OnDestroy { * the indexed db store */ onSubmit(): void { - const settings = this.settingsForm.value; + const settings = { + ...this.settingsForm.value, + mpvPlayerPath: this.normalizeExternalPlayerPath( + this.settingsForm.value.mpvPlayerPath + ), + vlcPlayerPath: this.normalizeExternalPlayerPath( + this.settingsForm.value.vlcPlayerPath + ), + mpvPlayerArguments: this.normalizeExternalPlayerArguments( + this.settingsForm.value.mpvPlayerArguments + ), + vlcPlayerArguments: this.normalizeExternalPlayerArguments( + this.settingsForm.value.vlcPlayerArguments + ), + }; const mpvPlayerPath = this.normalizeExternalPlayerPath( settings.mpvPlayerPath ); @@ -494,6 +510,18 @@ export class SettingsComponent implements OnInit, OnDestroy { return playerPath?.trim() ?? ''; } + private normalizeExternalPlayerArguments( + playerArguments: string | null | undefined + ): string { + return ( + playerArguments + ?.split(/\r?\n/) + .map((argument) => argument.trim()) + .filter(Boolean) + .join('\n') ?? '' + ); + } + /** * Applies the changed settings to the app */ diff --git a/apps/web/src/assets/i18n/ar.json b/apps/web/src/assets/i18n/ar.json index 89077016b..723daab4f 100644 --- a/apps/web/src/assets/i18n/ar.json +++ b/apps/web/src/assets/i18n/ar.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "حدد مسار MPV. على macOS يمكنك استخدام حزمة تطبيق MPV مثل /Applications/mpv.app أو مسار الملف التنفيذي.", "MPV_COMPATIBLE_PLAYER_TIP": "يمكن تشغيل IINA كمشغل متوافق مع MPV على macOS، لكن استخدم مسار الملف التنفيذي مثل /Applications/IINA.app/Contents/MacOS/iina-cli أو /Applications/IINA.app/Contents/MacOS/IINA. عناصر تحكم IPTVnator وتتبع الموضع وإعادة استخدام النافذة مضمونة فقط مع MPV IPC.", "MPV_PLAYER_PATH": "مسار مشغل MPV", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "إعادة استخدام نسخة MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "عند التفعيل، سيتم إعادة استخدام نفس نافذة MPV لتشغيل البثوث المختلفة. عند التعطيل، يفتح كل بث في نافذة MPV جديدة.", "VLC_PLAYER_PATH_LABEL": "مسار VLC", "VLC_PLAYER_PATH_DESCRIPTION": "حدد مسار VLC. على macOS يمكنك استخدام حزمة تطبيق VLC مثل /Applications/VLC.app أو مسار الملف التنفيذي.", "VLC_PLAYER_PATH": "مسار مشغل VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "إعادة استخدام نسخة VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "عند التفعيل، سيتم إعادة استخدام نفس نافذة VLC لتشغيل البثوث المختلفة. عند التعطيل، يفتح كل بث في نافذة VLC جديدة.", "REMOTE_CONTROL": "التحكم عن بعد", diff --git a/apps/web/src/assets/i18n/ary.json b/apps/web/src/assets/i18n/ary.json index d0e98eae8..e21c67da6 100644 --- a/apps/web/src/assets/i18n/ary.json +++ b/apps/web/src/assets/i18n/ary.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "حدد مسار MPV. فـ macOS تقدر تستعمل باقة تطبيق MPV بحال /Applications/mpv.app أو مسار الملف التنفيذي.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA يقدر يتفتح كمشغل متوافق مع MPV فـ macOS، ولكن استعمل مسار الملف التنفيذي بحال /Applications/IINA.app/Contents/MacOS/iina-cli أو /Applications/IINA.app/Contents/MacOS/IINA. تحكم IPTVnator وتتبع الموضع وإعادة استعمال النافذة مضمونين غير مع MPV IPC.", "MPV_PLAYER_PATH": "مسار مشغل mpv", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "إعادة استخدام نسخة MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "إلى كانت مفعلة، نفس نافذة MPV غادي تستعمل لتشغيل بثوث مختلفة. إلى كانت معطلة، كل بث كيتحل في نافذة MPV جديدة.", "VLC_PLAYER_PATH_LABEL": "مسار VLC", "VLC_PLAYER_PATH_DESCRIPTION": "حدد مسار VLC. فـ macOS تقدر تستعمل باقة تطبيق VLC بحال /Applications/VLC.app أو مسار الملف التنفيذي.", "VLC_PLAYER_PATH": "مسار مشغل VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "إعادة استخدام نسخة VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "إلى كانت مفعلة، نفس نافذة VLC غادي تستعمل لتشغيل بثوث مختلفة. إلى كانت معطلة، كل بث كيتحل في نافذة VLC جديدة.", "REMOTE_CONTROL": "التحكم عن بعد", diff --git a/apps/web/src/assets/i18n/by.json b/apps/web/src/assets/i18n/by.json index 4d12859fd..38a14c918 100644 --- a/apps/web/src/assets/i18n/by.json +++ b/apps/web/src/assets/i18n/by.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Укажыце шлях да MPV. На macOS можна выкарыстоўваць пакет праграмы MPV, напрыклад /Applications/mpv.app, або шлях да выканальнага файла.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA можна запускаць як MPV-сумяшчальны прайгравальнік на macOS, але выкарыстоўвайце шлях да выканальнага файла, напрыклад /Applications/IINA.app/Contents/MacOS/iina-cli або /Applications/IINA.app/Contents/MacOS/IINA. Кіраванне IPTVnator, апытанне пазіцыі і паўторнае выкарыстанне акна гарантаваныя толькі для MPV IPC.", "MPV_PLAYER_PATH": "Шлях да mpv прайгравальніка", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Паўторна выкарыстоўваць асобнік MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Калі ўключана, тое ж акно MPV будзе паўторна выкарыстоўвацца для прайгравання розных патокаў. Калі адключана, кожны паток адкрываецца ў новым акне MPV.", "VLC_PLAYER_PATH_LABEL": "Шлях да VLC прайгравальніка", "VLC_PLAYER_PATH_DESCRIPTION": "Укажыце шлях да VLC. На macOS можна выкарыстоўваць пакет праграмы VLC, напрыклад /Applications/VLC.app, або шлях да выканальнага файла.", "VLC_PLAYER_PATH": "Шлях да VLC прайгравальніка", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Паўторна выкарыстоўваць асобнік VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Калі ўключана, тое ж акно VLC будзе паўторна выкарыстоўвацца для прайгравання розных патокаў. Калі адключана, кожны паток адкрываецца ў новым акне VLC.", "REMOTE_CONTROL": "Аддаленае кіраванне", diff --git a/apps/web/src/assets/i18n/de.json b/apps/web/src/assets/i18n/de.json index 1a0b45ffb..6cbf84c63 100644 --- a/apps/web/src/assets/i18n/de.json +++ b/apps/web/src/assets/i18n/de.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Lege den Pfad zu MPV fest. Unter macOS kannst du das MPV-App-Bundle wie /Applications/mpv.app oder den ausführbaren Pfad verwenden.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA kann unter macOS als MPV-kompatibler Player gestartet werden, verwende dafür aber den ausführbaren Pfad wie /Applications/IINA.app/Contents/MacOS/iina-cli oder /Applications/IINA.app/Contents/MacOS/IINA. IPTVnator-Steuerung, Positionsabfrage und Wiederverwendung der Instanz sind nur für MPV IPC garantiert.", "MPV_PLAYER_PATH": "MPV-Player-Pfad", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "MPV-Instanz wiederverwenden", "MPV_REUSE_INSTANCE_DESCRIPTION": "Wenn aktiviert, wird dasselbe MPV-Fenster zum Abspielen verschiedener Streams wiederverwendet. Wenn deaktiviert, wird jeder Stream in einem neuen MPV-Fenster geöffnet.", "VLC_PLAYER_PATH_LABEL": "VLC-Pfad", "VLC_PLAYER_PATH_DESCRIPTION": "Lege den Pfad zu VLC fest. Unter macOS kannst du das VLC-App-Bundle wie /Applications/VLC.app oder den ausführbaren Pfad verwenden.", "VLC_PLAYER_PATH": "VLC-Playerpfad", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "VLC-Instanz wiederverwenden", "VLC_REUSE_INSTANCE_DESCRIPTION": "Wenn aktiviert, wird dasselbe VLC-Fenster zum Abspielen verschiedener Streams wiederverwendet. Wenn deaktiviert, wird jeder Stream in einem neuen VLC-Fenster geöffnet.", "REMOTE_CONTROL": "Fernsteuerung", diff --git a/apps/web/src/assets/i18n/el.json b/apps/web/src/assets/i18n/el.json index 73fe688b5..169dd5d95 100644 --- a/apps/web/src/assets/i18n/el.json +++ b/apps/web/src/assets/i18n/el.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Ορίστε τη διαδρομή προς το MPV. Στο macOS μπορείτε να χρησιμοποιήσετε το πακέτο εφαρμογής MPV, όπως /Applications/mpv.app, ή τη διαδρομή του εκτελέσιμου αρχείου.", "MPV_COMPATIBLE_PLAYER_TIP": "Το IINA μπορεί να εκκινηθεί ως συμβατό με MPV πρόγραμμα αναπαραγωγής στο macOS, αλλά χρησιμοποιήστε τη διαδρομή του εκτελέσιμου, όπως /Applications/IINA.app/Contents/MacOS/iina-cli ή /Applications/IINA.app/Contents/MacOS/IINA. Τα στοιχεία ελέγχου του IPTVnator, η παρακολούθηση θέσης και η επαναχρησιμοποίηση instance είναι εγγυημένα μόνο για MPV IPC.", "MPV_PLAYER_PATH": "διαδρομή mpv προγράμματος αναπαραγωγής", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Επαναχρησιμοποίηση της παρουσίας MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Όταν είναι ενεργοποιημένη, το ίδιο παράθυρο MPV θα επαναχρησιμοποιηθεί για την αναπαραγωγή διαφορετικών ροών. Όταν είναι απενεργοποιημένη, κάθε ροή ανοίγει σε ένα νέο παράθυρο MPV.", "VLC_PLAYER_PATH_LABEL": "διαδρομή VLC", "VLC_PLAYER_PATH_DESCRIPTION": "Ορίστε τη διαδρομή προς το VLC. Στο macOS μπορείτε να χρησιμοποιήσετε το πακέτο εφαρμογής VLC, όπως /Applications/VLC.app, ή τη διαδρομή του εκτελέσιμου αρχείου.", "VLC_PLAYER_PATH": "διαδρομή VLC player", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Επαναχρησιμοποίηση της παρουσίας VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Όταν είναι ενεργοποιημένη, το ίδιο παράθυρο VLC θα επαναχρησιμοποιηθεί για την αναπαραγωγή διαφορετικών ροών. Όταν είναι απενεργοποιημένη, κάθε ροή ανοίγει σε ένα νέο παράθυρο VLC.", "REMOTE_CONTROL": "Τηλεχειριστήριο", diff --git a/apps/web/src/assets/i18n/en.json b/apps/web/src/assets/i18n/en.json index 3ac2322f6..faf73197b 100644 --- a/apps/web/src/assets/i18n/en.json +++ b/apps/web/src/assets/i18n/en.json @@ -323,6 +323,9 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Set the path to MPV. On macOS you can use the MPV app bundle, such as /Applications/mpv.app, or the executable path.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA can be launched as an MPV-compatible player on macOS, but use its executable path, such as /Applications/IINA.app/Contents/MacOS/iina-cli or /Applications/IINA.app/Contents/MacOS/IINA. IPTVnator controls, position polling, and reuse-instance behavior are guaranteed only for MPV IPC.", "MPV_PLAYER_PATH": "mpv player path", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Reuse MPV instance", "MPV_REUSE_INSTANCE_DESCRIPTION": "When enabled, the same MPV window will be reused for playing different streams. When disabled, each stream opens in a new MPV window.", "RECORDING_FOLDER_LABEL": "Recording folder", @@ -332,6 +335,10 @@ "VLC_PLAYER_PATH_LABEL": "VLC path", "VLC_PLAYER_PATH_DESCRIPTION": "Set the path to VLC. On macOS you can use the VLC app bundle, such as /Applications/VLC.app, or the executable path.", "VLC_PLAYER_PATH": "VLC player path", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Reuse VLC instance", "VLC_REUSE_INSTANCE_DESCRIPTION": "When enabled, the same VLC window will be reused for playing different streams. When disabled, each stream opens in a new VLC window.", "REMOTE_CONTROL": "Remote control", diff --git a/apps/web/src/assets/i18n/es.json b/apps/web/src/assets/i18n/es.json index 23dbf76e0..7ccfed620 100644 --- a/apps/web/src/assets/i18n/es.json +++ b/apps/web/src/assets/i18n/es.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Establece la ruta a MPV. En macOS puedes usar el paquete de la app MPV, como /Applications/mpv.app, o la ruta del ejecutable.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA puede iniciarse como reproductor compatible con MPV en macOS, pero usa su ruta ejecutable, como /Applications/IINA.app/Contents/MacOS/iina-cli o /Applications/IINA.app/Contents/MacOS/IINA. Los controles de IPTVnator, el seguimiento de posición y la reutilización de instancia solo están garantizados con MPV IPC.", "MPV_PLAYER_PATH": "ruta del reproductor mpv", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Reutilizar instancia de MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Cuando esta opción está activada, se reutiliza la misma ventana de MPV para reproducir distintos streams. Cuando está desactivada, cada stream se abre en una nueva ventana de MPV.", "VLC_PLAYER_PATH_LABEL": "ruta VLC", "VLC_PLAYER_PATH_DESCRIPTION": "Establece la ruta a VLC. En macOS puedes usar el paquete de la app VLC, como /Applications/VLC.app, o la ruta del ejecutable.", "VLC_PLAYER_PATH": "Ruta del reproductor VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Reutilizar instancia de VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Cuando esta opción está activada, se reutiliza la misma ventana de VLC para reproducir distintos streams. Cuando está desactivada, cada stream se abre en una nueva ventana de VLC.", "REMOTE_CONTROL": "Control remoto", diff --git a/apps/web/src/assets/i18n/fr.json b/apps/web/src/assets/i18n/fr.json index 8136fdde7..35e451955 100644 --- a/apps/web/src/assets/i18n/fr.json +++ b/apps/web/src/assets/i18n/fr.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Définissez le chemin vers MPV. Sur macOS, vous pouvez utiliser le bundle de l’app MPV, comme /Applications/mpv.app, ou le chemin de l’exécutable.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA peut être lancé comme lecteur compatible MPV sur macOS, mais utilisez son chemin exécutable, comme /Applications/IINA.app/Contents/MacOS/iina-cli ou /Applications/IINA.app/Contents/MacOS/IINA. Les contrôles IPTVnator, le suivi de position et la réutilisation d’instance ne sont garantis qu’avec MPV IPC.", "MPV_PLAYER_PATH": "Chemin du lecteur mpv", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Réutiliser l'instance MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Lorsqu'elle est activée, la même fenêtre MPV sera réutilisée pour lire différents flux. Lorsqu'elle est désactivée, chaque flux s'ouvre dans une nouvelle fenêtre MPV.", "VLC_PLAYER_PATH_LABEL": "Chemin VLC", "VLC_PLAYER_PATH_DESCRIPTION": "Définissez le chemin vers VLC. Sur macOS, vous pouvez utiliser le bundle de l’app VLC, comme /Applications/VLC.app, ou le chemin de l’exécutable.", "VLC_PLAYER_PATH": "Chemin du lecteur VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Réutiliser l'instance VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Lorsqu'elle est activée, la même fenêtre VLC sera réutilisée pour lire différents flux. Lorsqu'elle est désactivée, chaque flux s'ouvre dans une nouvelle fenêtre VLC.", "REMOTE_CONTROL": "Télécommande", diff --git a/apps/web/src/assets/i18n/it.json b/apps/web/src/assets/i18n/it.json index dc686b2c6..81b47e2ec 100644 --- a/apps/web/src/assets/i18n/it.json +++ b/apps/web/src/assets/i18n/it.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Imposta il percorso di MPV. Su macOS puoi usare il bundle dell’app MPV, come /Applications/mpv.app, oppure il percorso dell’eseguibile.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA può essere avviato come player compatibile con MPV su macOS, ma usa il suo percorso eseguibile, come /Applications/IINA.app/Contents/MacOS/iina-cli o /Applications/IINA.app/Contents/MacOS/IINA. I controlli di IPTVnator, il polling della posizione e il riuso dell’istanza sono garantiti solo con MPV IPC.", "MPV_PLAYER_PATH": "percorso riproduttore mpv", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Riutilizza istanza MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Quando attivo, la stessa finestra MPV viene riutilizzata per riprodurre stream diversi. Quando disattivo, ogni stream viene aperto in una nuova finestra MPV.", "VLC_PLAYER_PATH_LABEL": "Percorso VLC", "VLC_PLAYER_PATH_DESCRIPTION": "Imposta il percorso di VLC. Su macOS puoi usare il bundle dell’app VLC, come /Applications/VLC.app, oppure il percorso dell’eseguibile.", "VLC_PLAYER_PATH": "Percorso lettore VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Riutilizza istanza VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Quando attivo, la stessa finestra VLC viene riutilizzata per riprodurre stream diversi. Quando disattivo, ogni stream viene aperto in una nuova finestra VLC.", "REMOTE_CONTROL": "Telecomando", diff --git a/apps/web/src/assets/i18n/ja.json b/apps/web/src/assets/i18n/ja.json index a927ee680..653ae142e 100644 --- a/apps/web/src/assets/i18n/ja.json +++ b/apps/web/src/assets/i18n/ja.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "MPV へのパスを設定します。macOS では /Applications/mpv.app のような MPV アプリバンドル、または実行ファイルのパスを使用できます。", "MPV_COMPATIBLE_PLAYER_TIP": "IINA は macOS で MPV 互換プレーヤーとして起動できますが、/Applications/IINA.app/Contents/MacOS/iina-cli または /Applications/IINA.app/Contents/MacOS/IINA のような実行ファイルのパスを指定してください。IPTVnator の操作、位置ポーリング、インスタンス再利用は MPV IPC でのみ保証されます。", "MPV_PLAYER_PATH": "mpvプレーヤーのパス", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "MPVインスタンスを再利用", "MPV_REUSE_INSTANCE_DESCRIPTION": "有効にすると、異なるストリームの再生に同じMPVウィンドウが再利用されます。無効にすると、各ストリームが新しいMPVウィンドウで開きます。", "VLC_PLAYER_PATH_LABEL": "VLCのパス", "VLC_PLAYER_PATH_DESCRIPTION": "VLC へのパスを設定します。macOS では /Applications/VLC.app のような VLC アプリバンドル、または実行ファイルのパスを使用できます。", "VLC_PLAYER_PATH": "VLCプレーヤーのパス", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "VLCインスタンスを再利用", "VLC_REUSE_INSTANCE_DESCRIPTION": "有効にすると、異なるストリームの再生に同じVLCウィンドウが再利用されます。無効にすると、各ストリームが新しいVLCウィンドウで開きます。", "REMOTE_CONTROL": "リモートコントロール", diff --git a/apps/web/src/assets/i18n/ko.json b/apps/web/src/assets/i18n/ko.json index 22d98d4da..73b698b3f 100644 --- a/apps/web/src/assets/i18n/ko.json +++ b/apps/web/src/assets/i18n/ko.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "MPV 경로를 설정합니다. macOS에서는 /Applications/mpv.app 같은 MPV 앱 번들이나 실행 파일 경로를 사용할 수 있습니다.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA는 macOS에서 MPV 호환 플레이어로 실행할 수 있지만 /Applications/IINA.app/Contents/MacOS/iina-cli 또는 /Applications/IINA.app/Contents/MacOS/IINA 같은 실행 파일 경로를 사용하세요. IPTVnator 컨트롤, 위치 폴링, 인스턴스 재사용 동작은 MPV IPC에서만 보장됩니다.", "MPV_PLAYER_PATH": "mpv 플레이어 경로", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "MPV 인스턴스 재사용", "MPV_REUSE_INSTANCE_DESCRIPTION": "활성화하면 동일한 MPV 창에서 다른 스트림을 재생합니다. 비활성화하면 각 스트림이 새 MPV 창에서 열립니다.", "VLC_PLAYER_PATH_LABEL": "VLC 경로", "VLC_PLAYER_PATH_DESCRIPTION": "VLC 경로를 설정합니다. macOS에서는 /Applications/VLC.app 같은 VLC 앱 번들이나 실행 파일 경로를 사용할 수 있습니다.", "VLC_PLAYER_PATH": "VLC 플레이어 경로", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "VLC 인스턴스 재사용", "VLC_REUSE_INSTANCE_DESCRIPTION": "활성화하면 동일한 VLC 창에서 다른 스트림을 재생합니다. 비활성화하면 각 스트림이 새 VLC 창에서 열립니다.", "REMOTE_CONTROL": "원격 제어", diff --git a/apps/web/src/assets/i18n/nl.json b/apps/web/src/assets/i18n/nl.json index 9263f1308..e4a4f28e2 100644 --- a/apps/web/src/assets/i18n/nl.json +++ b/apps/web/src/assets/i18n/nl.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Stel het pad naar MPV in. Op macOS kun je de MPV-appbundel gebruiken, zoals /Applications/mpv.app, of het pad naar het uitvoerbare bestand.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA kan op macOS als MPV-compatibele speler worden gestart, maar gebruik het uitvoerbare pad, zoals /Applications/IINA.app/Contents/MacOS/iina-cli of /Applications/IINA.app/Contents/MacOS/IINA. IPTVnator-bediening, positie-polling en hergebruik van de instantie zijn alleen gegarandeerd met MPV IPC.", "MPV_PLAYER_PATH": "mpv-speler bestandspad", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "MPV-instantie hergebruiken", "MPV_REUSE_INSTANCE_DESCRIPTION": "Wanneer ingeschakeld, wordt hetzelfde MPV-venster hergebruikt voor het afspelen van verschillende streams. Wanneer uitgeschakeld, wordt elke stream geopend in een nieuw MPV-venster.", "VLC_PLAYER_PATH_LABEL": "VLC-bestandspad", "VLC_PLAYER_PATH_DESCRIPTION": "Stel het pad naar VLC in. Op macOS kun je de VLC-appbundel gebruiken, zoals /Applications/VLC.app, of het pad naar het uitvoerbare bestand.", "VLC_PLAYER_PATH": "VLC-speler bestandspad", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "VLC-instantie hergebruiken", "VLC_REUSE_INSTANCE_DESCRIPTION": "Wanneer ingeschakeld, wordt hetzelfde VLC-venster hergebruikt voor het afspelen van verschillende streams. Wanneer uitgeschakeld, wordt elke stream geopend in een nieuw VLC-venster.", "REMOTE_CONTROL": "Afstandsbediening", diff --git a/apps/web/src/assets/i18n/pl.json b/apps/web/src/assets/i18n/pl.json index 1df5bcd69..c0293fa21 100644 --- a/apps/web/src/assets/i18n/pl.json +++ b/apps/web/src/assets/i18n/pl.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Ustaw ścieżkę do MPV. W macOS możesz użyć pakietu aplikacji MPV, np. /Applications/mpv.app, albo ścieżki do pliku wykonywalnego.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA można uruchomić jako odtwarzacz zgodny z MPV w macOS, ale użyj ścieżki do pliku wykonywalnego, np. /Applications/IINA.app/Contents/MacOS/iina-cli lub /Applications/IINA.app/Contents/MacOS/IINA. Sterowanie IPTVnator, odpytywanie pozycji i ponowne użycie instancji są gwarantowane tylko dla MPV IPC.", "MPV_PLAYER_PATH": "Ścieżka odtwarzacza mpv", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Użyj ponownie instancji MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Po włączeniu to samo okno MPV będzie używane do odtwarzania różnych strumieni. Po wyłączeniu każdy strumień otwiera się w nowym oknie MPV.", "VLC_PLAYER_PATH_LABEL": "Ścieżka VLC", "VLC_PLAYER_PATH_DESCRIPTION": "Ustaw ścieżkę do VLC. W macOS możesz użyć pakietu aplikacji VLC, np. /Applications/VLC.app, albo ścieżki do pliku wykonywalnego.", "VLC_PLAYER_PATH": "Ścieżka odtwarzacza VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Użyj ponownie instancji VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Po włączeniu to samo okno VLC będzie używane do odtwarzania różnych strumieni. Po wyłączeniu każdy strumień otwiera się w nowym oknie VLC.", "REMOTE_CONTROL": "Zdalne sterowanie", diff --git a/apps/web/src/assets/i18n/pt.json b/apps/web/src/assets/i18n/pt.json index d4dccf1aa..6cada2740 100644 --- a/apps/web/src/assets/i18n/pt.json +++ b/apps/web/src/assets/i18n/pt.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Defina o caminho para o MPV. No macOS você pode usar o pacote do app MPV, como /Applications/mpv.app, ou o caminho do executável.", "MPV_COMPATIBLE_PLAYER_TIP": "O IINA pode ser iniciado como player compatível com MPV no macOS, mas use o caminho do executável, como /Applications/IINA.app/Contents/MacOS/iina-cli ou /Applications/IINA.app/Contents/MacOS/IINA. Controles do IPTVnator, consulta de posição e reutilização de instância são garantidos apenas com MPV IPC.", "MPV_PLAYER_PATH": "Caminho do reprodutor mpv", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "Reutilizar instância do MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Quando ativado, a mesma janela do MPV será reutilizada para reproduzir streams diferentes. Quando desativado, cada stream abre em uma nova janela do MPV.", "VLC_PLAYER_PATH_LABEL": "Caminho do VLC", "VLC_PLAYER_PATH_DESCRIPTION": "Defina o caminho para o VLC. No macOS você pode usar o pacote do app VLC, como /Applications/VLC.app, ou o caminho do executável.", "VLC_PLAYER_PATH": "Caminho do reprodutor VLC", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "Reutilizar instância do VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Quando ativado, a mesma janela do VLC será reutilizada para reproduzir streams diferentes. Quando desativado, cada stream abre em uma nova janela do VLC.", "REMOTE_CONTROL": "Controle remoto", diff --git a/apps/web/src/assets/i18n/ru.json b/apps/web/src/assets/i18n/ru.json index f80230efa..af1480a04 100644 --- a/apps/web/src/assets/i18n/ru.json +++ b/apps/web/src/assets/i18n/ru.json @@ -321,6 +321,9 @@ "MPV_PLAYER_PATH_DESCRIPTION": "Укажите путь к MPV. В macOS можно использовать пакет приложения MPV, например /Applications/mpv.app, или путь к исполняемому файлу.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA можно запускать как MPV-совместимый плеер в macOS, но указывайте путь к исполняемому файлу, например /Applications/IINA.app/Contents/MacOS/iina-cli или /Applications/IINA.app/Contents/MacOS/IINA. Управление из IPTVnator, опрос позиции и переиспользование экземпляра гарантированы только для MPV IPC.", "MPV_PLAYER_PATH": "Путь к mpv плееру", + "MPV_PLAYER_ARGUMENTS_LABEL": "Аргументы командной строки mpv", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Необязательные аргументы, которые передаются в mpv при запуске нового внешнего процесса плеера.", + "MPV_PLAYER_ARGUMENTS": "Аргументы mpv", "MPV_REUSE_INSTANCE_LABEL": "Переиспользовать экземпляр MPV", "MPV_REUSE_INSTANCE_DESCRIPTION": "Когда включено, одно и то же окно MPV будет использоваться для воспроизведения разных потоков. Когда отключено, каждый поток открывается в новом окне MPV.", "RECORDING_FOLDER_LABEL": "Папка для записей", @@ -330,6 +333,10 @@ "VLC_PLAYER_PATH_LABEL": "Путь к VLC плееру", "VLC_PLAYER_PATH_DESCRIPTION": "Укажите путь к VLC. В macOS можно использовать пакет приложения VLC, например /Applications/VLC.app, или путь к исполняемому файлу.", "VLC_PLAYER_PATH": "Путь к VLC плееру", + "VLC_PLAYER_ARGUMENTS_LABEL": "Аргументы командной строки VLC", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Необязательные аргументы, которые передаются в VLC при запуске нового внешнего процесса плеера.", + "VLC_PLAYER_ARGUMENTS": "Аргументы VLC", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Один аргумент на строку. Эти значения применяются перед параметрами IPTVnator для конкретного потока.", "VLC_REUSE_INSTANCE_LABEL": "Переиспользовать экземпляр VLC", "VLC_REUSE_INSTANCE_DESCRIPTION": "Когда включено, одно и то же окно VLC будет использоваться для воспроизведения разных потоков. Когда отключено, каждый поток открывается в новом окне VLC.", "REMOTE_CONTROL": "Удалённое управление", diff --git a/apps/web/src/assets/i18n/tr.json b/apps/web/src/assets/i18n/tr.json index eb5858e58..059d257f1 100644 --- a/apps/web/src/assets/i18n/tr.json +++ b/apps/web/src/assets/i18n/tr.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "MPV yolunu ayarlayın. macOS’ta /Applications/mpv.app gibi MPV uygulama paketini veya yürütülebilir dosya yolunu kullanabilirsiniz.", "MPV_COMPATIBLE_PLAYER_TIP": "IINA, macOS’ta MPV uyumlu bir oynatıcı olarak başlatılabilir; ancak /Applications/IINA.app/Contents/MacOS/iina-cli veya /Applications/IINA.app/Contents/MacOS/IINA gibi yürütülebilir dosya yolunu kullanın. IPTVnator kontrolleri, konum yoklama ve örnek yeniden kullanımı yalnızca MPV IPC için garanti edilir.", "MPV_PLAYER_PATH": "mpv oynatıcı yolu", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "MPV örneğini yeniden kullan", "MPV_REUSE_INSTANCE_DESCRIPTION": "Etkinleştirildiğinde, farklı yayınları oynatmak için aynı MPV penceresi yeniden kullanılır. Devre dışı bırakıldığında, her yayın yeni bir MPV penceresinde açılır.", "VLC_PLAYER_PATH_LABEL": "VLC yolu", "VLC_PLAYER_PATH_DESCRIPTION": "VLC yolunu ayarlayın. macOS’ta /Applications/VLC.app gibi VLC uygulama paketini veya yürütülebilir dosya yolunu kullanabilirsiniz.", "VLC_PLAYER_PATH": "VLC oynatıcı yolu", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "VLC örneğini yeniden kullan", "VLC_REUSE_INSTANCE_DESCRIPTION": "Etkinleştirildiğinde, farklı yayınları oynatmak için aynı VLC penceresi yeniden kullanılır. Devre dışı bırakıldığında, her yayın yeni bir VLC penceresinde açılır.", "REMOTE_CONTROL": "Uzaktan kontrol", diff --git a/apps/web/src/assets/i18n/zh.json b/apps/web/src/assets/i18n/zh.json index 29b003a69..a2096f120 100644 --- a/apps/web/src/assets/i18n/zh.json +++ b/apps/web/src/assets/i18n/zh.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "设置 MPV 路径。在 macOS 上可以使用 MPV 应用包,例如 /Applications/mpv.app,也可以使用可执行文件路径。", "MPV_COMPATIBLE_PLAYER_TIP": "IINA 可以在 macOS 上作为兼容 MPV 的播放器启动,但请使用它的可执行文件路径,例如 /Applications/IINA.app/Contents/MacOS/iina-cli 或 /Applications/IINA.app/Contents/MacOS/IINA。IPTVnator 控制、位置轮询和实例复用行为仅对 MPV IPC 保证可用。", "MPV_PLAYER_PATH": "mpv 播放器路径", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "复用 MPV 实例", "MPV_REUSE_INSTANCE_DESCRIPTION": "启用后,将复用同一个 MPV 窗口播放不同的视频流。禁用后,每个视频流都会在新的 MPV 窗口中打开。", "VLC_PLAYER_PATH_LABEL": "VLC路径", "VLC_PLAYER_PATH_DESCRIPTION": "设置 VLC 路径。在 macOS 上可以使用 VLC 应用包,例如 /Applications/VLC.app,也可以使用可执行文件路径。", "VLC_PLAYER_PATH": "VLC播放器路径", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "复用 VLC 实例", "VLC_REUSE_INSTANCE_DESCRIPTION": "启用后,将复用同一个 VLC 窗口播放不同的视频流。禁用后,每个视频流都会在新的 VLC 窗口中打开。", "REMOTE_CONTROL": "远程控制", diff --git a/apps/web/src/assets/i18n/zhtw.json b/apps/web/src/assets/i18n/zhtw.json index f0180760f..747260097 100644 --- a/apps/web/src/assets/i18n/zhtw.json +++ b/apps/web/src/assets/i18n/zhtw.json @@ -321,11 +321,18 @@ "MPV_PLAYER_PATH_DESCRIPTION": "設定 MPV 路徑。在 macOS 上可以使用 MPV App bundle,例如 /Applications/mpv.app,也可以使用可執行檔路徑。", "MPV_COMPATIBLE_PLAYER_TIP": "IINA 可以在 macOS 上作為相容 MPV 的播放器啟動,但請使用它的可執行檔路徑,例如 /Applications/IINA.app/Contents/MacOS/iina-cli 或 /Applications/IINA.app/Contents/MacOS/IINA。IPTVnator 控制、位置輪詢與 instance 重複使用僅保證適用於 MPV IPC。", "MPV_PLAYER_PATH": "mpv 播放器路徑", + "MPV_PLAYER_ARGUMENTS_LABEL": "mpv command-line arguments", + "MPV_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to mpv when IPTVnator starts a new external player process.", + "MPV_PLAYER_ARGUMENTS": "mpv arguments", "MPV_REUSE_INSTANCE_LABEL": "重複使用 MPV 實體", "MPV_REUSE_INSTANCE_DESCRIPTION": "啟用後,相同的 MPV 視窗將重複用於播放不同串流。停用時,每個串流會在新的 MPV 視窗中開啟。", "VLC_PLAYER_PATH_LABEL": "VLC 路徑", "VLC_PLAYER_PATH_DESCRIPTION": "設定 VLC 路徑。在 macOS 上可以使用 VLC App bundle,例如 /Applications/VLC.app,也可以使用可執行檔路徑。", "VLC_PLAYER_PATH": "VLC 播放器路徑", + "VLC_PLAYER_ARGUMENTS_LABEL": "VLC command-line arguments", + "VLC_PLAYER_ARGUMENTS_DESCRIPTION": "Optional arguments passed to VLC when IPTVnator starts a new external player process.", + "VLC_PLAYER_ARGUMENTS": "VLC arguments", + "EXTERNAL_PLAYER_ARGUMENTS_HINT": "Use one argument per line. These values are applied before stream-specific IPTVnator options.", "VLC_REUSE_INSTANCE_LABEL": "重複使用 VLC 實體", "VLC_REUSE_INSTANCE_DESCRIPTION": "啟用後,相同的 VLC 視窗將重複用於播放不同串流。停用時,每個串流會在新的 VLC 視窗中開啟。", "REMOTE_CONTROL": "遠端控制", diff --git a/docs/architecture/embedded-inline-playback.md b/docs/architecture/embedded-inline-playback.md index 76e8cff63..d06f52576 100644 --- a/docs/architecture/embedded-inline-playback.md +++ b/docs/architecture/embedded-inline-playback.md @@ -160,6 +160,24 @@ When a diagnostic is actionable in Electron, the inline banner may offer `Open i `PortalPlayer.openExternalPlayback(playback, player)` is the forced external launch API. It sends the playback payload to MPV or VLC regardless of the current saved player setting, so fallback buttons do not mutate preferences. +## External Player Arguments + +Electron settings expose optional MPV and VLC command-line argument fields only +when the corresponding external player is selected. The executable path remains a +path-only setting; extra flags are stored separately as `mpvPlayerArguments` and +`vlcPlayerArguments`. + +Argument fields are line-oriented: one non-empty trimmed line becomes one argv +entry. IPTVnator prepends those custom entries before its stream-specific runtime +arguments, then keeps the stream URL last. This avoids shell parsing, keeps paths +with spaces safe, and preserves existing settings for users who never configured +extra arguments. + +The arguments apply only when IPTVnator spawns a new external player process. If +MPV or VLC instance reuse is active and an existing process is reused, subsequent +streams are loaded through MPV IPC or VLC RC commands and new process arguments +are not re-applied until a fresh process starts. + ## Flatpak External Players Flatpak cannot execute host-installed `mpv` or `vlc` binaries directly from the sandbox. diff --git a/libs/services/src/lib/settings-store.service.ts b/libs/services/src/lib/settings-store.service.ts index 2b7daa772..ae02ff58a 100644 --- a/libs/services/src/lib/settings-store.service.ts +++ b/libs/services/src/lib/settings-store.service.ts @@ -29,8 +29,10 @@ const DEFAULT_SETTINGS: Settings = { showExternalPlaybackBar: true, theme: Theme.SystemTheme, mpvPlayerPath: '', + mpvPlayerArguments: '', mpvReuseInstance: false, vlcPlayerPath: '', + vlcPlayerArguments: '', vlcReuseInstance: false, remoteControl: false, remoteControlPort: 8765, @@ -136,8 +138,10 @@ export const SettingsStore = signalStore( showExternalPlaybackBar: store.showExternalPlaybackBar!(), theme: store.theme(), mpvPlayerPath: store.mpvPlayerPath(), + mpvPlayerArguments: store.mpvPlayerArguments?.() ?? '', mpvReuseInstance: store.mpvReuseInstance(), vlcPlayerPath: store.vlcPlayerPath(), + vlcPlayerArguments: store.vlcPlayerArguments?.() ?? '', vlcReuseInstance: store.vlcReuseInstance(), remoteControl: store.remoteControl(), remoteControlPort: store.remoteControlPort(), diff --git a/libs/shared/interfaces/src/lib/settings.interface.ts b/libs/shared/interfaces/src/lib/settings.interface.ts index c2df9479a..835b223af 100644 --- a/libs/shared/interfaces/src/lib/settings.interface.ts +++ b/libs/shared/interfaces/src/lib/settings.interface.ts @@ -37,8 +37,18 @@ export interface Settings { showExternalPlaybackBar?: boolean; theme: Theme; mpvPlayerPath: string; + /** + * Extra MPV CLI arguments entered one argument per line. Applied only when + * starting a new external MPV process. + */ + mpvPlayerArguments?: string; mpvReuseInstance: boolean; vlcPlayerPath: string; + /** + * Extra VLC CLI arguments entered one argument per line. Applied only when + * starting a new external VLC process. + */ + vlcPlayerArguments?: string; vlcReuseInstance: boolean; remoteControl: boolean; remoteControlPort: number;