🔧 Updates to configs for mpv
This commit is contained in:
parent
ab6733fe95
commit
8789ffc5e8
3 changed files with 3570 additions and 4191 deletions
74
.config/mpv/lua-settings/mpv_thumbnail_script.conf
Normal file
74
.config/mpv/lua-settings/mpv_thumbnail_script.conf
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# The thumbnail cache directory.
|
||||
# On Windows this defaults to %TEMP%\mpv_thumbs_cache,
|
||||
# and on other platforms to /tmp/mpv_thumbs_cache.
|
||||
# The directory will be created automatically, but must be writeable!
|
||||
# Use absolute paths, and take note that environment variables like %TEMP% are unsupported (despite the default)!
|
||||
cache_directory=/tmp/my_mpv_thumbnails
|
||||
# THIS IS NOT A WINDOWS PATH. COMMENT IT OUT OR ADJUST IT YOURSELF.
|
||||
|
||||
# Whether to generate thumbnails automatically on video load, without a keypress
|
||||
# Defaults to yes
|
||||
# autogenerate=[yes/no]
|
||||
autogenerate=yes
|
||||
|
||||
# Only automatically thumbnail videos shorter than this (in seconds)
|
||||
# You will have to press T (or your own keybind) to enable the thumbnail previews
|
||||
# Set to 0 to disable the check, ie. thumbnail videos no matter how long they are
|
||||
# Defaults to 3600 (one hour)
|
||||
autogenerate_max_duration=3600
|
||||
|
||||
# Use mpv to generate thumbnail even if ffmpeg is found in PATH
|
||||
# ffmpeg is slightly faster than mpv but lacks support for ordered chapters in MKVs,
|
||||
# which can break the resulting thumbnails. You have been warned.
|
||||
# Defaults to yes (don't use ffmpeg)
|
||||
# prefer_mpv=[yes/no]
|
||||
prefer_mpv=yes
|
||||
|
||||
# Explicitly disable subtitles on the mpv sub-calls
|
||||
# mpv can and will by default render subtitles into the thumbnails.
|
||||
# If this is not what you wish, set mpv_no_sub to yes
|
||||
# Defaults to no
|
||||
mpv_no_sub=yes
|
||||
|
||||
# Enable to disable the built-in keybind ("T") to add your own, see after the block
|
||||
disable_keybinds=no
|
||||
|
||||
# The maximum dimensions of the thumbnails, in pixels
|
||||
# Defaults to 200 and 200
|
||||
thumbnail_width=200
|
||||
thumbnail_height=200
|
||||
|
||||
# The thumbnail count target
|
||||
# (This will result in a thumbnail every ~10 seconds for a 25 minute video)
|
||||
thumbnail_count=150
|
||||
|
||||
# The above target count will be adjusted by the minimum and
|
||||
# maximum time difference between thumbnails.
|
||||
# The thumbnail_count will be used to calculate a target separation,
|
||||
# and min/max_delta will be used to constrict it.
|
||||
|
||||
# In other words, thumbnails will be:
|
||||
# - at least min_delta seconds apart (limiting the amount)
|
||||
# - at most max_delta seconds apart (raising the amount if needed)
|
||||
# Defaults to 5 and 90, values are seconds
|
||||
min_delta=5
|
||||
max_delta=90
|
||||
# 120 seconds aka 2 minutes will add more thumbnails only when the video is over 5 hours long!
|
||||
|
||||
# Below are overrides for remote urls (you generally want less thumbnails, because it's slow!)
|
||||
# Thumbnailing network paths will be done with mpv (leveraging youtube-dl)
|
||||
|
||||
# Allow thumbnailing network paths (naive check for "://")
|
||||
# Defaults to no
|
||||
# thumbnail_network=[yes/no]
|
||||
thumbnail_network=no
|
||||
# Override thumbnail count, min/max delta, as above
|
||||
remote_thumbnail_count=60
|
||||
remote_min_delta=15
|
||||
remote_max_delta=120
|
||||
|
||||
# Try to grab the raw stream and disable ytdl for the mpv subcalls
|
||||
# Much faster than passing the url to ytdl again, but may cause problems with some sites
|
||||
# Defaults to yes
|
||||
# remote_direct_stream=[yes/no]
|
||||
remote_direct_stream=no
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -13,26 +13,26 @@
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]--
|
||||
]]
|
||||
--
|
||||
--[[
|
||||
mpv_thumbnail_script.lua unknown - commit unknown (branch unknown)
|
||||
mpv_thumbnail_script.lua 0.4.2 - commit a2de250 (branch master)
|
||||
https://github.com/TheAMM/mpv_thumbnail_script
|
||||
Built on 2023-11-14 05:54:49
|
||||
]]--
|
||||
local assdraw = require 'mp.assdraw'
|
||||
local msg = require 'mp.msg'
|
||||
local opt = require 'mp.options'
|
||||
local utils = require 'mp.utils'
|
||||
Built on 2018-02-07 20:36:54
|
||||
]]
|
||||
--
|
||||
local assdraw = require("mp.assdraw")
|
||||
local msg = require("mp.msg")
|
||||
local opt = require("mp.options")
|
||||
local utils = require("mp.utils")
|
||||
|
||||
-- Determine if the platform is Windows --
|
||||
ON_WINDOWS = (package.config:sub(1,1) ~= '/')
|
||||
|
||||
-- Determine if the platform is MacOS --
|
||||
local uname = io.popen("uname -s"):read("*l")
|
||||
ON_MAC = not ON_WINDOWS and (uname == "Mac" or uname == "Darwin")
|
||||
-- Determine platform --
|
||||
ON_WINDOWS = (package.config:sub(1, 1) ~= "/")
|
||||
|
||||
-- Some helper functions needed to parse the options --
|
||||
function isempty(v) return not v or (v == "") or (v == 0) or (type(v) == "table" and not next(v)) end
|
||||
function isempty(v)
|
||||
return (v == false) or (v == nil) or (v == "") or (v == 0) or (type(v) == "table" and next(v) == nil)
|
||||
end
|
||||
|
||||
function divmod(a, b)
|
||||
return math.floor(a / b), a % b
|
||||
|
|
@ -45,7 +45,7 @@ end
|
|||
|
||||
function join_paths(...)
|
||||
local sep = ON_WINDOWS and "\\" or "/"
|
||||
local result = "";
|
||||
local result = ""
|
||||
for i, p in pairs({ ... }) do
|
||||
if p ~= "" then
|
||||
if is_absolute_path(p) then
|
||||
|
|
@ -61,9 +61,9 @@ end
|
|||
-- /some/path/file.ext -> /some/path, file.ext
|
||||
function split_path(path)
|
||||
local sep = ON_WINDOWS and "\\" or "/"
|
||||
local first_index, last_index = path:find('^.*' .. sep)
|
||||
local first_index, last_index = path:find("^.*" .. sep)
|
||||
|
||||
if not last_index then
|
||||
if last_index == nil then
|
||||
return "", path
|
||||
else
|
||||
local dir = path:sub(0, last_index - 1)
|
||||
|
|
@ -81,7 +81,9 @@ end
|
|||
|
||||
function Set(source)
|
||||
local set = {}
|
||||
for _, l in ipairs(source) do set[l] = true end
|
||||
for _, l in ipairs(source) do
|
||||
set[l] = true
|
||||
end
|
||||
return set
|
||||
end
|
||||
|
||||
|
|
@ -111,10 +113,10 @@ end
|
|||
|
||||
function file_exists(name)
|
||||
local f = io.open(name, "rb")
|
||||
if f then
|
||||
if f ~= nil then
|
||||
local ok, err, code = f:read(1)
|
||||
io.close(f)
|
||||
return not code
|
||||
return code == nil
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
|
@ -122,7 +124,7 @@ end
|
|||
|
||||
function path_exists(name)
|
||||
local f = io.open(name, "rb")
|
||||
if f then
|
||||
if f ~= nil then
|
||||
io.close(f)
|
||||
return true
|
||||
else
|
||||
|
|
@ -166,7 +168,7 @@ local ExecutableFinder = { path_cache = {} }
|
|||
function ExecutableFinder:get_executable_path(name, raw_name)
|
||||
name = ON_WINDOWS and not raw_name and (name .. ".exe") or name
|
||||
|
||||
if not self.path_cache[name] then
|
||||
if self.path_cache[name] == nil then
|
||||
self.path_cache[name] = find_executable(name) or false
|
||||
end
|
||||
return self.path_cache[name]
|
||||
|
|
@ -174,8 +176,8 @@ end
|
|||
|
||||
-- Format seconds to HH.MM.SS.sss
|
||||
function format_time(seconds, sep, decimals)
|
||||
decimals = decimals or 3
|
||||
sep = sep or "."
|
||||
decimals = decimals == nil and 3 or decimals
|
||||
sep = sep and sep or "."
|
||||
local s = seconds
|
||||
local h, s = divmod(s, 60 * 60)
|
||||
local m, s = divmod(s, 60)
|
||||
|
|
@ -187,8 +189,8 @@ end
|
|||
|
||||
-- Format seconds to 1h 2m 3.4s
|
||||
function format_time_hms(seconds, sep, decimals, force_full)
|
||||
decimals = decimals or 1
|
||||
sep = sep or " "
|
||||
decimals = decimals == nil and 1 or decimals
|
||||
sep = sep ~= nil and sep or " "
|
||||
|
||||
local s = seconds
|
||||
local h, s = divmod(s, 60 * 60)
|
||||
|
|
@ -272,7 +274,6 @@ function create_temporary_file(base, mode, suffix)
|
|||
return handle, filename
|
||||
end
|
||||
|
||||
|
||||
function get_processor_count()
|
||||
local proc_count
|
||||
|
||||
|
|
@ -280,15 +281,17 @@ function get_processor_count()
|
|||
proc_count = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
local cpuinfo_handle = io.open("/proc/cpuinfo")
|
||||
if cpuinfo_handle then
|
||||
if cpuinfo_handle ~= nil then
|
||||
local cpuinfo_contents = cpuinfo_handle:read("*a")
|
||||
local _, replace_count = cpuinfo_contents:gsub('processor', '')
|
||||
local _, replace_count = cpuinfo_contents:gsub("processor", "")
|
||||
proc_count = replace_count
|
||||
end
|
||||
end
|
||||
|
||||
if proc_count and proc_count > 0 then
|
||||
return proc_count
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -302,7 +305,7 @@ function substitute_values(string, values)
|
|||
end
|
||||
end
|
||||
|
||||
local substituted = string:gsub('%%(.)', substitutor)
|
||||
local substituted = string:gsub("%%(.)", substitutor)
|
||||
return substituted
|
||||
end
|
||||
|
||||
|
|
@ -344,7 +347,7 @@ function round_rect(ass, x0, y0, x1, y1, rtl, rtr, rbr, rbl)
|
|||
end
|
||||
local SCRIPT_NAME = "mpv_thumbnail_script"
|
||||
|
||||
local default_cache_base = ON_WINDOWS and os.getenv("TEMP") or (os.getenv("XDG_CACHE_HOME") or "/tmp/")
|
||||
local default_cache_base = ON_WINDOWS and os.getenv("TEMP") or "/tmp/"
|
||||
|
||||
local thumbnailer_options = {
|
||||
-- The thumbnail directory
|
||||
|
|
@ -377,10 +380,6 @@ local thumbnailer_options = {
|
|||
-- Add a "--profile=<mpv_profile>" to the mpv sub-call arguments
|
||||
-- Use "" to disable
|
||||
mpv_profile = "",
|
||||
-- Hardware decoding
|
||||
mpv_hwdec = "no",
|
||||
-- High precision seek
|
||||
mpv_hr_seek = "yes",
|
||||
-- Output debug logs to <thumbnail_path>.log, ala <cache_directory>/<video_filename>/000000.bgra.log
|
||||
-- The logs are removed after successful encodes, unless you set mpv_keep_logs below
|
||||
mpv_logs = true,
|
||||
|
|
@ -450,14 +449,11 @@ local thumbnailer_options = {
|
|||
-- 120 seconds aka 2 minutes will add more thumbnails when the video is over 5 hours!
|
||||
max_delta = 90,
|
||||
|
||||
|
||||
-- Overrides for remote urls (you generally want less thumbnails!)
|
||||
-- Thumbnailing network paths will be done with mpv
|
||||
|
||||
-- Allow thumbnailing network paths (naive check for "://")
|
||||
thumbnail_network = false,
|
||||
-- Same as autogenerate_max_duration but for remote videos
|
||||
remote_autogenerate_max_duration = 1200, -- 20 min
|
||||
-- Override thumbnail count, min/max delta
|
||||
remote_thumbnail_count = 60,
|
||||
remote_min_delta = 15,
|
||||
|
|
@ -466,13 +462,6 @@ local thumbnailer_options = {
|
|||
-- Try to grab the raw stream and disable ytdl for the mpv subcalls
|
||||
-- Much faster than passing the url to ytdl again, but may cause problems with some sites
|
||||
remote_direct_stream = true,
|
||||
|
||||
-- Enable storyboards (requires yt-dlp in PATH). Currently only supports YouTube and Twitch VoDs
|
||||
storyboard_enable = true,
|
||||
-- Max thumbnails for storyboards. It only skips processing some of the downloaded thumbnails and doesn't make it much faster
|
||||
storyboard_max_thumbnail_count = 800,
|
||||
-- Most storyboard thumbnails are 160x90. Enabling this allows upscaling them up to thumbnail_height
|
||||
storyboard_upscale = false,
|
||||
}
|
||||
|
||||
read_options(thumbnailer_options, SCRIPT_NAME)
|
||||
|
|
@ -487,8 +476,8 @@ end
|
|||
function create_thumbnail_mpv(file_path, timestamp, size, output_path, options)
|
||||
options = options or {}
|
||||
|
||||
local ytdl_disabled = not options.enable_ytdl and (mp.get_property_native("ytdl") == false
|
||||
or thumbnailer_options.remote_direct_stream)
|
||||
local ytdl_disabled = not options.enable_ytdl
|
||||
and (mp.get_property_native("ytdl") == false or thumbnailer_options.remote_direct_stream)
|
||||
|
||||
local header_fields_arg = nil
|
||||
local header_fields = mp.get_property_native("http-header-fields")
|
||||
|
|
@ -504,10 +493,8 @@ function create_thumbnail_mpv(file_path, timestamp, size, output_path, options)
|
|||
|
||||
local log_arg = "--log-file=" .. output_path .. ".log"
|
||||
|
||||
local mpv_path = ON_MAC and "/opt/homebrew/bin/mpv" or "mpv"
|
||||
|
||||
local mpv_command = skip_nil{
|
||||
mpv_path,
|
||||
local mpv_command = skip_nil({
|
||||
"mpv",
|
||||
-- Hide console output
|
||||
"--msg-level=all=no",
|
||||
|
||||
|
|
@ -518,68 +505,63 @@ function create_thumbnail_mpv(file_path, timestamp, size, output_path, options)
|
|||
-- Pass User-Agent and Referer - should do no harm even with ytdl active
|
||||
"--user-agent=" .. mp.get_property_native("user-agent"),
|
||||
"--referrer=" .. mp.get_property_native("referrer"),
|
||||
-- User set hardware decoding
|
||||
"--hwdec=" .. thumbnailer_options.mpv_hwdec,
|
||||
-- Disable hardware decoding
|
||||
"--hwdec=no",
|
||||
|
||||
-- Insert --no-config, --profile=... and --log-file if enabled
|
||||
(thumbnailer_options.mpv_no_config and "--no-config" or nil),
|
||||
profile_arg,
|
||||
(thumbnailer_options.mpv_logs and log_arg or nil),
|
||||
|
||||
file_path,
|
||||
|
||||
"--start=" .. tostring(timestamp),
|
||||
"--frames=1",
|
||||
"--hr-seek=" .. thumbnailer_options.mpv_hr_seek,
|
||||
"--hr-seek=yes",
|
||||
"--no-audio",
|
||||
-- Optionally disable subtitles
|
||||
(thumbnailer_options.mpv_no_sub and "--no-sub" or nil),
|
||||
|
||||
(options.relative_scale
|
||||
and ("--vf=scale=iw*%d:ih*%d"):format(size.w, size.h)
|
||||
or ("--vf=scale=%d:%d"):format(size.w, size.h)),
|
||||
|
||||
("--vf=scale=%d:%d"):format(size.w, size.h),
|
||||
"--vf-add=format=bgra",
|
||||
"--of=rawvideo",
|
||||
"--ovc=rawvideo",
|
||||
("--o=%s"):format(output_path),
|
||||
|
||||
"--",
|
||||
|
||||
file_path,
|
||||
}
|
||||
return mp.command_native{name="subprocess", args=mpv_command}
|
||||
-- "--o",
|
||||
output_path,
|
||||
})
|
||||
return utils.subprocess({ args = mpv_command })
|
||||
end
|
||||
|
||||
|
||||
function create_thumbnail_ffmpeg(file_path, timestamp, size, output_path, options)
|
||||
options = options or {}
|
||||
|
||||
local ffmpeg_path = ON_MAC and "/opt/homebrew/bin/ffmpeg" or "ffmpeg"
|
||||
|
||||
function create_thumbnail_ffmpeg(file_path, timestamp, size, output_path)
|
||||
local ffmpeg_command = {
|
||||
ffmpeg_path,
|
||||
"-loglevel", "quiet",
|
||||
"ffmpeg",
|
||||
"-loglevel",
|
||||
"quiet",
|
||||
"-noaccurate_seek",
|
||||
"-ss", format_time(timestamp, ":"),
|
||||
"-i", file_path,
|
||||
"-ss",
|
||||
format_time(timestamp, ":"),
|
||||
"-i",
|
||||
file_path,
|
||||
|
||||
"-frames:v", "1",
|
||||
"-frames:v",
|
||||
"1",
|
||||
"-an",
|
||||
|
||||
"-vf",
|
||||
(options.relative_scale
|
||||
and ("scale=iw*%d:ih*%d"):format(size.w, size.h)
|
||||
or ("scale=%d:%d"):format(size.w, size.h)),
|
||||
("scale=%d:%d"):format(size.w, size.h),
|
||||
"-c:v",
|
||||
"rawvideo",
|
||||
"-pix_fmt",
|
||||
"bgra",
|
||||
"-f",
|
||||
"rawvideo",
|
||||
|
||||
"-c:v", "rawvideo",
|
||||
"-pix_fmt", "bgra",
|
||||
"-f", "rawvideo",
|
||||
|
||||
"-y", output_path,
|
||||
"-y",
|
||||
output_path,
|
||||
}
|
||||
return mp.command_native{name="subprocess", args=ffmpeg_command}
|
||||
return utils.subprocess({ args = ffmpeg_command })
|
||||
end
|
||||
|
||||
|
||||
function check_output(ret, output_path, is_mpv)
|
||||
local log_path = output_path .. ".log"
|
||||
local success = true
|
||||
|
|
@ -587,6 +569,7 @@ function check_output(ret, output_path, is_mpv)
|
|||
if ret.killed_by_us then
|
||||
return nil
|
||||
else
|
||||
print("ret.status :=>", ret.status)
|
||||
if ret.error or ret.status ~= 0 then
|
||||
msg.error("Thumbnailing command failed!")
|
||||
msg.error("mpv process error:", ret.error)
|
||||
|
|
@ -595,12 +578,12 @@ function check_output(ret, output_path, is_mpv)
|
|||
msg.error("Debug log:", log_path)
|
||||
end
|
||||
|
||||
success = false
|
||||
-- success = false
|
||||
end
|
||||
|
||||
if not file_exists(output_path) then
|
||||
if not file_exists(log_path) then
|
||||
msg.error("Output file missing!", output_path)
|
||||
success = false
|
||||
-- success = false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -614,31 +597,6 @@ function check_output(ret, output_path, is_mpv)
|
|||
return success
|
||||
end
|
||||
|
||||
-- split cols x N atlas in BGRA format into many thumbnail files
|
||||
function split_atlas(atlas_path, cols, thumbnail_size, output_name)
|
||||
local atlas = io.open(atlas_path, "rb")
|
||||
local atlas_filesize = atlas:seek("end")
|
||||
local atlas_pictures = math.floor(atlas_filesize / (4 * thumbnail_size.w * thumbnail_size.h))
|
||||
local stride = 4 * thumbnail_size.w * math.min(cols, atlas_pictures)
|
||||
for pic = 0, atlas_pictures-1 do
|
||||
local x_start = (pic % cols) * thumbnail_size.w
|
||||
local y_start = math.floor(pic / cols) * thumbnail_size.h
|
||||
local filename = output_name(pic)
|
||||
if filename then
|
||||
local thumb_file = io.open(filename, "wb")
|
||||
for line = 0, thumbnail_size.h - 1 do
|
||||
atlas:seek("set", 4 * x_start + (y_start + line) * stride)
|
||||
local data = atlas:read(thumbnail_size.w * 4)
|
||||
if data then
|
||||
thumb_file:write(data)
|
||||
end
|
||||
end
|
||||
thumb_file:close()
|
||||
end
|
||||
end
|
||||
atlas:close()
|
||||
end
|
||||
|
||||
function do_worker_job(state_json_string, frames_json_string)
|
||||
msg.debug("Handling given job")
|
||||
local thumb_state, err = utils.parse_json(state_json_string)
|
||||
|
|
@ -665,8 +623,8 @@ function do_worker_job(state_json_string, frames_json_string)
|
|||
local file_duration = mp.get_property_native("duration")
|
||||
local file_path = thumb_state.worker_input_path
|
||||
|
||||
if thumb_state.is_remote and not thumb_state.storyboard then
|
||||
if (thumbnail_func == create_thumbnail_ffmpeg) then
|
||||
if thumb_state.is_remote then
|
||||
if thumbnail_func == create_thumbnail_ffmpeg then
|
||||
msg.warn("Thumbnailing remote path, falling back on mpv.")
|
||||
end
|
||||
thumbnail_func = create_thumbnail_mpv
|
||||
|
|
@ -690,7 +648,7 @@ function do_worker_job(state_json_string, frames_json_string)
|
|||
|
||||
-- Check if the thumbnail already exists and is the correct size
|
||||
local thumbnail_file = io.open(thumbnail_path, "rb")
|
||||
if not thumbnail_file then
|
||||
if thumbnail_file == nil then
|
||||
need_thumbnail_generation = true
|
||||
else
|
||||
local existing_thumbnail_filesize = thumbnail_file:seek("end")
|
||||
|
|
@ -703,35 +661,16 @@ function do_worker_job(state_json_string, frames_json_string)
|
|||
end
|
||||
|
||||
if need_thumbnail_generation then
|
||||
local success
|
||||
if thumb_state.storyboard then
|
||||
-- get atlas and then split it into thumbnails
|
||||
local rows = thumb_state.storyboard.rows
|
||||
local cols = thumb_state.storyboard.cols
|
||||
local div = thumb_state.storyboard.divisor
|
||||
local atlas_idx = math.floor(thumb_idx * div /(cols*rows))
|
||||
local atlas_path = thumb_state.thumbnail_template:format(atlas_idx) .. ".atlas"
|
||||
local url = thumb_state.storyboard.fragments[atlas_idx+1].url
|
||||
if not url then
|
||||
url = thumb_state.storyboard.fragment_base_url .. "/" .. thumb_state.storyboard.fragments[atlas_idx+1].path
|
||||
end
|
||||
local ret = thumbnail_func(url, 0, { w=thumb_state.storyboard.scale, h=thumb_state.storyboard.scale }, atlas_path, { relative_scale=true })
|
||||
success = check_output(ret, atlas_path, thumbnail_func == create_thumbnail_mpv)
|
||||
if success then
|
||||
split_atlas(atlas_path, cols, thumb_state.thumbnail_size, function(idx)
|
||||
if (atlas_idx * cols * rows + idx) % div ~= 0 then
|
||||
return nil
|
||||
end
|
||||
return thumb_state.thumbnail_template:format(math.floor((atlas_idx * cols * rows + idx) / div))
|
||||
end)
|
||||
os.remove(atlas_path)
|
||||
end
|
||||
else
|
||||
local ret = thumbnail_func(file_path, timestamp, thumb_state.thumbnail_size, thumbnail_path, thumb_state.worker_extra)
|
||||
success = check_output(ret, thumbnail_path, thumbnail_func == create_thumbnail_mpv)
|
||||
end
|
||||
local ret = thumbnail_func(
|
||||
file_path,
|
||||
timestamp,
|
||||
thumb_state.thumbnail_size,
|
||||
thumbnail_path,
|
||||
thumb_state.worker_extra
|
||||
)
|
||||
local success = check_output(ret, thumbnail_path, thumbnail_func == create_thumbnail_mpv)
|
||||
|
||||
if not success then
|
||||
if success == nil then
|
||||
-- Killed by us, changing files, ignore
|
||||
msg.debug("Changing files, subprocess killed")
|
||||
return true
|
||||
|
|
@ -749,7 +688,7 @@ function do_worker_job(state_json_string, frames_json_string)
|
|||
thumbnail_file = io.open(thumbnail_path, "rb")
|
||||
|
||||
-- Bail if we can't read the file (it should really exist by now, we checked this in check_output!)
|
||||
if not thumbnail_file then
|
||||
if thumbnail_file == nil then
|
||||
msg.error("Thumbnail suddenly disappeared!")
|
||||
return true
|
||||
end
|
||||
|
|
@ -761,9 +700,14 @@ function do_worker_job(state_json_string, frames_json_string)
|
|||
-- Check if the file is big enough
|
||||
local missing_bytes = math.max(0, thumbnail_raw_size - thumbnail_file_size)
|
||||
if missing_bytes > 0 then
|
||||
msg.warn(("Thumbnail missing %d bytes (expected %d, had %d), padding %s"):format(
|
||||
missing_bytes, thumbnail_raw_size, thumbnail_file_size, thumbnail_path
|
||||
))
|
||||
msg.warn(
|
||||
("Thumbnail missing %d bytes (expected %d, had %d), padding %s"):format(
|
||||
missing_bytes,
|
||||
thumbnail_raw_size,
|
||||
thumbnail_file_size,
|
||||
thumbnail_path
|
||||
)
|
||||
)
|
||||
-- Pad the file if it's missing content (eg. ffmpeg seek to file end)
|
||||
thumbnail_file = io.open(thumbnail_path, "ab")
|
||||
thumbnail_file:write(string.rep(string.char(0), missing_bytes))
|
||||
|
|
@ -774,17 +718,21 @@ function do_worker_job(state_json_string, frames_json_string)
|
|||
mp.commandv("script-message", "mpv_thumbnail_script-ready", tostring(thumbnail_index), thumbnail_path)
|
||||
end
|
||||
|
||||
msg.debug(("Generating %d thumbnails @ %dx%d for %q"):format(
|
||||
msg.debug(
|
||||
("Generating %d thumbnails @ %dx%d for %q"):format(
|
||||
#thumbnail_indexes,
|
||||
thumb_state.thumbnail_size.w,
|
||||
thumb_state.thumbnail_size.h,
|
||||
file_path))
|
||||
file_path
|
||||
)
|
||||
)
|
||||
|
||||
for i, thumbnail_index in ipairs(thumbnail_indexes) do
|
||||
local bail = generate_thumbnail_for_index(thumbnail_index)
|
||||
if bail then return end
|
||||
if bail then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Set up listeners and keybinds
|
||||
|
|
@ -792,7 +740,6 @@ end
|
|||
-- Job listener
|
||||
mp.register_script_message("mpv_thumbnail_script-job", do_worker_job)
|
||||
|
||||
|
||||
-- Register this worker with the master script
|
||||
local register_timer = nil
|
||||
local register_timeout = mp.get_time() + 1.5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue