UNPKG

tauri-plugin-mpv-api

Version:

A Tauri plugin for embedding the mpv player in your app via JSON IPC.

303 lines (299 loc) 8.86 kB
'use strict'; var core = require('@tauri-apps/api/core'); var window = require('@tauri-apps/api/window'); var event = require('@tauri-apps/api/event'); const COMMON_PROPERTIES = [ 'playlist', // Playlist 'filename', // Current filename 'pause', // Pause state 'eof-reached', // End of file reached state 'time-pos', // Playback position (seconds) 'duration', // Total duration (seconds) 'volume', // Volume (0-100) 'mute', // Mute state 'speed', // Playback speed ]; const DEFAULT_MPV_CONFIG = { args: [ '--vo=gpu-next', '--hwdec=auto-safe', '--keep-open=yes', '--force-window', ], observedProperties: COMMON_PROPERTIES, ipcTimeoutMs: 2000, showMpvOutput: false, }; /** * Initialize mpv player. * * @param {MpvConfig} [mpvConfig] - Initialization options. * @param {string} [windowLabel] - The label of the target window. Defaults to the current window's label. * @returns {Promise<string>} A promise that resolves with the actual window label used for initialization. * @throws {Error} Throws an error if mpv initialization fails (e.g., mpv executable not in PATH). * * @example * ```typescript * import { init, destroy, MpvConfig } from 'tauri-plugin-mpv-api'; * * // Properties to observe * const OBSERVED_PROPERTIES = ['pause', 'time-pos', 'duration', 'filename'] as const; * * // mpv configuration * const mpvConfig: MpvConfig = { * args: [ * '--vo=gpu-next', * '--hwdec=auto-safe', * '--keep-open=yes', * '--force-window', * ], * observedProperties: OBSERVED_PROPERTIES, * }; * * // Initialize mpv * try { * await init(mpvConfig); * } catch (error) { * console.error('Failed to initialize mpv:', error); * } * * // Destroy mpv when no longer needed * await destroy(); * ``` */ async function init(mpvConfig, windowLabel) { mpvConfig = { ...DEFAULT_MPV_CONFIG, ...mpvConfig, }; windowLabel = windowLabel ?? window.getCurrentWindow().label; return await core.invoke('plugin:mpv|init', { mpvConfig, windowLabel, }); } /** * @deprecated Use `init()` instead. This function will be removed in a future version. */ const initializeMpv = init; /** * Destroy mpv player. * * @param {string} [windowLabel] - Target window label, defaults to current window * @returns {Promise<void>} A promise that resolves when the operation completes. * * @example * ```typescript * import { destroy } from 'tauri-plugin-mpv-api'; * * await destroy(); * ``` */ async function destroy(windowLabel) { windowLabel = windowLabel ?? window.getCurrentWindow().label; return await core.invoke('plugin:mpv|destroy', { windowLabel, }); } /** * @deprecated Use `destroy()` instead. This function will be removed in a future version. */ const destroyMpv = destroy; async function observeMpvProperties(arg1, arg2, arg3) { let properties; let callback; let windowLabel; if (typeof arg1 === 'function') { properties = COMMON_PROPERTIES; callback = arg1; windowLabel = arg2; } else { properties = arg1; callback = arg2; windowLabel = arg3; } return await listenMpvEvents((mpvEvent) => { if (mpvEvent.event === 'property-change') { if (properties.includes(mpvEvent.name)) { callback(mpvEvent); } } }, windowLabel); } /** * Listen to all mpv events. * * @param {(event: MpvEvent) => void} callback - Function to call when mpv events are received * @param {string} [windowLabel] - Target window label, defaults to current window * @returns {Promise<UnlistenFn>} Function to call to stop listening * * @example * ```typescript * import { listenMpvEvents } from 'tauri-plugin-mpv-api'; * * // Listen events * const unlisten = await listenMpvEvents((mpvEvent) => { * if (mpvEvent.event === 'property-change') { * const { name, data } = mpvEvent * switch (name) { * case 'pause': * console.log('Playback paused state:', data); * break; * case 'time-pos': * console.log('Current time position:', data); * break; * case 'duration': * console.log('Duration:', data); * break; * case 'filename': * console.log('Current playing file:', data); * break; * } * } * }); * * // Unlisten when no longer needed * unlisten(); * ``` */ async function listenMpvEvents(callback, windowLabel) { windowLabel = windowLabel ?? window.getCurrentWindow().label; const eventName = `mpv-event-${windowLabel}`; return await event.listen(eventName, (event) => callback(event.payload)); } async function command(arg1, arg2, arg3) { let finalMpvCommand; let finalWindowLabel; let isShortcut = false; if (typeof arg1 === 'string') { isShortcut = true; const name = arg1; const args = Array.isArray(arg2) ? arg2 : []; finalWindowLabel = Array.isArray(arg2) ? arg3 : arg2; finalMpvCommand = { command: [name, ...args], }; } else { isShortcut = false; finalMpvCommand = arg1; finalWindowLabel = arg2; } finalWindowLabel = finalWindowLabel ?? window.getCurrentWindow().label; const response = await core.invoke('plugin:mpv|command', { mpvCommand: finalMpvCommand, windowLabel: finalWindowLabel, }); if (isShortcut) { if (response.error !== 'success') { throw new Error(`mpv command failed: ${response.error}`); } return response.data; } else { return response; } } /** * @deprecated Use `command()` instead. This function will be removed in a future version. */ const sendMpvCommand = command; /** * Gets the value of an mpv property. * * @param name The name of the property to get. * @param windowLabel (Optional) The label of the Tauri window to target. * @returns A promise that resolves with the typed property value. * @throws {Error} Throws an error if the command fails. * * @example * ```typescript * import { getProperty } from 'tauri-plugin-mpv-api'; * * // Get volume * const volume = await getProperty('volume'); * * // `custom` is now treated as `string` * const custom = await getProperty<string>('my-custom-property'); * ``` */ async function getProperty(name, windowLabel) { const value = await command('get_property', [name], windowLabel); return value; } /** * Sets the value of an mpv property. * * @param name The name of the property to set. * @param value The value to set. Must match the property's type if it is known. * @param windowLabel (Optional) The label of the Tauri window to target. * @returns A promise that resolves when the property has been set. * @throws {Error} Throws an error if the command fails. * * @example * ```typescript * import { setProperty } from 'tauri-plugin-mpv-api'; * * // Set volume * await setProperty('volume', 80); * * // Explicitly provide a type for a custom or unknown property * await setProperty<string>('my-custom-property', 'some-value'); * ``` */ async function setProperty(name, value, windowLabel) { await command('set_property', [name, value], windowLabel); } /** * Set video margin ratio * * @param {VideoMarginRatio} ratio - Margin ratio configuration object * @param {string} [windowLabel] - Target window label, defaults to current window * @returns {Promise<void>} Promise with no return value * @throws {Error} Throws error when setting fails * * @example * ```typescript * import { setVideoMarginRatio } from 'tauri-plugin-mpv-api'; * * // Leave 10% space at bottom for control bar * await setVideoMarginRatio({ bottom: 0.1 }); * * // Leave margins on all sides * await setVideoMarginRatio({ * left: 0.05, * right: 0.05, * top: 0.1, * bottom: 0.15, * }); * * // Reset margins (remove all margins) * await setVideoMarginRatio({ * left: 0, * right: 0, * top: 0, * bottom: 0, * }); * ``` */ async function setVideoMarginRatio(ratio, windowLabel) { windowLabel = windowLabel ?? window.getCurrentWindow().label; return await core.invoke('plugin:mpv|set_video_margin_ratio', { ratio, windowLabel, }); } exports.COMMON_PROPERTIES = COMMON_PROPERTIES; exports.DEFAULT_MPV_CONFIG = DEFAULT_MPV_CONFIG; exports.command = command; exports.destroy = destroy; exports.destroyMpv = destroyMpv; exports.getProperty = getProperty; exports.init = init; exports.initializeMpv = initializeMpv; exports.listenMpvEvents = listenMpvEvents; exports.observeMpvProperties = observeMpvProperties; exports.sendMpvCommand = sendMpvCommand; exports.setProperty = setProperty; exports.setVideoMarginRatio = setVideoMarginRatio;