Skip to content

Commit

Permalink
select.lua: select from the watch history with g-h
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
guidocella committed Jan 9, 2025
1 parent 47e7af2 commit c653be6
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 1 deletion.
3 changes: 3 additions & 0 deletions DOCS/man/mpv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::

Expand Down
1 change: 1 addition & 0 deletions etc/input.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
104 changes: 104 additions & 0 deletions player/lua/select.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ License along with mpv. If not, see <http://www.gnu.org/licenses/>.
local utils = require "mp.utils"
local input = require "mp.input"

local options = {
history_date_format = "%Y-%m-%d %H:%M:%S",
}

require "mp.options".read_options(options, nil, function () end)

local function show_warning(message)
mp.msg.warn(message)
if mp.get_property_native("vo-configured") then
Expand Down Expand Up @@ -353,6 +359,104 @@ 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

if not entry.path then
mp.msg.warn(error_message)
return
end

if seen[entry.path] then
return
end

seen[entry.path] = true

local status
status, entry.time = pcall(os.date, options.history_date_format, entry.time)

if not status then
-- Lua 5.1 and LuaJIT return invalid formats as is, but Lua 5.2+ errors,
-- so also print the returned error message for that case.
mp.msg.warn(error_message .. " - " .. entry.time)
return
end

return entry
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.time .. ") " ..
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")

Expand Down

0 comments on commit c653be6

Please sign in to comment.