From ffb384f7ab015413b847d3796c436a60c64d3f6b Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Tue, 7 Jan 2025 18:23:55 +0100 Subject: [PATCH] select.lua: select from the watch history with g-h Implement selection of the entries in the watch history. --osd-playlist-entry determines whether titles and/or filenames are shown. But unlike in show-text ${playlist} and select-playlist, "file" and "both" print full paths because history is much more likely to have files from completely different directories, so showing the directory conveys where files are located. This is particularly helpful for filenames like 1.jpg. The last entry in the selector deletes the history file, as requested by Samillion. --- DOCS/man/mpv.rst | 3 ++ DOCS/man/options.rst | 3 +- etc/input.conf | 1 + player/lua/select.lua | 100 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index 7c67cf0d96d18..ecb54f42abec9 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -328,6 +328,9 @@ g-l g-d Select an audio device. +g-h + Select a file from the watch history. Requires ``--save-watch-history``. + g-w Select a file from watch later config files (see `RESUMING PLAYBACK`_) to resume playing. Requires ``--write-filename-in-watch-later-config``. This diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index ece0e1621641b..d83f6241068d0 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1152,7 +1152,8 @@ Watch History ------------- ``--save-watch-history`` - Whether to save which files are played. + Whether to save which files are played. These can be then selected with the + default ``g-h`` key binding. .. warning:: diff --git a/etc/input.conf b/etc/input.conf index 2faa88c233b28..adbb824a0d838 100644 --- a/etc/input.conf +++ b/etc/input.conf @@ -187,6 +187,7 @@ #g-e script-binding select/select-edition #g-l script-binding select/select-subtitle-line #g-d script-binding select/select-audio-device +#g-h script-binding select/select-watch-history #g-w script-binding select/select-watch-later #g-b script-binding select/select-binding #g-r script-binding select/show-properties diff --git a/player/lua/select.lua b/player/lua/select.lua index 7f20602aff098..3f29bfdee9491 100644 --- a/player/lua/select.lua +++ b/player/lua/select.lua @@ -353,6 +353,106 @@ mp.add_key_binding(nil, "select-audio-device", function () }) end) +local function get_history_entry(line, seen, error_message) + local entry = utils.parse_json(line) + + if not entry then + mp.msg.warn(error_message) + return + end + + local time, path, title = unpack(entry) + + if not path then + mp.msg.warn(error_message) + return + end + + if seen[path] then + return + end + + seen[path] = true + + local status, date = pcall(os.date, "(%Y-%m-%d %H:%M) ", time) + + if not status then + mp.msg.warn(error_message) + return + end + + return { + date = date, + path = path, + title = title, + } +end + + +local function format_history_entry(entry, osd_playlist_entry) + if entry.title and osd_playlist_entry == "title" then + return entry.title + end + + if entry.title and osd_playlist_entry == "both" then + return entry.title .. " (" .. entry.path .. ")" + end + + return entry.path +end + +mp.add_key_binding(nil, "select-watch-history", function () + local history_file_path = mp.command_native({"expand-path", + mp.get_property("watch-history-path")}) + local history_file, error_message = io.open(history_file_path) + if not history_file then + show_warning(mp.get_property_native("save-watch-history") + and error_message + or "Enable --save-watch-history") + return + end + + local lines = {} + for line in history_file:lines() do + table.insert(lines, line) + end + history_file:close() + + local entries = {} + local seen = {} + local items = {} + local osd_playlist_entry = mp.get_property("osd-playlist-entry") + + for i = #lines, 1, -1 do + error_message = history_file_path .. ": Parse error at line " .. i + local entry = get_history_entry(lines[i], seen, error_message) + if entry then + entries[#entries + 1] = entry + items[#items + 1] = entry.date .. format_history_entry(entry, osd_playlist_entry) + end + end + + items[#items+1] = "Clear history" + + input.select({ + prompt = "Select a file:", + items = items, + submit = function (i) + if entries[i] then + mp.commandv("loadfile", entries[i].path) + return + end + + error_message = select(2, os.remove(history_file_path)) + if error_message then + show_error(error_message) + else + mp.osd_message("History cleared.") + end + end, + }) +end) + mp.add_key_binding(nil, "select-watch-later", function () local watch_later_dir = mp.get_property("current-watch-later-dir")