基于fdfind与fzf的mpv Lua文件选择播放脚本实现求助
1. Completed Lua Code Implementation
First, let's fix your Lua script to properly pipe the fdfind output into your menu_fzf.sh and capture the selected files. The key issue with your previous attempts was that mp.utils.subprocess doesn't handle shell pipe syntax (|) by default—you need to enable shell mode to use shell features like pipes.
Here's the working code:
local utils = require 'mp.utils' -- Replace this with your target directory (e.g., "/path/to/Music") local target_dir = "/path/to/your/media/directory" -- Build the full shell command: fdfind -> menu_fzf.sh local command = string.format('fdfind . "%s" | /path/to/your/menu_fzf.sh', target_dir) -- Execute the command with shell enabled to handle pipes local file_select = utils.subprocess({ args = command, shell = true, -- Critical: enables shell to process the pipe cancellable = false, stdout = "pipe", -- Capture stdout to get selected files stderr = "ignore" -- Optional: suppress error output if not needed }) -- Process the result: split stdout into individual file paths if file_select.status == 0 then -- Check if command succeeded local selected_files = {} -- Split stdout by newlines (ignore empty lines from trailing newlines) for line in string.gmatch(file_select.stdout, '[^\n]+') do table.insert(selected_files, line) end -- Add selected files to mpv's playlist (like kdialog-open-files.lua) for _, file in ipairs(selected_files) do mp.commandv('loadfile', file, 'append') end -- Optional: play the first file if playlist was empty if #selected_files > 0 then mp.command('play') end else mp.osd_message("File selection cancelled or failed", 2) end
Key Fixes Explained:
shell = true: This tellsmp.utils.subprocessto run the command through the system shell, which allows pipe (|) syntax to work. Without this, the shell treats|andfzfas arguments tofdfind, which caused your earlier error.- Full Command String: We construct the exact pipe command you used in bash, ensuring
fdfind's output is passed tomenu_fzf.shas input. - Capturing Stdout: The
stdout = "pipe"setting ensures we capture the selected file paths frommenu_fzf.sh's output. - Result Processing: We split the captured stdout into individual file paths and add them to mpv's playlist, matching the behavior of the existing KDialog/Zenity scripts.
Don't forget to replace /path/to/your/media/directory and /path/to/your/menu_fzf.sh with your actual paths!
2. Detailed mp.utils.subprocess Reference
Since the official mpv docs are sparse, here's a breakdown of the key parameters and behavior:
Parameters (Table Keys)
args: Can be either:- An array of strings (when
shell = false, default): Each element is a command or argument (e.g.,{'fdfind', '.', '/path/to/Music'}). No shell features like pipes/globs work here. - A single string (when
shell = true): The full command to run via the system shell (supports pipes, variables, globs, etc.).
- An array of strings (when
shell: Boolean (defaultfalse). Iftrue, runs the command through/bin/sh(or your system's default shell).cancellable: Boolean (defaultfalse). Iftrue, allows mpv to kill the subprocess if the user cancels the action.stdin: Controls how the subprocess receives input:"ignore"(default): Subprocess gets no input."pipe": You can write to the subprocess's stdin (via the returned handle, though this is more advanced).
stdout/stderr: Controls output capture:"ignore"(default): Discards output."pipe": Captures the output into the returned result table."devnull": Redirects to/dev/null.
Returned Result Table
The function returns a table with these keys:
status: Exit code of the subprocess (0 = success, non-zero = error).stdout: String containing captured stdout (only ifstdout = "pipe").stderr: String containing captured stderr (only ifstderr = "pipe").killed: Boolean indicating if the subprocess was killed by mpv (only ifcancellable = true).
Source Location
If you want to dive deeper into the implementation, the mp.utils.subprocess code lives in mpv's source tree at:
- For the C backend:
player/lua/utils.c(handles the subprocess execution) - For Lua wrapper docs:
DOCS/man/lua.rst(the official sparse docs, but you can find more context in the C source)
内容的提问来源于stack exchange,提问作者Inspired_Blue

