dfdfdd
This commit is contained in:
128
MPV/LUA/main.lua
128
MPV/LUA/main.lua
@@ -688,9 +688,114 @@ local function _reset_pan_zoom()
|
||||
_show_image_status('Zoom reset')
|
||||
end
|
||||
|
||||
local function _sanitize_filename_component(s)
|
||||
s = trim(tostring(s or ''))
|
||||
if s == '' then
|
||||
return 'screenshot'
|
||||
end
|
||||
-- Windows-unfriendly characters: <>:"/\|?* and control chars
|
||||
s = s:gsub('[%c]', '')
|
||||
s = s:gsub('[<>:"/\\|%?%*]', '_')
|
||||
s = trim(s)
|
||||
s = s:gsub('[%.%s]+$', '')
|
||||
if s == '' then
|
||||
return 'screenshot'
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function _strip_title_extension(title, path)
|
||||
title = trim(tostring(title or ''))
|
||||
if title == '' then
|
||||
return title
|
||||
end
|
||||
path = tostring(path or '')
|
||||
local ext = path:match('%.([%w%d]+)$')
|
||||
if not ext or ext == '' then
|
||||
return title
|
||||
end
|
||||
ext = ext:lower()
|
||||
local suffix = '.' .. ext
|
||||
if title:lower():sub(-#suffix) == suffix then
|
||||
return trim(title:sub(1, #title - #suffix))
|
||||
end
|
||||
return title
|
||||
end
|
||||
|
||||
local function _capture_screenshot()
|
||||
mp.commandv('screenshot')
|
||||
mp.osd_message('Screenshot captured', 0.7)
|
||||
local function _format_time_label(seconds)
|
||||
local total = math.max(0, math.floor(tonumber(seconds or 0) or 0))
|
||||
local hours = math.floor(total / 3600)
|
||||
local minutes = math.floor(total / 60) % 60
|
||||
local secs = total % 60
|
||||
local parts = {}
|
||||
if hours > 0 then
|
||||
table.insert(parts, ('%dh'):format(hours))
|
||||
end
|
||||
if minutes > 0 or hours > 0 then
|
||||
table.insert(parts, ('%dm'):format(minutes))
|
||||
end
|
||||
table.insert(parts, ('%ds'):format(secs))
|
||||
return table.concat(parts)
|
||||
end
|
||||
|
||||
local time = mp.get_property_number('time-pos') or mp.get_property_number('time') or 0
|
||||
local label = _format_time_label(time)
|
||||
|
||||
local raw_title = trim(tostring(mp.get_property('media-title') or ''))
|
||||
local raw_path = tostring(mp.get_property('path') or '')
|
||||
if raw_title == '' then
|
||||
raw_title = 'screenshot'
|
||||
end
|
||||
raw_title = _strip_title_extension(raw_title, raw_path)
|
||||
local safe_title = _sanitize_filename_component(raw_title)
|
||||
|
||||
local filename = safe_title .. '_' .. label .. '.png'
|
||||
local temp_dir = mp.get_property('user-data/medeia-config-temp') or os.getenv('TEMP') or os.getenv('TMP') or '/tmp'
|
||||
local out_path = utils.join_path(temp_dir, filename)
|
||||
|
||||
local ok = pcall(function()
|
||||
mp.commandv('screenshot-to-file', out_path, 'video')
|
||||
end)
|
||||
if not ok then
|
||||
mp.osd_message('Screenshot failed', 2)
|
||||
return
|
||||
end
|
||||
|
||||
_ensure_selected_store_loaded()
|
||||
local selected_store = _get_selected_store()
|
||||
selected_store = trim(tostring(selected_store or ''))
|
||||
selected_store = selected_store:gsub('^\"', ''):gsub('\"$', '')
|
||||
|
||||
if selected_store == '' then
|
||||
mp.osd_message('Select a store first (Store button)', 2)
|
||||
return
|
||||
end
|
||||
|
||||
local python_exe = _resolve_python_exe(true)
|
||||
if not python_exe or python_exe == '' then
|
||||
mp.osd_message('Screenshot saved; Python not found', 3)
|
||||
return
|
||||
end
|
||||
|
||||
local start_dir = mp.get_script_directory() or ''
|
||||
local cli_py = find_file_upwards(start_dir, 'CLI.py', 8)
|
||||
if not cli_py or cli_py == '' or not utils.file_info(cli_py) then
|
||||
mp.osd_message('Screenshot saved; CLI.py not found', 3)
|
||||
return
|
||||
end
|
||||
|
||||
local res = utils.subprocess({
|
||||
args = { python_exe, cli_py, 'add-file', '-store', selected_store, '-path', out_path },
|
||||
cancellable = false,
|
||||
})
|
||||
|
||||
if res and res.status == 0 then
|
||||
mp.osd_message('Screenshot saved to store: ' .. selected_store, 3)
|
||||
else
|
||||
local stderr = (res and res.stderr) or 'unknown error'
|
||||
mp.osd_message('Screenshot upload failed: ' .. tostring(stderr), 5)
|
||||
end
|
||||
end
|
||||
|
||||
mp.register_script_message('medeia-image-screenshot', function()
|
||||
@@ -2528,6 +2633,25 @@ mp.add_key_binding("L", "medeia-lyric-toggle-shift", lyric_toggle)
|
||||
mp.add_timeout(0, function()
|
||||
pcall(ensure_mpv_ipc_server)
|
||||
pcall(_lua_log, 'medeia-lua loaded version=' .. MEDEIA_LUA_VERSION)
|
||||
|
||||
-- Load optional modules (kept in separate files).
|
||||
pcall(function()
|
||||
local script_dir = mp.get_script_directory() or ''
|
||||
local candidates = {}
|
||||
if script_dir ~= '' then
|
||||
table.insert(candidates, script_dir .. '/sleep_timer.lua')
|
||||
table.insert(candidates, script_dir .. '/LUA/sleep_timer.lua')
|
||||
table.insert(candidates, script_dir .. '/../sleep_timer.lua')
|
||||
end
|
||||
table.insert(candidates, 'C:/medios/Medios-Macina/MPV/LUA/sleep_timer.lua')
|
||||
for _, p in ipairs(candidates) do
|
||||
local ok, chunk = pcall(loadfile, p)
|
||||
if ok and chunk then
|
||||
pcall(chunk)
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
return M
|
||||
|
||||
116
MPV/LUA/sleep_timer.lua
Normal file
116
MPV/LUA/sleep_timer.lua
Normal file
@@ -0,0 +1,116 @@
|
||||
local mp = require 'mp'
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
local SLEEP_MENU_TYPE = 'medeia_sleep_timer_prompt'
|
||||
|
||||
local _timer = nil
|
||||
|
||||
local function _trim(s)
|
||||
s = tostring(s or '')
|
||||
s = s:gsub('^%s+', '')
|
||||
s = s:gsub('%s+$', '')
|
||||
return s
|
||||
end
|
||||
|
||||
local function _cancel_timer()
|
||||
if _timer ~= nil then
|
||||
pcall(function()
|
||||
_timer:kill()
|
||||
end)
|
||||
_timer = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function _parse_minutes(text)
|
||||
local s = _trim(text)
|
||||
if s == '' then
|
||||
return nil
|
||||
end
|
||||
|
||||
local lower = s:lower()
|
||||
|
||||
-- allow: 15, 15m, 1h, 1.5h
|
||||
local hours = lower:match('^([%d%.]+)%s*h$')
|
||||
if hours then
|
||||
local v = tonumber(hours)
|
||||
if v and v > 0 then
|
||||
return v * 60
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local mins = lower:match('^([%d%.]+)%s*m$')
|
||||
if mins then
|
||||
local v = tonumber(mins)
|
||||
if v and v > 0 then
|
||||
return v
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local v = tonumber(lower)
|
||||
if v and v > 0 then
|
||||
return v
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function _open_prompt()
|
||||
local menu_data = {
|
||||
type = SLEEP_MENU_TYPE,
|
||||
title = 'Sleep Timer',
|
||||
search_style = 'palette',
|
||||
search_debounce = 'submit',
|
||||
on_search = 'callback',
|
||||
footnote = 'Enter minutes (e.g. 30) then press Enter.',
|
||||
callback = { mp.get_script_name(), 'medeia-sleep-timer-event' },
|
||||
items = {},
|
||||
}
|
||||
|
||||
local json = utils.format_json(menu_data)
|
||||
local ok = pcall(function()
|
||||
mp.commandv('script-message-to', 'uosc', 'open-menu', json)
|
||||
end)
|
||||
if not ok then
|
||||
mp.osd_message('Sleep timer: uosc not available', 2.0)
|
||||
end
|
||||
end
|
||||
|
||||
local function _handle_event(json)
|
||||
local ok, ev = pcall(utils.parse_json, json)
|
||||
if not ok or type(ev) ~= 'table' then
|
||||
return
|
||||
end
|
||||
if ev.type ~= 'search' then
|
||||
return
|
||||
end
|
||||
|
||||
local minutes = _parse_minutes(ev.query or '')
|
||||
if not minutes then
|
||||
mp.osd_message('Sleep timer cancelled', 1.0)
|
||||
_cancel_timer()
|
||||
return
|
||||
end
|
||||
|
||||
_cancel_timer()
|
||||
|
||||
local seconds = math.floor(minutes * 60)
|
||||
_timer = mp.add_timeout(seconds, function()
|
||||
mp.osd_message('Sleep timer: closing mpv', 1.5)
|
||||
mp.commandv('quit')
|
||||
end)
|
||||
|
||||
mp.osd_message(string.format('Sleep timer set: %d min', math.floor(minutes + 0.5)), 1.5)
|
||||
|
||||
pcall(function()
|
||||
mp.commandv('script-message-to', 'uosc', 'close-menu', SLEEP_MENU_TYPE)
|
||||
end)
|
||||
end
|
||||
|
||||
mp.register_script_message('medeia-sleep-timer', _open_prompt)
|
||||
mp.register_script_message('medeia-sleep-timer-event', _handle_event)
|
||||
|
||||
return {
|
||||
open_prompt = _open_prompt,
|
||||
}
|
||||
@@ -10,10 +10,8 @@ local trim = {}
|
||||
-- Configuration for trim presets
|
||||
trim.config = {
|
||||
output_dir = os.getenv('TEMP') or os.getenv('TMP') or '/tmp', -- use temp dir by default
|
||||
video_codec = "copy", -- lossless by default
|
||||
audio_codec = "copy",
|
||||
container = "auto",
|
||||
audio_bitrate = "",
|
||||
scale = "640:-2", -- Scale to 640 width, -2 ensures even height for codec
|
||||
osd_duration = 2000,
|
||||
}
|
||||
|
||||
@@ -26,7 +24,7 @@ trim.presets = {
|
||||
tiny = { video_codec="libx264", crf="28", preset="ultrafast", audio_codec="aac", audio_bitrate="64k" },
|
||||
}
|
||||
|
||||
trim.current_quality = "copy"
|
||||
trim.current_quality = "medium"
|
||||
|
||||
-- Get active preset with current quality
|
||||
local function _get_active_preset()
|
||||
|
||||
@@ -84,7 +84,7 @@ progress_line_width=20
|
||||
# fullscreen = cycle:crop_free:fullscreen:no/yes=fullscreen_exit!?Fullscreen
|
||||
# loop-playlist = cycle:repeat:loop-playlist:no/inf!?Loop playlist
|
||||
# toggle:{icon}:{prop} = cycle:{icon}:{prop}:no/yes!
|
||||
controls=menu,gap,<video,audio>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,gap,shuffle,gap,prev,items,next,space,command:photo_camera:script-message medeia-image-screenshot?Screenshot,command:content_cut:script-message medeia-image-clip?Clip Marker,command:headset:script-message medeia-audio-only?Audio,command:store:script-message medeia-store-picker?Store
|
||||
controls=menu,gap,<video,audio>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,gap,shuffle,gap,prev,items,next,space,command:photo_camera:script-message medeia-image-screenshot?Screenshot,command:content_cut:script-message medeia-image-clip?Clip Marker,command:headset:script-message medeia-audio-only?Audio,command:store:script-message medeia-store-picker?Store,command:schedule:script-message medeia-sleep-timer?Sleep
|
||||
controls_size=32
|
||||
controls_margin=8
|
||||
controls_spacing=2
|
||||
|
||||
Reference in New Issue
Block a user