Compare commits

..

1 Commits

Author SHA1 Message Date
Uyanide 22246060e6 init (again) 2026-05-26 15:18:17 +02:00
23 changed files with 228 additions and 27904 deletions
+3
View File
@@ -1,3 +1,6 @@
**/.git
.manager/*
!.manager/.gitkeep
cache/
files/*.log
View File
+15
View File
@@ -16,3 +16,18 @@
| ---------- | ------------------------------------- | ---------------------------------------------- |
| alass | 字幕自动同步autosubsync 脚本) | `paru -S alass` |
| ffsubsync | 字幕自动同步alass 的替代) | `pip install ffsubsync` |
## 字体
弹幕中可能出现 emoji, 因此需要使用支持的字体, 例如将 Symbola 加到 Noto Sans CJK SC 的末尾:
```xml
<match target="pattern">
<test name="family">
<string>Noto Sans CJK SC</string>
</test>
<edit mode="append" name="family">
<string>Symbola</string>
</edit>
</match>
```
+14 -3
View File
@@ -60,10 +60,21 @@ icc/ # ICC 色彩配置文件
## 更新流程
1. 在 mpv 中按 `M` 触发 manager.lua观察控制台输出确认无 `FAILED` 条目
2. 更新完成后删除 manager 在子目录留下的嵌套 `.git`(否则 `git add` 会失败
1. 在 mpv 中按 `M` 触发 manager.lua观察控制台输出确认无 `FAILED` 条目。可能会有其他报错如 `[manager] Fehler: externes Repository manager existiert bereits.`,这是正常的。只需要确保不出现全大写的 `FAILED` 即可。
2. manager.lua 在 dest 目录产生的嵌套 `.git` 目录迁移到仓库内的 `.manager/`(避免根仓库误判为 submodule幂等可重复执行
```bash
find ~/.config/mpv -mindepth 2 -name .git -type d | sort -r | xargs rm -rvf
REPO=$(git -C ~/.config/mpv rev-parse --show-toplevel)
GITSTORE="$REPO/.manager"
mkdir -p "$GITSTORE"
find -L ~/.config/mpv -mindepth 2 -name .git -type d | while read gitdir; do
dest="${gitdir%/.git}"
rel="${dest#$REPO/}"
name=$(echo "$rel" | tr '/' '-')
mv "$gitdir" "$GITSTORE/$name"
depth=$(echo "$rel" | tr -cd '/' | wc -c)
ups=$(printf '../%.0s' $(seq 1 $((depth + 1))))
echo "gitdir: ${ups}.manager/$name" > "$dest/.git"
done
```
3. 重启 mpv检查控制台有无 `unknown key` 或脚本加载失败的警告
4. 若有 `unknown key` 警告,说明对应脚本的配置项发生变化,找 `script-opts/` 下同名 `.conf` 对照脚本源码更新
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -70,8 +70,8 @@ UP no-osd add volume 5; script-message-to uosc flash-volume
DOWN no-osd add volume -5; script-message-to uosc flash-volume #menu: 音频 > 音量 > 音量 -5
SHIFT+RIGHT seek 1 exact #menu: 导航 > 前进后退 > 精准前进 1 秒
SHIFT+LEFT seek -1 exact #menu: 导航 > 前进后退 > 精准后退 1 秒
SHIFT+UP seek 80 exact #menu: 导航 > 前进后退 > 精准前进 80 秒
SHIFT+DOWN seek -80 exact #menu: 导航 > 前进后退 > 精准后退 80 秒
SHIFT+UP seek 85 exact #menu: 导航 > 前进后退 > 精准前进 80 秒
SHIFT+DOWN seek -85 exact #menu: 导航 > 前进后退 > 精准后退 80 秒
CTRL+z script-message-to undoredo undo #menu: 导航 > 跳转 > 撤消跳转
CTRL+x script-message-to undoredo redo #menu: 导航 > 跳转 > 重做跳转
CTRL+ALT+z script-message-to undoredo undoLoop #menu: 导航 > 跳转 > 循环跳转
+118 -112
View File
@@ -1,114 +1,120 @@
[
{
"git": "https://github.com/po5/evafast",
"branch": "rewrite",
"whitelist": "%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/stax76/mpv-scripts",
"branch": "main",
"whitelist": "delete_current_file%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/mpv-scripts",
"branch": "main",
"blacklist": "license|%.md$|drcbox%.lua$|.-%-list%.lua$|mpv-torrserver.lua",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/mpv-playlistmanager",
"branch": "dev",
"whitelist": "playlistmanager%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/mpv-sub-assrt",
"whitelist": "%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/chapterskip",
"branch": "dev",
"whitelist": "%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/Eisa01_mpv-scripts",
"branch": "dev",
"whitelist": "undoredo%.lua$|simplehistory%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/autosubsync-mpv",
"branch": "v0.33_CM",
"whitelist": "readme%.md$|%.lua$",
"dest": "~~/scripts/autosubsync"
},
{
"git": "https://github.com/christoph-heinrich/mpv-quality-menu",
"whitelist": "quality%-menu%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/tomasklaen/uosc",
"branch": "main",
"whitelist": "src/uosc/",
"dest": "~~/scripts/uosc"
},
{
"git": "https://github.com/Tony15246/uosc_danmaku",
"branch": "main",
"blacklist": "^%.",
"dest": "~~/scripts/uosc_danmaku"
},
{
"git": "https://github.com/CogentRedTester/mpv-sub-select",
"whitelist": "sub%-select%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/CogentRedTester/mpv-scripts",
"whitelist": "cycle%-commands%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://gist.github.com/igv/8a77e4eb8276753b54bb94c1c50c317e",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://gist.github.com/igv/a015fc885d5c22e6891820ad89555637",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://gist.github.com/igv/2364ffa6e81540f29cb7ab4c9bc05b6b",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://gist.github.com/igv/36508af3ffc84410fe39761d6969be10",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://github.com/Artoriuz/glsl-joint-bilateral",
"branch": "main",
"whitelist": "jointbilateral%.glsl$",
"dest": "~~/shaders/other"
},
{
"git": "https://github.com/Artoriuz/glsl-pixel-clipper",
"branch": "main",
"whitelist": "%.glsl$",
"dest": "~~/shaders/other"
},
{
"git": "https://github.com/bloc97/Anime4K",
"whitelist": "%.md$|%.glsl$",
"blacklist": "tensorflow",
"dest": "~~/shaders/Anime4K"
}
{
"git": "https://github.com/po5/mpv_manager",
"branch": "master",
"whitelist": "manager%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/po5/evafast",
"branch": "rewrite",
"whitelist": "%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/stax76/mpv-scripts",
"branch": "main",
"whitelist": "delete_current_file%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/mpv-scripts",
"branch": "main",
"blacklist": "license|%.md$|drcbox%.lua$|.-%-list%.lua$|mpv-torrserver.lua",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/mpv-playlistmanager",
"branch": "dev",
"whitelist": "playlistmanager%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/mpv-sub-assrt",
"whitelist": "%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/chapterskip",
"branch": "dev",
"whitelist": "%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/Eisa01_mpv-scripts",
"branch": "dev",
"whitelist": "undoredo%.lua$|simplehistory%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/dyphire/autosubsync-mpv",
"branch": "v0.33_CM",
"whitelist": "readme%.md$|%.lua$",
"dest": "~~/scripts/autosubsync"
},
{
"git": "https://github.com/christoph-heinrich/mpv-quality-menu",
"whitelist": "quality%-menu%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/tomasklaen/uosc",
"branch": "main",
"whitelist": "src/uosc/",
"dest": "~~/scripts/uosc"
},
{
"git": "https://github.com/Tony15246/uosc_danmaku",
"branch": "main",
"blacklist": "^%.|^\"",
"dest": "~~/scripts/uosc_danmaku"
},
{
"git": "https://github.com/CogentRedTester/mpv-sub-select",
"whitelist": "sub%-select%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://github.com/CogentRedTester/mpv-scripts",
"whitelist": "cycle%-commands%.lua$",
"dest": "~~/scripts"
},
{
"git": "https://gist.github.com/igv/8a77e4eb8276753b54bb94c1c50c317e",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://gist.github.com/igv/a015fc885d5c22e6891820ad89555637",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://gist.github.com/igv/2364ffa6e81540f29cb7ab4c9bc05b6b",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://gist.github.com/igv/36508af3ffc84410fe39761d6969be10",
"whitelist": "%.glsl$",
"dest": "~~/shaders/igv"
},
{
"git": "https://github.com/Artoriuz/glsl-joint-bilateral",
"branch": "main",
"whitelist": "jointbilateral%.glsl$",
"dest": "~~/shaders/other"
},
{
"git": "https://github.com/Artoriuz/glsl-pixel-clipper",
"branch": "main",
"whitelist": "%.glsl$",
"dest": "~~/shaders/other"
},
{
"git": "https://github.com/bloc97/Anime4K",
"whitelist": "%.md$|%.glsl$",
"blacklist": "tensorflow",
"dest": "~~/shaders/Anime4K"
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+55 -53
View File
@@ -1,3 +1,5 @@
-- https://github.com/Seme4eg/mpv-scripts/blob/master/script-modules/extended-menu.lua
local mp = require 'mp'
local utils = require 'mp.utils'
local assdraw = require 'mp.assdraw'
@@ -449,7 +451,7 @@ end
I was too lazy to list all modifications i've done to the script, but if u
rly need to see those - do diff with the original code
]]
--
--
-------------------------------------------------------------------------------
-- START ORIGINAL MPV CODE --
@@ -830,58 +832,58 @@ end
-- bindings and readline bindings.
function em:get_bindings()
local bindings = {
{ 'ctrl+[', function() self:set_active(false) end },
{ 'ctrl+g', function() self:set_active(false) end },
{ 'esc', function() self:set_active(false) end },
{ 'enter', function() self:handle_enter() end },
{ 'kp_enter', function() self:handle_enter() end },
{ 'ctrl+m', function() self:handle_enter() end },
{ 'bs', function() self:handle_backspace() end },
{ 'shift+bs', function() self:handle_backspace() end },
{ 'ctrl+h', function() self:handle_backspace() end },
{ 'del', function() self:handle_del() end },
{ 'shift+del', function() self:handle_del() end },
{ 'ins', function() self:handle_ins() end },
{ 'shift+ins', function() self:paste(false) end },
{ 'mbtn_mid', function() self:paste(false) end },
{ 'left', function() self:prev_char() end },
{ 'ctrl+b', function() self:prev_char() end },
{ 'right', function() self:next_char() end },
{ 'ctrl+f', function() self:next_char() end },
{ 'ctrl+k', function() self:change_selected_index(-1) end },
{ 'ctrl+p', function() self:change_selected_index(-1) end },
{ 'ctrl+j', function() self:change_selected_index(1) end },
{ 'ctrl+n', function() self:change_selected_index(1) end },
{ 'up', function() self:move_history(-1) end },
{ 'alt+p', function() self:move_history(-1) end },
{ 'wheel_up', function() self:move_history(-1) end },
{ 'down', function() self:move_history(1) end },
{ 'alt+n', function() self:move_history(1) end },
{ 'wheel_down', function() self:move_history(1) end },
{ 'wheel_left', function() end },
{ 'wheel_right', function() end },
{ 'ctrl+left', function() self:prev_word() end },
{ 'alt+b', function() self:prev_word() end },
{ 'ctrl+right', function() self:next_word() end },
{ 'alt+f', function() self:next_word() end },
{ 'ctrl+a', function() self:go_home() end },
{ 'home', function() self:go_home() end },
{ 'ctrl+e', function() self:go_end() end },
{ 'end', function() self:go_end() end },
{ 'ctrl+shift+f',function() self:handle_pgdown() end },
{ 'ctrl+shift+b',function() self:handle_pgup() end },
{ 'pgdwn', function() self:handle_pgdown() end },
{ 'pgup', function() self:handle_pgup() end },
{ 'ctrl+c', function() self:clear() end },
{ 'ctrl+d', function() self:handle_del() end },
{ 'ctrl+u', function() self:del_to_start() end },
{ 'ctrl+v', function() self:paste(true) end },
{ 'meta+v', function() self:paste(true) end },
{ 'ctrl+bs', function() self:del_word() end },
{ 'ctrl+w', function() self:del_word() end },
{ 'ctrl+del', function() self:del_next_word() end },
{ 'alt+d', function() self:del_next_word() end },
{ 'kp_dec', function() self:handle_char_input('.') end },
{ 'ctrl+[', function() self:set_active(false) end },
{ 'ctrl+g', function() self:set_active(false) end },
{ 'esc', function() self:set_active(false) end },
{ 'enter', function() self:handle_enter() end },
{ 'kp_enter', function() self:handle_enter() end },
{ 'ctrl+m', function() self:handle_enter() end },
{ 'bs', function() self:handle_backspace() end },
{ 'shift+bs', function() self:handle_backspace() end },
{ 'ctrl+h', function() self:handle_backspace() end },
{ 'del', function() self:handle_del() end },
{ 'shift+del', function() self:handle_del() end },
{ 'ins', function() self:handle_ins() end },
{ 'shift+ins', function() self:paste(false) end },
{ 'mbtn_mid', function() self:paste(false) end },
{ 'left', function() self:prev_char() end },
{ 'ctrl+b', function() self:prev_char() end },
{ 'right', function() self:next_char() end },
{ 'ctrl+f', function() self:next_char() end },
{ 'ctrl+k', function() self:change_selected_index(-1) end },
{ 'ctrl+p', function() self:change_selected_index(-1) end },
{ 'ctrl+j', function() self:change_selected_index(1) end },
{ 'ctrl+n', function() self:change_selected_index(1) end },
{ 'up', function() self:move_history(-1) end },
{ 'alt+p', function() self:move_history(-1) end },
{ 'wheel_up', function() self:move_history(-1) end },
{ 'down', function() self:move_history(1) end },
{ 'alt+n', function() self:move_history(1) end },
{ 'wheel_down', function() self:move_history(1) end },
{ 'wheel_left', function() end },
{ 'wheel_right', function() end },
{ 'ctrl+left', function() self:prev_word() end },
{ 'alt+b', function() self:prev_word() end },
{ 'ctrl+right', function() self:next_word() end },
{ 'alt+f', function() self:next_word() end },
{ 'ctrl+a', function() self:go_home() end },
{ 'home', function() self:go_home() end },
{ 'ctrl+e', function() self:go_end() end },
{ 'end', function() self:go_end() end },
{ 'ctrl+shift+f', function() self:handle_pgdown() end },
{ 'ctrl+shift+b', function() self:handle_pgup() end },
{ 'pgdwn', function() self:handle_pgdown() end },
{ 'pgup', function() self:handle_pgup() end },
{ 'ctrl+c', function() self:clear() end },
{ 'ctrl+d', function() self:handle_del() end },
{ 'ctrl+u', function() self:del_to_start() end },
{ 'ctrl+v', function() self:paste(true) end },
{ 'meta+v', function() self:paste(true) end },
{ 'ctrl+bs', function() self:del_word() end },
{ 'ctrl+w', function() self:del_word() end },
{ 'ctrl+del', function() self:del_next_word() end },
{ 'alt+d', function() self:del_next_word() end },
{ 'kp_dec', function() self:handle_char_input('.') end },
}
for i = 0, 9 do
+2 -2
View File
@@ -36,9 +36,9 @@ scrolltime=15
## 固定弹幕的显示时间
fixtime=5
## 字体
fontname=Noto Sans CJK SC
fontname=danmaku
## 字体大小
fontsize=30
fontsize=24
## 透明度
opacity=0.6
## 粗体
+18 -63
View File
@@ -1,4 +1,3 @@
local msg = require "mp.msg"
local utils = require "mp.utils"
local legacy = mp.command_native_async == nil
local config = {}
@@ -45,55 +44,22 @@ function apply_defaults(info)
return info
end
local function build_directory_string(dir, repo)
local str = ""
local contents = utils.readdir(dir)
if not contents then return msg.error("could not access local repo:", repo) end
for _, item in ipairs(contents) do
local path = dir..'/'..item
if utils.file_info(path).is_dir then
if item ~= ".git" then str = str..'/'..build_directory_string(path, repo)..'\n' end
else
str = str..(path:sub(repo:len()+2))..'\n'
end
end
return str
end
local function get_file_list(info)
if not info.local_repo then
return run({"git", "-C", info.edist, "ls-tree", "-r", "--name-only", "remotes/manager/"..info.branch}).stdout
else
return build_directory_string(info.local_repo, info.local_repo)
end
end
function update(info)
info = apply_defaults(info)
if not info then return false end
local base = nil
info.edist = string.match(mp.command_native({"expand-path", info.dest}), "(.-)[/\\]?$")
mkdir(info.edist)
local e_dest = string.match(mp.command_native({"expand-path", info.dest}), "(.-)[/\\]?$")
mkdir(e_dest)
local files = {}
if info.local_repo then
info.local_repo = mp.command_native({"expand-path", info.local_repo})
if not utils.file_info(info.local_repo) then
info.local_repo = false
msg.warn("local repo not found - falling back to git")
end
end
if not info.local_repo then
run({"git", "-C", info.edist, "remote", "add", "manager", info.git})
run({"git", "-C", info.edist, "remote", "set-url", "manager", info.git})
run({"git", "-C", info.edist, "fetch", "manager", info.branch})
end
for file in string.gmatch(get_file_list(info), "[^\r\n]+") do
run({"git", "-C", e_dest, "remote", "add", "manager", info.git})
run({"git", "-C", e_dest, "remote", "set-url", "manager", info.git})
run({"git", "-C", e_dest, "fetch", "manager", info.branch})
for file in string.gmatch(run({"git", "-C", e_dest, "ls-tree", "-r", "--name-only", "remotes/manager/"..info.branch}).stdout, "[^\r\n]+") do
local l_file = string.lower(file)
if info.whitelist == "" or match(l_file, info.whitelist) then
if info.blacklist == "" or not match(l_file, info.blacklist) then
@@ -107,29 +73,20 @@ function update(info)
end
end
end
if base == nil then return false end
if base ~= "" then base = base.."/" end
if next(files) == nil then
print("no files matching patterns")
else
for _, file in ipairs(files) do
local based = string.sub(file, string.len(base)+1)
local p_based = parent(based)
if p_based and not info.flatten_folders then mkdir(info.edist.."/"..p_based) end
local c = ""
if info.local_repo then
local source = io.open(info.local_repo..'/'..file)
c = source:read("*a")
source:close()
else
c = string.match(run({"git", "-C", info.edist, "--no-pager", "show", "remotes/manager/"..info.branch..":"..file}).stdout, "(.-)[\r\n]?$")
end
local f = io.open(info.edist.."/"..(info.flatten_folders and file:match("[^/]+$") or based), "w")
if p_based and not info.flatten_folders then mkdir(e_dest.."/"..p_based) end
local c = string.match(run({"git", "-C", e_dest, "--no-pager", "show", "remotes/manager/"..info.branch..":"..file}).stdout, "(.-)[\r\n]?$")
local f = io.open(e_dest.."/"..(info.flatten_folders and file:match("[^/]+$") or based), "w")
f:write(c)
f:close()
end
@@ -150,10 +107,8 @@ function update_all()
end
for i, info in ipairs(config) do
print("updating", (info.git:match("([^/]+)%.git$") or info.git).."...")
if not update(info) then msg.error("FAILED") end
print("update"..i, update(info))
end
print("all files updated")
end
mp.add_key_binding(nil, "manager-update-all", update_all)
mp.add_key_binding(nil, "manager-update-all", update_all)
-224
View File
@@ -1,224 +0,0 @@
-- Install [Torrserver](https://github.com/YouROK/TorrServer)
-- then add "script-opts-append=mpv_torrserver-server=http://[TorrServer ip]:[port]" to mpv.conf
local utils = require 'mp.utils'
local opts = {
server = "http://localhost:8090",
torrserver_init = false,
torrserver_path = "TorrServer",
search_for_external_tracks = true
}
(require 'mp.options').read_options(opts)
local luacurl_available, cURL = pcall(require, 'cURL')
local is_windows = package.config:sub(1, 1) == "\\" -- detect path separator, windows uses backslashes
local function find_executable(name)
local os_path = os.getenv("PATH") or ""
local fallback_path = utils.join_path("/usr/bin", name)
local exec_path
for path in os_path:gmatch("[^:]+") do
exec_path = utils.join_path(path, name)
local meta, meta_error = utils.file_info(exec_path)
if meta and meta.is_file then
return exec_path
end
end
if not is_windows then return fallback_path end
return name -- fallback to just the name, hoping it's in PATH
end
local function init()
local exec_path = find_executable(opts.torrserver_path)
local windows_args = { 'powershell', '-NoProfile', '-Command', exec_path }
local unix_args = { '/bin/bash', '-c', exec_path }
local args = is_windows and windows_args or unix_args
local res = mp.command_native_async({ name = "subprocess", capture_stdout = true, playback_only = false, args = args })
if res.status == 0 then
mp.msg.error("TorrServer failed to start: ")
end
end
local char_to_hex = function(c)
return string.format("%%%02X", string.byte(c))
end
local function urlencode(url)
if url == nil then
return
end
url = url:gsub("\n", "\r\n")
url = url:gsub("([^%w ])", char_to_hex)
url = url:gsub(" ", "+")
return url
end
local function get_magnet_info(url)
local info_url = opts.server .. "/stream?stat&link=" .. urlencode(url)
local res
if not (luacurl_available) then
-- if Lua-cURL is not available on this system
local curl_cmd = {
"curl",
"-L",
"--silent",
"--max-time", "10",
info_url
}
local cmd = mp.command_native {
name = "subprocess",
capture_stdout = true,
playback_only = false,
args = curl_cmd
}
res = cmd.stdout
else
-- otherwise use Lua-cURL (binding to libcurl)
local buf = {}
local c = cURL.easy_init()
c:setopt_followlocation(1)
c:setopt_url(info_url)
c:setopt_writefunction(function(chunk)
table.insert(buf, chunk);
return true;
end)
c:perform()
res = table.concat(buf)
end
if res and res ~= "" then
return (require 'mp.utils').parse_json(res)
else
return nil, "no info response (timeout?)"
end
end
local function edlencode(url)
return "%" .. string.len(url) .. "%" .. url
end
local function guess_type_by_extension(ext)
if ext == "mkv" or ext == "mp4" or ext == "avi" or ext == "wmv" or ext == "vob" or ext == "m2ts" or ext == "ogm" then
return "video"
end
if ext == "mka" or ext == "mp3" or ext == "aac" or ext == "flac" or ext == "ogg" or ext == "wma" or ext == "mpg"
or ext == "wav" or ext == "wv" or ext == "opus" or ext == "ac3" then
return "audio"
end
if ext == "ass" or ext == "srt" or ext == "vtt" then
return "sub"
end
return "other";
end
local function string_replace(str, match, replace)
local s, e = string.find(str, match, 1, true)
if s == nil or e == nil then
return str
end
return string.sub(str, 1, s - 1) .. replace .. string.sub(str, e + 1)
end
-- https://github.com/mpv-player/mpv/blob/master/DOCS/edl-mpv.rst
local function generate_m3u(magnet_uri, files)
for _, fileinfo in ipairs(files) do
-- strip top directory
if fileinfo.path:find("/", 1, true) then
fileinfo.fullpath = string.sub(fileinfo.path, fileinfo.path:find("/", 1, true) + 1)
else
fileinfo.fullpath = fileinfo.path
end
fileinfo.path = {}
for w in fileinfo.fullpath:gmatch("([^/]+)") do table.insert(fileinfo.path, w) end
local ext = string.match(fileinfo.path[#fileinfo.path], "%.(%w+)$")
fileinfo.type = guess_type_by_extension(ext)
end
table.sort(files, function(a, b)
-- make top-level files appear first in the playlist
if (#a.path == 1 or #b.path == 1) and #a.path ~= #b.path then
return #a.path < #b.path
end
-- make videos first
if (a.type == "video" or b.type == "video") and a.type ~= b.type then
return a.type == "video"
end
-- otherwise sort by path
return a.fullpath < b.fullpath
end);
local infohash = magnet_uri:match("^magnet:%?xt=urn:bt[im]h:(%w+)") or urlencode(magnet_uri)
local playlist = { '#EXTM3U' }
for _, fileinfo in ipairs(files) do
if fileinfo.processed ~= true then
table.insert(playlist, '#EXTINF:0,' .. fileinfo.fullpath)
local basename = string.match(fileinfo.path[#fileinfo.path], '^(.+)%.%w+$')
local url = opts.server .. "/stream/" .. urlencode(fileinfo.fullpath) .."?play&index=" .. fileinfo.id .. "&link=" .. infohash
local hdr = { "!new_stream", "!no_clip",
--"!track_meta,title=" .. edlencode(basename),
edlencode(url)
}
local edl = "edl://" .. table.concat(hdr, ";") .. ";"
local external_tracks = 0
fileinfo.processed = true
if opts.search_for_external_tracks and basename ~= nil and fileinfo.type == "video" then
mp.msg.info("!" .. basename)
for _, fileinfo2 in ipairs(files) do
if #fileinfo2.path > 0 and
fileinfo2.type ~= "other" and
fileinfo2.processed ~= true and
string.find(fileinfo2.path[#fileinfo2.path], basename, 1, true) ~= nil
then
mp.msg.info("->" .. fileinfo2.fullpath)
local title = string_replace(fileinfo2.fullpath, basename, "%")
local url = opts.server .. "/stream/" .. urlencode(fileinfo2.fullpath).."?play&index=" .. fileinfo2.id .. "&link=" .. infohash
local hdr = { "!new_stream", "!no_clip", "!no_chapters",
"!delay_open,media_type=" .. fileinfo2.type,
"!track_meta,title=" .. edlencode(title),
edlencode(url)
}
edl = edl .. table.concat(hdr, ";") .. ";"
fileinfo2.processed = true
external_tracks = external_tracks + 1
end
end
end
if external_tracks == 0 then -- dont use edl
table.insert(playlist, url)
else
table.insert(playlist, edl)
end
end
end
return table.concat(playlist, '\n')
end
mp.add_hook("on_load", 5, function()
local url = mp.get_property("stream-open-filename")
if url:find("^magnet:") == 1 or (url:find("^https?://") == 1 and url:find("%.torrent$") ~= nil) then
mp.set_property_bool("file-local-options/ytdl", false)
if opts.torrserver_init then init() end
local magnet_info, err = get_magnet_info(url)
if type(magnet_info) == "table" then
if magnet_info.file_stats then
-- torrent has multiple files. open as playlist
mp.set_property("stream-open-filename", "memory://" .. generate_m3u(url, magnet_info.file_stats))
return
end
-- if not a playlist and has a name
if magnet_info.name then
mp.set_property("stream-open-filename", "memory://#EXTM3U\n" ..
"#EXTINF:0," .. magnet_info.name .. "\n" ..
opts.server .. "/stream?play&index=1&link=" .. urlencode(url))
return
end
else
mp.msg.warn("error: " .. err)
end
mp.set_property("stream-open-filename", opts.server .. "/stream?m3u&link=" .. urlencode(url))
end
end)
+1 -1
View File
@@ -754,7 +754,7 @@ fallback_server
想要使用此选项请在mpv配置文件夹下的 `script-opts`中创建 `uosc_danmaku.conf`文件并自定义如下内容:
```
fallback_server= https://api.danmu.icu
fallback_server=https://api.danmu.icu
```
</details>