diff options
Diffstat (limited to 'TOOLS')
-rwxr-xr-x | TOOLS/gen-interface-changes.py | 18 | ||||
-rwxr-xr-x | TOOLS/gen-mpv-desktop.py | 45 | ||||
-rw-r--r-- | TOOLS/lua/acompressor.lua | 9 | ||||
-rw-r--r-- | TOOLS/lua/ao-null-reload.lua | 6 | ||||
-rw-r--r-- | TOOLS/lua/audio-hotplug-test.lua | 6 | ||||
-rw-r--r-- | TOOLS/lua/autocrop.lua | 103 | ||||
-rw-r--r-- | TOOLS/lua/autodeint.lua | 75 | ||||
-rw-r--r-- | TOOLS/lua/autoload.lua | 229 | ||||
-rw-r--r-- | TOOLS/lua/command-test.lua | 27 | ||||
-rw-r--r-- | TOOLS/lua/cycle-deinterlace-pullup.lua | 12 | ||||
-rw-r--r-- | TOOLS/lua/nan-test.lua | 6 | ||||
-rw-r--r-- | TOOLS/lua/observe-all.lua | 10 | ||||
-rw-r--r-- | TOOLS/lua/ontop-playback.lua | 2 | ||||
-rw-r--r-- | TOOLS/lua/osd-test.lua | 2 | ||||
-rw-r--r-- | TOOLS/lua/pause-when-minimize.lua | 2 | ||||
-rw-r--r-- | TOOLS/lua/skip-logo.lua | 18 | ||||
-rw-r--r-- | TOOLS/lua/status-line.lua | 12 | ||||
-rw-r--r-- | TOOLS/lua/test-hooks.lua | 6 | ||||
-rw-r--r-- | TOOLS/osxbundle/mpv.app/Contents/Info.plist | 628 |
19 files changed, 781 insertions, 435 deletions
diff --git a/TOOLS/gen-interface-changes.py b/TOOLS/gen-interface-changes.py index 7f5435e216..3a415192af 100755 --- a/TOOLS/gen-interface-changes.py +++ b/TOOLS/gen-interface-changes.py @@ -22,6 +22,7 @@ import pathlib import sys +import textwrap from shutil import which from subprocess import check_output @@ -33,16 +34,19 @@ def add_new_entries(docs_dir, out, git): timestamp = check_output([git, "log", "--format=%ct", "-n", "1", "--", f], encoding="UTF-8") if timestamp: - files.append((f, timestamp)) + content = f.read_text() + files.append(content) else: print(f"Skipping file not tracked by git: {f.name}") - files.sort(key=lambda x: x[1]) - for file in files: - with open(file[0].resolve(), "r") as f: - for line in f: - line = " - " + line.rstrip() - out.write(line + "\n") + # Sort the changes by "severity", which roughly corresponds to + # alphabetical order by accident (e.g. remove > deprecate > change > add) + for file in reversed(sorted(files)): + for line in file.splitlines(): + line = textwrap.fill(line.rstrip(), width=80, + initial_indent=" - ", + subsequent_indent=" ") + out.write(line + "\n") if __name__ == "__main__": if len(sys.argv) < 2: diff --git a/TOOLS/gen-mpv-desktop.py b/TOOLS/gen-mpv-desktop.py new file mode 100755 index 0000000000..2b05de1ec4 --- /dev/null +++ b/TOOLS/gen-mpv-desktop.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# Modify X-KDE-Protocols in the mpv.desktop file based on output from +# mpv --list-protocols. + +# +# This file is part of mpv. +# +# mpv is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# mpv is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with mpv. If not, see <http://www.gnu.org/licenses/>. +# + +import sys +from subprocess import check_output + +if __name__ == "__main__": + with open(sys.argv[1], "r", encoding="UTF-8") as f: + next(f) + mpv_desktop = dict([line.split("=", 1) for line in f]) + + if not mpv_desktop["X-KDE-Protocols"]: + raise ValueError("Missing X-KDE-Protocols entry in mpv.desktop file") + + mpv_protocols = check_output([sys.argv[2], "--list-protocols"], encoding="UTF-8") + mpv_protocols = set(line.strip(" :/") for line in mpv_protocols.splitlines() if "://" in line) + if len(mpv_protocols) == 0: + raise ValueError("Unable to parse any protocols from mpv '--list-protocols'") + + protocol_list = set(mpv_desktop["X-KDE-Protocols"].strip().split(",")) + mpv_desktop["X-KDE-Protocols"] = ",".join(sorted(mpv_protocols & protocol_list)) + "\n" + + with open(sys.argv[3], "w", encoding="UTF-8") as f: + f.write("[Desktop Entry]" + "\n") + for key, value in mpv_desktop.items(): + f.write(f"{key}={value}") diff --git a/TOOLS/lua/acompressor.lua b/TOOLS/lua/acompressor.lua index 6a6914076a..e94dc3e0fb 100644 --- a/TOOLS/lua/acompressor.lua +++ b/TOOLS/lua/acompressor.lua @@ -53,8 +53,10 @@ local params = { } local function parse_value(value) - -- Using nil here because tonumber differs between lua 5.1 and 5.2 when parsing fractions in combination with explicit base argument set to 10. - -- And we can't omit it because gsub returns 2 values which would get unpacked and cause more problems. Gotta love scripting languages. + -- Using nil here because tonumber differs between lua 5.1 and 5.2 when + -- parsing fractions in combination with explicit base argument set to 10. + -- And we can't omit it because gsub returns 2 values which would get + -- unpacked and cause more problems. Gotta love scripting languages. return tonumber(value:gsub('dB$', ''), nil) end @@ -76,7 +78,8 @@ local function show_osd(filter) for _,param in ipairs(params) do local value = parse_value(filter.params[param.name]) if not (param.hide_default and value == o['default_' .. param.name]) then - pretty[#pretty+1] = string.format('%s: %g%s', param.name:gsub("^%l", string.upper), value, param.dB) + pretty[#pretty+1] = string.format('%s: %g%s', param.name:gsub("^%l", string.upper), + value, param.dB) end end diff --git a/TOOLS/lua/ao-null-reload.lua b/TOOLS/lua/ao-null-reload.lua index 5b2330b517..6809bb3a25 100644 --- a/TOOLS/lua/ao-null-reload.lua +++ b/TOOLS/lua/ao-null-reload.lua @@ -3,12 +3,14 @@ -- particular for ao=wasapi, since the internal IMMNotificationClient code that -- normally triggers ao-reload will not be running in this case. -function do_reload() +local reloading + +local function do_reload() mp.command("ao-reload") reloading = nil end -function on_audio_device_list_change() +local function on_audio_device_list_change() if mp.get_property("current-ao") == "null" and not reloading then mp.msg.verbose("audio-device-list changed: reloading audio") -- avoid calling ao-reload too often diff --git a/TOOLS/lua/audio-hotplug-test.lua b/TOOLS/lua/audio-hotplug-test.lua index 8dedc68cbe..e0ef223c0c 100644 --- a/TOOLS/lua/audio-hotplug-test.lua +++ b/TOOLS/lua/audio-hotplug-test.lua @@ -1,8 +1,6 @@ -local utils = require("mp.utils") - -mp.observe_property("audio-device-list", "native", function(name, val) +mp.observe_property("audio-device-list", "native", function(_, val) print("Audio device list changed:") - for index, e in ipairs(val) do + for _, e in ipairs(val) do print(" - '" .. e.name .. "' (" .. e.description .. ")") end end) diff --git a/TOOLS/lua/autocrop.lua b/TOOLS/lua/autocrop.lua index ea57d15658..ba38f487cc 100644 --- a/TOOLS/lua/autocrop.lua +++ b/TOOLS/lua/autocrop.lua @@ -56,7 +56,7 @@ require "mp.options".read_options(options) local cropdetect_label = mp.get_script_name() .. "-cropdetect" -timers = { +local timers = { auto_delay = nil, detect_crop = nil } @@ -65,8 +65,7 @@ local hwdec_backup local command_prefix = options.suppress_osd and 'no-osd' or '' -function is_enough_time(seconds) - +local function is_enough_time(seconds) -- Plus 1 second for deviation. local time_needed = seconds + 1 local playtime_remaining = mp.get_property_native("playtime-remaining") @@ -74,7 +73,7 @@ function is_enough_time(seconds) return playtime_remaining and time_needed < playtime_remaining end -function is_cropable(time_needed) +local function is_cropable(time_needed) if mp.get_property_native('current-tracks/video/image') ~= false then mp.msg.warn("autocrop only works for videos.") return false @@ -88,7 +87,7 @@ function is_cropable(time_needed) return true end -function remove_cropdetect() +local function remove_cropdetect() for _, filter in pairs(mp.get_property_native("vf")) do if filter.label == cropdetect_label then mp.command( @@ -99,14 +98,14 @@ function remove_cropdetect() end end -function restore_hwdec() +local function restore_hwdec() if hwdec_backup then mp.set_property("hwdec", hwdec_backup) hwdec_backup = nil end end -function cleanup() +local function cleanup() remove_cropdetect() -- Kill all timers. @@ -120,37 +119,32 @@ function cleanup() restore_hwdec() end -function detect_crop() - local time_needed = options.detect_seconds +local function apply_crop(meta) + -- Verify if it is necessary to crop. + local is_effective = meta.w and meta.h and meta.x and meta.y and + (meta.x > 0 or meta.y > 0 + or meta.w < meta.max_w or meta.h < meta.max_h) - if not is_cropable(time_needed) then - return + -- Verify it is not over cropped. + local is_excessive = false + if is_effective and (meta.w < meta.min_w or meta.h < meta.min_h) then + mp.msg.info("The area to be cropped is too large.") + mp.msg.info("You might need to decrease detect_min_ratio.") + is_excessive = true end - local hwdec_current = mp.get_property("hwdec-current") - if hwdec_current:find("-copy$") == nil and hwdec_current ~= "no" and - hwdec_current ~= "crystalhd" and hwdec_current ~= "rkmpp" then - hwdec_backup = mp.get_property("hwdec") - mp.set_property("hwdec", "no") + if not is_effective or is_excessive then + -- Clear any existing crop. + mp.command(string.format("%s set file-local-options/video-crop ''", command_prefix)) + return end - -- Insert the cropdetect filter. - local limit = options.detect_limit - local round = options.detect_round - - mp.command( - string.format( - '%s vf pre @%s:cropdetect=limit=%s:round=%d:reset=0', - command_prefix, cropdetect_label, limit, round - ) - ) - - -- Wait to gather data. - timers.detect_crop = mp.add_timeout(time_needed, detect_end) + -- Apply crop. + mp.command(string.format("%s set file-local-options/video-crop %sx%s+%s+%s", + command_prefix, meta.w, meta.h, meta.x, meta.y)) end -function detect_end() - +local function detect_end() -- Get the metadata and remove the cropdetect filter. local cropdetect_metadata = mp.get_property_native( "vf-metadata/" .. cropdetect_label) @@ -164,7 +158,7 @@ function detect_end() restore_hwdec() - local meta = {} + local meta -- Verify the existence of metadata. if cropdetect_metadata then @@ -204,33 +198,36 @@ function detect_end() apply_crop(meta) end -function apply_crop(meta) - - -- Verify if it is necessary to crop. - local is_effective = meta.w and meta.h and meta.x and meta.y and - (meta.x > 0 or meta.y > 0 - or meta.w < meta.max_w or meta.h < meta.max_h) +local function detect_crop() + local time_needed = options.detect_seconds - -- Verify it is not over cropped. - local is_excessive = false - if is_effective and (meta.w < meta.min_w or meta.h < meta.min_h) then - mp.msg.info("The area to be cropped is too large.") - mp.msg.info("You might need to decrease detect_min_ratio.") - is_excessive = true + if not is_cropable(time_needed) then + return end - if not is_effective or is_excessive then - -- Clear any existing crop. - mp.command(string.format("%s set file-local-options/video-crop ''", command_prefix)) - return + local hwdec_current = mp.get_property("hwdec-current") + if hwdec_current:find("-copy$") == nil and hwdec_current ~= "no" and + hwdec_current ~= "crystalhd" and hwdec_current ~= "rkmpp" then + hwdec_backup = mp.get_property("hwdec") + mp.set_property("hwdec", "no") end - -- Apply crop. - mp.command(string.format("%s set file-local-options/video-crop %sx%s+%s+%s", - command_prefix, meta.w, meta.h, meta.x, meta.y)) + -- Insert the cropdetect filter. + local limit = options.detect_limit + local round = options.detect_round + + mp.command( + string.format( + '%s vf pre @%s:cropdetect=limit=%s:round=%d:reset=0', + command_prefix, cropdetect_label, limit, round + ) + ) + + -- Wait to gather data. + timers.detect_crop = mp.add_timeout(time_needed, detect_end) end -function on_start() +local function on_start() -- Clean up at the beginning. cleanup() @@ -269,7 +266,7 @@ function on_start() end end -function on_toggle() +local function on_toggle() -- If it is during auto_delay, kill the timer. if timers.auto_delay then diff --git a/TOOLS/lua/autodeint.lua b/TOOLS/lua/autodeint.lua index 4e929607a0..df938f8318 100644 --- a/TOOLS/lua/autodeint.lua +++ b/TOOLS/lua/autodeint.lua @@ -26,19 +26,21 @@ require "mp.msg" -script_name = mp.get_script_name() -detect_label = string.format("%s-detect", script_name) -pullup_label = string.format("%s", script_name) -dominance_label = string.format("%s-dominance", script_name) -ivtc_detect_label = string.format("%s-ivtc-detect", script_name) +local script_name = mp.get_script_name() +local detect_label = string.format("%s-detect", script_name) +local pullup_label = string.format("%s", script_name) +local dominance_label = string.format("%s-dominance", script_name) +local ivtc_detect_label = string.format("%s-ivtc-detect", script_name) +local timer +local progressive, interlaced_tff, interlaced_bff, interlaced = 0, 1, 2, 3 -- number of seconds to gather cropdetect data -detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name))) +local detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name))) if not detect_seconds then detect_seconds = 4 end -function del_filter_if_present(label) +local function del_filter_if_present(label) -- necessary because mp.command('vf del @label:filter') raises an -- error if the filter doesn't exist local vfs = mp.get_property_native("vf") @@ -57,39 +59,13 @@ local function add_vf(label, filter) return mp.command(('vf add @%s:%s'):format(label, filter)) end -function start_detect() - -- exit if detection is already in progress - if timer then - mp.msg.warn("already detecting!") - return - end - - mp.set_property("deinterlace","no") - del_filter_if_present(pullup_label) - del_filter_if_present(dominance_label) - - -- insert the detection filters - if not (add_vf(detect_label, 'idet') and - add_vf(dominance_label, 'setfield=mode=auto') and - add_vf(pullup_label, 'lavfi-pullup') and - add_vf(ivtc_detect_label, 'idet')) then - mp.msg.error("failed to insert detection filters") - return - end - - -- wait to gather data - timer = mp.add_timeout(detect_seconds, select_filter) -end - -function stop_detect() +local function stop_detect() del_filter_if_present(detect_label) del_filter_if_present(ivtc_detect_label) timer = nil end -progressive, interlaced_tff, interlaced_bff, interlaced = 0, 1, 2, 3, 4 - -function judge(label) +local function judge(label) -- get the metadata local result = mp.get_property_native(string.format("vf-metadata/%s", label)) local num_tff = tonumber(result["lavfi.idet.multiple.tff"]) @@ -118,7 +94,7 @@ function judge(label) end end -function select_filter() +local function select_filter() -- handle the first detection filter results local verdict = judge(detect_label) local ivtc_verdict = judge(ivtc_detect_label) @@ -146,11 +122,36 @@ function select_filter() mp.msg.info(string.format("telecined with %s field dominance: using pullup", dominance)) stop_detect() else - mp.msg.info(string.format("interlaced with %s field dominance: setting deinterlace property", dominance)) + mp.msg.info("interlaced with " .. dominance .. + " field dominance: setting deinterlace property") del_filter_if_present(pullup_label) mp.set_property("deinterlace","yes") stop_detect() end end +local function start_detect() + -- exit if detection is already in progress + if timer then + mp.msg.warn("already detecting!") + return + end + + mp.set_property("deinterlace","no") + del_filter_if_present(pullup_label) + del_filter_if_present(dominance_label) + + -- insert the detection filters + if not (add_vf(detect_label, 'idet') and + add_vf(dominance_label, 'setfield=mode=auto') and + add_vf(pullup_label, 'lavfi-pullup') and + add_vf(ivtc_detect_label, 'idet')) then + mp.msg.error("failed to insert detection filters") + return + end + + -- wait to gather data + timer = mp.add_timeout(detect_seconds, select_filter) +end + mp.add_key_binding("ctrl+d", script_name, start_detect) diff --git a/TOOLS/lua/autoload.lua b/TOOLS/lua/autoload.lua index 593d375431..dedfc64e85 100644 --- a/TOOLS/lua/autoload.lua +++ b/TOOLS/lua/autoload.lua @@ -1,5 +1,5 @@ -- This script automatically loads playlist entries before and after the --- the currently played file. It does so by scanning the directory a file is +-- currently played file. It does so by scanning the directory a file is -- located in when starting playback. It sorts the directory entries -- alphabetically, and adds entries before and after the current file to -- the internal playlist. (It stops if it would add an already existing @@ -32,14 +32,14 @@ ignore_patterns=^~,^bak-,%.bak$ --]] -MAXENTRIES = 5000 -MAXDIRSTACK = 20 +local MAX_ENTRIES = 5000 +local MAX_DIR_STACK = 20 local msg = require 'mp.msg' local options = require 'mp.options' local utils = require 'mp.utils' -o = { +local o = { disabled = false, images = true, videos = true, @@ -52,37 +52,43 @@ o = { directory_mode = "auto", ignore_patterns = "" } -options.read_options(o, nil, function(list) - split_option_exts(list.additional_video_exts, list.additional_audio_exts, list.additional_image_exts) - if list.videos or list.additional_video_exts or - list.audio or list.additional_audio_exts or - list.images or list.additional_image_exts then - create_extensions() - end - if list.directory_mode then - validate_directory_mode() - end -end) -function Set (t) +local function Set(t) local set = {} for _, v in pairs(t) do set[v] = true end return set end -function SetUnion (a,b) +local EXTENSIONS_VIDEO_DEFAULT = Set { + '3g2', '3gp', 'avi', 'flv', 'm2ts', 'm4v', 'mj2', 'mkv', 'mov', + 'mp4', 'mpeg', 'mpg', 'ogv', 'rmvb', 'webm', 'wmv', 'y4m' +} + +local EXTENSIONS_AUDIO_DEFAULT = Set { + 'aiff', 'ape', 'au', 'flac', 'm4a', 'mka', 'mp3', 'oga', 'ogg', + 'ogm', 'opus', 'wav', 'wma' +} + +local EXTENSIONS_IMAGES_DEFAULT = Set { + 'avif', 'bmp', 'gif', 'j2k', 'jp2', 'jpeg', 'jpg', 'jxl', 'png', + 'svg', 'tga', 'tif', 'tiff', 'webp' +} + +local EXTENSIONS, EXTENSIONS_VIDEO, EXTENSIONS_AUDIO, EXTENSIONS_IMAGES + +local function SetUnion(a, b) for k in pairs(b) do a[k] = true end return a end -- Returns first and last positions in string or past-to-end indices -function FindOrPastTheEnd (string, pattern, start_at) - local pos1, pos2 = string.find(string, pattern, start_at) +local function FindOrPastTheEnd(string, pattern, start_at) + local pos1, pos2 = string:find(pattern, start_at) return pos1 or #string + 1, pos2 or #string + 1 end -function Split (list) +local function Split(list) local set = {} local item_pos = 1 @@ -117,34 +123,17 @@ function Split (list) return set end -EXTENSIONS_VIDEO_DEFAULT = Set { - '3g2', '3gp', 'avi', 'flv', 'm2ts', 'm4v', 'mj2', 'mkv', 'mov', - 'mp4', 'mpeg', 'mpg', 'ogv', 'rmvb', 'webm', 'wmv', 'y4m' -} - -EXTENSIONS_AUDIO_DEFAULT = Set { - 'aiff', 'ape', 'au', 'flac', 'm4a', 'mka', 'mp3', 'oga', 'ogg', - 'ogm', 'opus', 'wav', 'wma' -} - -EXTENSIONS_IMAGES_DEFAULT = Set { - 'avif', 'bmp', 'gif', 'j2k', 'jp2', 'jpeg', 'jpg', 'jxl', 'png', - 'svg', 'tga', 'tif', 'tiff', 'webp' -} - -function split_option_exts(video, audio, image) +local function split_option_exts(video, audio, image) if video then o.additional_video_exts = Split(o.additional_video_exts) end if audio then o.additional_audio_exts = Split(o.additional_audio_exts) end if image then o.additional_image_exts = Split(o.additional_image_exts) end end -split_option_exts(true, true, true) -function split_patterns() +local function split_patterns() o.ignore_patterns = Split(o.ignore_patterns) end -split_patterns() -function create_extensions() +local function create_extensions() EXTENSIONS = {} EXTENSIONS_VIDEO = {} EXTENSIONS_AUDIO = {} @@ -162,16 +151,36 @@ function create_extensions() SetUnion(EXTENSIONS, EXTENSIONS_IMAGES) end end -create_extensions() -function validate_directory_mode() - if o.directory_mode ~= "recursive" and o.directory_mode ~= "lazy" and o.directory_mode ~= "ignore" then +local function validate_directory_mode() + if o.directory_mode ~= "recursive" and o.directory_mode ~= "lazy" + and o.directory_mode ~= "ignore" then o.directory_mode = nil end end + +options.read_options(o, nil, function(list) + split_option_exts(list.additional_video_exts, list.additional_audio_exts, + list.additional_image_exts) + if list.videos or list.additional_video_exts or + list.audio or list.additional_audio_exts or + list.images or list.additional_image_exts then + create_extensions() + end + if list.directory_mode then + validate_directory_mode() + end + if list.ignore_patterns then + split_patterns() + end +end) + +split_option_exts(true, true, true) +split_patterns() +create_extensions() validate_directory_mode() -function add_files(files) +local function add_files(files) local oldcount = mp.get_property_number("playlist-count", 1) for i = 1, #files do mp.commandv("loadfile", files[i][1], "append") @@ -179,44 +188,23 @@ function add_files(files) end end -function get_extension(path) - match = string.match(path, "%.([^%.]+)$" ) - if match == nil then - return "nomatch" - else - return match - end +local function get_extension(path) + return path:match("%.([^%.]+)$") or "nomatch" end -function is_ignored(file) - for pattern, _ in pairs(o.ignore_patterns) do - if string.match(file, pattern) then +local function is_ignored(file) + for pattern in pairs(o.ignore_patterns) do + if file:match(pattern) then return true end end - return false end -table.filter = function(t, iter) - for i = #t, 1, -1 do - if not iter(t[i]) then - table.remove(t, i) - end - end -end - -table.append = function(t1, t2) - local t1_size = #t1 - for i = 1, #t2 do - t1[t1_size + i] = t2[i] - end -end - -- alphanum sorting for humans in Lua -- http://notebook.kulchenko.com/algorithms/alphanumeric-natural-sorting-for-humans-in-lua -function alphanumsort(filenames) +local function alphanumsort(filenames) local function padnum(n, d) return #d > 0 and ("%03d%s%.12f"):format(#n, n, tonumber(d) / (10 ^ #d)) or ("%03d%s"):format(#n, n) @@ -233,37 +221,45 @@ function alphanumsort(filenames) return filenames end -local autoloaded = nil +local autoloaded local added_entries = {} -local autoloaded_dir = nil +local autoloaded_dir -function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_files, extensions) - if dir_depth == MAXDIRSTACK then +local function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_files, extensions) + if dir_depth == MAX_DIR_STACK then return end msg.trace("scanning: " .. path) local files = utils.readdir(path, "files") or {} local dirs = dir_mode ~= "ignore" and utils.readdir(path, "dirs") or {} local prefix = path == "." and "" or path - table.filter(files, function (v) - -- The current file could be a hidden file, ignoring it doesn't load other - -- files from the current directory. + + local function filter(t, iter) + for i = #t, 1, -1 do + if not iter(t[i]) then + table.remove(t, i) + end + end + end + + filter(files, function(v) + -- Always accept current file local current = prefix .. v == current_file - if o.ignore_hidden and not current and string.match(v, "^%.") then + if current then + return true + end + if o.ignore_hidden and v:match("^%.") then return false end - if not current and is_ignored(v) then + if is_ignored(v) then return false end local ext = get_extension(v) - if ext == nil then - return false - end - return extensions[string.lower(ext)] + return ext and extensions[ext:lower()] end) - table.filter(dirs, function(d) - return not ((o.ignore_hidden and string.match(d, "^%."))) + filter(dirs, function(d) + return not (o.ignore_hidden and d:match("^%.")) end) alphanumsort(files) alphanumsort(dirs) @@ -272,7 +268,14 @@ function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_file files[i] = prefix .. file end - table.append(total_files, files) + local function append(t1, t2) + local t1_size = #t1 + for i = 1, #t2 do + t1[t1_size + i] = t2[i] + end + end + + append(total_files, files) if dir_mode == "recursive" then for _, dir in ipairs(dirs) do scan_dir(prefix .. dir .. separator, current_file, dir_mode, @@ -282,11 +285,11 @@ function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_file for i, dir in ipairs(dirs) do dirs[i] = prefix .. dir end - table.append(total_files, dirs) + append(total_files, dirs) end end -function find_and_add_entries() +local function find_and_add_entries() local aborted = mp.get_property_native("playback-abort") if aborted then msg.debug("stopping: playback aborted") @@ -305,32 +308,33 @@ function find_and_add_entries() end local pl_count = mp.get_property_number("playlist-count", 1) - this_ext = get_extension(filename) + local this_ext = get_extension(filename) -- check if this is a manually made playlist - if (pl_count > 1 and autoloaded == nil) or - (pl_count == 1 and EXTENSIONS[string.lower(this_ext)] == nil) then + if pl_count > 1 and autoloaded == nil then msg.debug("stopping: manually made playlist") return - else - if pl_count == 1 then - autoloaded = true - autoloaded_dir = dir - added_entries = {} - end + elseif pl_count == 1 then + autoloaded = true + autoloaded_dir = dir + added_entries = {} end - local extensions = {} + local extensions if o.same_type then - if EXTENSIONS_VIDEO[string.lower(this_ext)] ~= nil then + if EXTENSIONS_VIDEO[this_ext:lower()] then extensions = EXTENSIONS_VIDEO - elseif EXTENSIONS_AUDIO[string.lower(this_ext)] ~= nil then + elseif EXTENSIONS_AUDIO[this_ext:lower()] then extensions = EXTENSIONS_AUDIO - else + elseif EXTENSIONS_IMAGES[this_ext:lower()] then extensions = EXTENSIONS_IMAGES end else extensions = EXTENSIONS end + if not extensions then + msg.debug("stopping: no matched extentions list") + return + end local pl = mp.get_property_native("playlist", {}) local pl_current = mp.get_property_number("playlist-pos-1", 1) @@ -338,11 +342,10 @@ function find_and_add_entries() utils.to_string(pl))) local files = {} - do - local dir_mode = o.directory_mode or mp.get_property("directory-mode", "lazy") - local separator = mp.get_property_native("platform") == "windows" and "\\" or "/" - scan_dir(autoloaded_dir, path, dir_mode, separator, 0, files, extensions) - end + scan_dir(autoloaded_dir, path, + o.directory_mode or mp.get_property("directory-mode", "lazy"), + mp.get_property_native("platform") == "windows" and "\\" or "/", + 0, files, extensions) if next(files) == nil then msg.debug("no other files or directories in directory") @@ -357,7 +360,8 @@ function find_and_add_entries() break end end - if current == nil then + if not current then + msg.debug("current file not found in directory") return end msg.trace("current file position in files: "..current) @@ -370,7 +374,7 @@ function find_and_add_entries() local append = {[-1] = {}, [1] = {}} for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1 - for i = 1, MAXENTRIES do + for i = 1, MAX_ENTRIES do local pos = current + i * direction local file = files[pos] if file == nil or file[1] == "." then @@ -390,12 +394,13 @@ function find_and_add_entries() mp.commandv("loadfile", file, "append") end end + added_entries[file] = true end - added_entries[file] = true end if pl_count == 1 and direction == -1 and #append[-1] > 0 then - for i = 1, #append[-1] do - mp.commandv("loadfile", append[-1][i][1], "append") + local load = append[-1] + for i = 1, #load do + mp.commandv("loadfile", load[i][1], "append") end mp.commandv("playlist-move", 0, current) end diff --git a/TOOLS/lua/command-test.lua b/TOOLS/lua/command-test.lua index 877cacdeb6..1f485cdf7f 100644 --- a/TOOLS/lua/command-test.lua +++ b/TOOLS/lua/command-test.lua @@ -2,7 +2,7 @@ local utils = require("mp.utils") -function join(sep, arr, count) +local function join(sep, arr, count) local r = "" if count == nil then count = #arr @@ -31,19 +31,19 @@ mp.observe_property("vo-configured", "bool", function(_, v) mp.set_property("screenshot-format", "png") mp.set_property("screenshot-png-compression", "9") - timer = mp.add_periodic_timer(0.1, function() print("I'm alive") end) + local timer = mp.add_periodic_timer(0.1, function() print("I'm alive") end) timer:resume() print("Slow screenshot command...") - res, err = mp.command_native({"screenshot"}) - pr |