commit 22246060e677ea4f2f76d0427ed90ccd8b8b7581 Author: Uyanide Date: Tue May 26 15:18:17 2026 +0200 init (again) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9059ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +**/.git +.manager/* +!.manager/.gitkeep +cache/ + +files/*.log +files/*.json +files/*.jsonl +files/command_history.txt +files/watch_history.jsonl +files/historybookmarks/ +files/screen/ +files/animated/ +files/cutfragments/ +files/chapters/ +files/danmaku-history.json + +historybookmarks + +*.log + +.claude/ +.vscode/ +*.swp +*.swo +*~ diff --git a/.manager/.gitkeep b/.manager/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md new file mode 100644 index 0000000..5cb4067 --- /dev/null +++ b/DEPENDENCIES.md @@ -0,0 +1,33 @@ +# 外部依赖 + +## 必需 + +| 依赖 | 用途 | 安装 | +| --------- | --------------------------------------- | --------------------- | +| mpv | 播放器本体(需 gpu-next + vulkan 支持) | `pacman -S mpv` | +| yt-dlp | URL 解析与流媒体播放 | `pacman -S yt-dlp` | +| ffmpeg | 字幕导出、缩略图生成、字幕同步 | `pacman -S ffmpeg` | +| curl | 字幕搜索下载、更新检查 | `pacman -S curl` | +| trash-cli | 安全删除文件(移至回收站) | `pacman -S trash-cli` | + +## 可选 + +| 依赖 | 用途 | 安装 | +| ---------- | ------------------------------------- | ---------------------------------------------- | +| alass | 字幕自动同步(autosubsync 脚本) | `paru -S alass` | +| ffsubsync | 字幕自动同步(alass 的替代) | `pip install ffsubsync` | + +## 字体 + +弹幕中可能出现 emoji, 因此需要使用支持的字体, 例如将 Symbola 加到 Noto Sans CJK SC 的末尾: + +```xml + + + Noto Sans CJK SC + + + Symbola + + +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..2e9f794 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# .config/mpv + +一套 mpv 播放器配置,集成 uosc 界面、多种着色器方案和自动更新机制。 + +## Credits + +原始仓库为 [emoeem/mpv](https://github.com/emoeem/mpv)。根据我的需要精简了一些功能,同时做了一些修复。 + +## 结构 + +``` +mpv.conf # 主配置(全局设置 + Profile 定义) +input.conf # 键位绑定与右键菜单 +inputevent_key.conf # inputevent.lua 增强键位(单击/双击/长按) +profiles.conf # 场景预设(游戏/电影/动画/低功耗/直播等) +manager.json # 脚本和着色器的 git 自动更新源 +scripts/ # Lua 脚本 +script-opts/ # 脚本配置 +shaders/ # GPU 着色器(NNEDI3/FSRCNNX/Ani4K/Anime4K/ravu/igv 等) +fonts/ # 字体 +icc/ # ICC 色彩配置文件 +``` + +## 主要功能 + +- **界面**:uosc 界面 + 右键菜单 + 缩略图预览 + 命令面板 +- **色彩管理**:ICC / Target 双模式,HDR 直通与色调映射,动态峰值检测 +- **着色器**:NNEDI3、FSRCNNX、Ani4K、AniSD、Anime4K、ravu-zoom、SSIM +- **条件 Profile**:根据分辨率 / HDR / 帧率 / 刷新率 / 网络等自动调整参数 +- **字幕**:自动加载、编码检测(GB18030)、在线搜索(assrt)、自动同步(autosubsync) +- **音频**:96kHz 重采样、独占模式、多声道自动下混调节、ReplayGain +- **播放管理**:历史记录(simplehistory)、进度保存、文件浏览器、播放列表管理 +- **网络**:yt-dlp 集成、浏览器 Cookie、自动缓存优化 +- **更新**:按 M 键通过 manager.lua 从 git 自动更新所有脚本和着色器 + +## 着色器方案 + +在 `mpv.conf` 的 Profile 激活区切换(取消注释对应行): + +| Profile | 适用场景 | GPU 开销 | +| --------- | --------------- | -------- | +| NNEDI3 | 通用 | 中 | +| NNEDI3+ | 通用(64 变体) | 高 | +| ravu-zoom | 通用 | 中 | +| FSRCNNX | HD 内容 | 中 | +| FSRCNNX+ | SD 内容去伪影 | 中 | +| Ani4K | 动画 | 极高 | +| AniSD | SD 动画 | 极高 | +| Anime4K | 动画 | 低 | +| SSIM | 低性能需求 | 低 | + +其中: + +- Ani4K / AniSD 着色器(`shaders/Ani4K/`)来自 [Sirosky/Upscale-Hub](https://github.com/Sirosky/Upscale-Hub)。 +- nnedi3 / ravu 着色器(`shaders/nnedi3/`,`shaders/ravu/`)来自 [mpv-prescalers](https://github.com/bjin/mpv-prescalers)。 + +## 外部依赖 + +见 [DEPENDENCIES.md](DEPENDENCIES.md)。 + +## 更新流程 + +1. 在 mpv 中按 `M` 触发 manager.lua,观察控制台输出,确认无 `FAILED` 条目。可能会有其他报错如 `[manager] Fehler: externes Repository manager existiert bereits.`,这是正常的。只需要确保不出现全大写的 `FAILED` 即可。 +2. 将 manager.lua 在 dest 目录产生的嵌套 `.git` 目录迁移到仓库内的 `.manager/`(避免根仓库误判为 submodule,幂等可重复执行): + ```bash + 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` 对照脚本源码更新 diff --git a/files/danmaku-blacklist.txt b/files/danmaku-blacklist.txt new file mode 100644 index 0000000..e69de29 diff --git a/fonts/MaterialIconsRound-Regular.otf b/fonts/MaterialIconsRound-Regular.otf new file mode 100644 index 0000000..4c4e0dc Binary files /dev/null and b/fonts/MaterialIconsRound-Regular.otf differ diff --git a/fonts/uosc_textures.ttf b/fonts/uosc_textures.ttf new file mode 100644 index 0000000..d25fed5 Binary files /dev/null and b/fonts/uosc_textures.ttf differ diff --git a/icc/DCI-P3-D65.icc b/icc/DCI-P3-D65.icc new file mode 100644 index 0000000..6e69c14 Binary files /dev/null and b/icc/DCI-P3-D65.icc differ diff --git a/icc/DCI-P3-DCI.icc b/icc/DCI-P3-DCI.icc new file mode 100644 index 0000000..72e5cbb Binary files /dev/null and b/icc/DCI-P3-DCI.icc differ diff --git a/icc/ITU-RBT709ReferenceDisplay.icc b/icc/ITU-RBT709ReferenceDisplay.icc new file mode 100644 index 0000000..0b6669f Binary files /dev/null and b/icc/ITU-RBT709ReferenceDisplay.icc differ diff --git a/icc/ITU-R_BT2020(beta).icc b/icc/ITU-R_BT2020(beta).icc new file mode 100644 index 0000000..cf554ac Binary files /dev/null and b/icc/ITU-R_BT2020(beta).icc differ diff --git a/input.conf b/input.conf new file mode 100644 index 0000000..31a9e6e --- /dev/null +++ b/input.conf @@ -0,0 +1,321 @@ +# 此文件定义 mpv 的快捷键绑定和 uosc 右键菜单项目 + +##⇘⇘uosc 一级菜单:打开 +o script-message-to uosc open-file #menu: 打开 > 打开内置浏览器 +# script-message-to uosc playlist #menu: 打开 > 播放菜单 +# script-message-to uosc chapters #menu: 打开 > 章节菜单 +# script-message-to uosc editions #menu: 打开 > 版本菜单 +# script-message-to uosc audio #menu: 打开 > 其他音轨 +# script-message-to uosc subtitles #menu: 打开 > 其他字幕 +# ignore #menu: 打开 > --- +` script-message-to simplehistory open-list;show-text '' #menu: 打开 > 历史 > 打开历史菜单 +ALT+l script-message-to simplehistory history-incognito-mode #menu: 打开 > 历史 > 开/关 隐身历史 +CTRL+L script-message-to simplehistory history-load-last #menu: 打开 > 历史 > 加载最后播放文件 +CTRL+l script-message-to simplehistory history-resume #menu: 打开 > 历史 > 加载最后播放文件及进度 +# ignore #menu: 打开 > --- +CTRL+c set clipboard/text ${path};show-text "已复制文件路径" #menu: 打开 > 复制 > 复制文件路径 +CTRL+ALT+c set clipboard/text ${filename};show-text "已复制文件名" #menu: 打开 > 复制 > 复制文件名 +# ignore #menu: 打开 > --- +CTRL+F script-message-to quality_menu video_formats_toggle #menu: 打开 > Youtube-dl > 开/关 ytdl 视频选择菜单 +ALT+F script-message-to quality_menu audio_formats_toggle #menu: 打开 > Youtube-dl > 开/关 ytdl 音频选择菜单 +# script-message-to quality_menu reload #menu: 打开 > Youtube-dl > ytdl 重新加载 + +##⇘⇘uosc 一级菜单:文件 +SHIFT+F11 stop #menu: 文件 > 停止 +ALT+t cycle ontop;show-text "置顶:${ontop}" #menu: 文件 > 开/关 置顶状态 #@state=(ontop and 'checked') +ALT+b cycle window-maximized #menu: 文件 > 开/关 最大化 #@state=(window_maximized and 'checked') +f cycle fullscreen #menu: 文件 > 开/关 全屏 #@state=(fullscreen and 'checked') +i script-binding stats/display-stats #menu: 文件 > 临时显示统计信息 +I script-binding stats/display-stats-toggle #menu: 文件 > 常驻显示统计信息 +l ab-loop #menu: 文件 > 设定/清除 片段循环 +L cycle-values loop-file inf no;show-text "循环播放:${loop-file}" #menu: 文件 > 开/关 循环播放 #@state=(loop_file and 'checked') +n script-message playlistmanager shuffle #menu: 文件 > 随机播放 +[ no-osd add speed -0.1; script-message-to uosc flash-speed #menu: 文件 > 速度 > 速度 -0.1 +] no-osd add speed 0.1; script-message-to uosc flash-speed #menu: 文件 > 速度 > 速度 +0.1 +{ no-osd multiply speed 0.5; script-message-to uosc flash-speed #menu: 文件 > 速度 > 半速 +} no-osd multiply speed 2.0; script-message-to uosc flash-speed #menu: 文件 > 速度 > 倍速 +BS no-osd set speed 1.0; script-message-to uosc flash-speed #menu: 文件 > 速度 > 重置速度 +ALT+o script-message-to uosc show-in-directory #menu: 文件 > 定位当前文件 +DEL script-message-to delete_current_file delete-file 1 "请按 1 确认删除" #menu: 文件 > 删除当前文件 + +##⇘⇘uosc 一级菜单:导航 +# show-text ${track-list} 5000 #menu: 导航 > 打开 OSD 轨道信息 +O no-osd cycle-values osd-level 3 1 #menu: 导航 > 开/关 显示 OSD 时间轴 +F4 script-binding select/menu;show-text '' #menu: 导航 > OSD 交互菜单 > 综合菜单 +F5 script-message-to playlistmanager showplaylist;show-text '' #menu: 导航 > OSD 交互菜单 > 播放列表 +F6 script-binding select/select-audio-device;show-text '' #menu: 导航 > OSD 交互菜单 > 音频设备列表 +# script-binding select/select-edition;show-text '' #menu: 导航 > OSD 交互菜单 > 版本列表 +F7 script-binding select/select-chapter;show-text '' #menu: 导航 > OSD 交互菜单 > 章节列表 +F8 script-binding select/select-track;show-text '' #menu: 导航 > OSD 交互菜单 > 轨道列表 +F9 script-binding select/select-vid;show-text '' #menu: 导航 > OSD 交互菜单 > 视频轨列表 +F10 script-binding select/select-aid;show-text '' #menu: 导航 > OSD 交互菜单 > 音频轨列表 +F11 script-binding select/select-sid;show-text '' #menu: 导航 > OSD 交互菜单 > 字幕轨列表 +ALT+c script-message-to chapter_make_read create_chapter #menu: 导航 > 章节制作 > 标记章节时间 +ALT+e script-message-to chapter_make_read edit_chapter #menu: 导航 > 章节制作 > 编辑章节标题 +ALT+r script-message-to chapter_make_read remove_chapter #menu: 导航 > 章节制作 > 删除当前章节 +ALT+w script-message-to chapter_make_read write_chapter chp #menu: 导航 > 章节制作 > 创建 chp 章节文件 +ALT+g script-message-to chapter_make_read write_chapter ogm #menu: 导航 > 章节制作 > 创建 ogm 章节文件 +< playlist-prev;show-text "播放列表:${playlist-pos-1}/${playlist-count}" #menu: 导航 > 上个文件 +> playlist-next;show-text "播放列表:${playlist-pos-1}/${playlist-count}" #menu: 导航 > 下个文件 +PGDWN add chapter -1 #menu: 导航 > 上一章节 +PGUP add chapter 1 #menu: 导航 > 下一章节 +F3 script-message-to chapterskip skip-to-silence;show-text "跳到下一个静音位置" #menu: 导航 > 跳到下一个静音位置 +ALT+q script-message-to chapterskip chapter-skip #menu: 导航 > 切换 章节跳过模式 +ALT+n script-message-to chapterskip toggle-markskip #menu: 导航 > 标记片头片尾 +, frame-back-step;show-text "当前帧:${estimated-frame-number}" #menu: 导航 > 前进后退 > 上一帧 +. frame-step ;show-text "当前帧:${estimated-frame-number}" #menu: 导航 > 前进后退 > 下一帧 +RIGHT seek 5 #menu: 导航 > 前进后退 > 前进 5 秒 +LEFT seek -5 #menu: 导航 > 前进后退 > 后退 5 秒 +UP no-osd add volume 5; script-message-to uosc flash-volume #menu: 音频 > 音量 > 音量 +5 +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 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: 导航 > 跳转 > 循环跳转 + +##⇘⇘uosc 一级菜单:画面 +# set video-aspect-override "-1";show-text "宽高比:${video-aspect-override}" #menu: 画面 > 切换 宽高比 > 默认值 +# set video-aspect-override "16:9";show-text "宽高比:${video-aspect-override}" #menu: 画面 > 切换 宽高比 > 16:9 +# set video-aspect-override "4:3";show-text "宽高比:${video-aspect-override}" #menu: 画面 > 切换 宽高比 > 4:3 +# set video-aspect-override "2.35:1";show-text "宽高比:${video-aspect-override}" #menu: 画面 > 切换 宽高比 > 2.35:1 +A cycle-values video-aspect-override 16:9 4:3 2.35:1 -1;show-text "宽高比:${video-aspect-override}" #menu: 画面 > 切换 宽高比 > 循环切换 +CTRL+LEFT cycle-values video-rotate 0 270 180 90;show-text "视频旋转:${video-rotate}" #menu: 画面 > 左旋转 +CTRL+RIGHT cycle-values video-rotate 0 90 180 270;show-text "视频旋转:${video-rotate}" #menu: 画面 > 右旋转 +CTRL+- add window-scale -0.1;show-text "窗口缩小:${window-scale}" #menu: 画面 > 画面缩放 > 缩小窗口 +CTRL+= add window-scale 0.1;show-text "窗口放大:${window-scale}" #menu: 画面 > 画面缩放 > 放大窗口 +ALT+- add video-zoom -0.1;show-text "画面缩小:${video-zoom}" #menu: 画面 > 画面缩放 > 画面缩小 +ALT+= add video-zoom 0.1;show-text "画面放大:${video-zoom}" #menu: 画面 > 画面缩放 > 画面放大 +ALT+LEFT add video-pan-x -0.1;show-text "画面左移动:${video-pan-x}" #menu: 画面 > 画面缩放 > 画面左移动 +ALT+RIGHT add video-pan-x 0.1;show-text "画面右移动:${video-pan-x}" #menu: 画面 > 画面缩放 > 画面右移动 +ALT+UP add video-pan-y -0.1;show-text "画面上移动:${video-pan-y}" #menu: 画面 > 画面缩放 > 画面上移动 +ALT+DOWN add video-pan-y 0.1;show-text "画面下移动:${video-pan-y}" #menu: 画面 > 画面缩放 > 画面下移动 +ALT+p cycle-values panscan 0.0 1.0;show-text "视频画面缩放:${panscan}" #menu: 画面 > 开/关 裁切填充 #@state=(panscan and 'checked') +# ignore #menu: 画面 > --- +ALT+BS set video-zoom 0;set panscan 0;set video-rotate 0;set video-pan-x 0;set video-pan-y 0;set video-aspect-override -1;show-text "重置画面操作" #menu: 画面 > 重置以上画面操作 +# ignore #menu: 画面 > --- +CTRL+I cycle icc-profile-auto ;show-text "ICC 自动校色:${icc-profile-auto}" #menu: 画面 > 开/关 自动 ICC 校色 #@state=(icc_profile_auto and 'checked') +# cycle sigmoid-upscaling;show-text "非线性色彩转换:${sigmoid-upscaling}" #menu: 画面 > 开/关 非线性色彩转换 #@state=(sigmoid_upscaling and 'checked') +1 add contrast -1;show-text "对比度:${contrast}" #menu: 画面 > 调色 > 对比度 -1 +2 add contrast 1;show-text "对比度:${contrast}" #menu: 画面 > 调色 > 对比度 +1 +3 add brightness -1;show-text "明度:${brightness}" #menu: 画面 > 调色 > 明度 -1 +4 add brightness 1;show-text "明度:${brightness}" #menu: 画面 > 调色 > 明度 +1 +5 add gamma -1;show-text "伽马:${gamma}" #menu: 画面 > 调色 > 伽马 -1 +6 add gamma 1;show-text "伽马:${gamma}" #menu: 画面 > 调色 > 伽马 +1 +7 add saturation -1;show-text "饱和度:${saturation}" #menu: 画面 > 调色 > 饱和度 -1 +8 add saturation 1;show-text "饱和度:${saturation}" #menu: 画面 > 调色 > 饱和度 +1 +- add hue -1;show-text "色相:${hue}" #menu: 画面 > 调色 > 色相 -1 += add hue 1;show-text "色相:${hue}" #menu: 画面 > 调色 > 色相 +1 +CTRL+BS set contrast 0;set brightness 0;set gamma 0;set saturation 0;set hue 0;show-text "重置调色" #menu: 画面 > 调色 > 重置 +D cycle deband;show-text "去色带:${deband}" #menu: 画面 > 去色带 > deband 开关 #@state=(deband and 'checked') +ALT+z add deband-iterations +1;show-text "增加去色带强度:${deband-iterations}" #menu: 画面 > 去色带 > deband 强度 +1 +ALT+x add deband-iterations -1;show-text "降低去色带强度:${deband-iterations}" #menu: 画面 > 去色带 > deband 强度 -1 +h cycle-values tone-mapping auto spline bt.2390 hable bt.2446a st2094-40 st2094-10;show-text "HDR 映射曲线:${tone-mapping}" #menu: 画面 > HDR 相关 > 切换 HDR 映射曲线 +ALT+h cycle-values hdr-compute-peak yes no;show-text "HDR 动态映射:${hdr-compute-peak}" #menu: 画面 > HDR 相关 > 切换 HDR 动态映射 #@state=(hdr_compute_peak and 'checked') +CTRL+h cycle target-colorspace-hint;show-text "HDR 直通模式:${target-colorspace-hint}" #menu: 画面 > HDR 相关 > 切换 HDR 直通模式 #@state=(target_colorspace_hint and 'checked') +CTRL+t cycle-values target-trc auto pq gamma2.2;show-text "显示器传输特性:${target-trc}" #menu: 画面 > HDR 相关 > 切换 显示器传输特性 +CTRL+T cycle-values target-peak 100 203;show-text "映射目标峰值:${target-peak}" #menu: 画面 > HDR 相关 > 切换 映射目标峰值 +CTRL+g cycle gamut-mapping-mode ;show-text "色域映射模式:${gamut-mapping-mode}" #menu: 画面 > HDR 相关 > 切换 色域映射模式 +# cycle tone-mapping-visualize;show-text "色调映射可视化模式:${tone-mapping-visualize}" #menu: 画面 > HDR 相关 > 切换 色调映射可视化模式 +# ignore #menu: --- + +##⇘⇘menu 一级菜单:轨道 +# ignore #menu: 菜单 > 轨道 #@tracks +# ignore #menu: 菜单 > 次字幕 #@tracks/sub-secondary +# ignore #menu: 菜单 > 章节列表 #@chapters +# ignore #menu: 菜单 > 版本列表 #@editions +# ignore #menu: --- + +##⇘⇘uosc 一级菜单:视频 +# cycle video #menu: 视频 > 切换 视频轨 +# set hwdec "no" #menu: 视频 > 切换 解码方式 > 软解 +# set hwdec "auto-safe" #menu: 视频 > 切换 解码方式 > 自动选择硬解加速模式 +# set hwdec "auto-copy-safe" #menu: 视频 > 切换 解码方式 > 自动选择 copy 硬解模式 +# set hwdec "nvdec" #menu: 视频 > 切换 解码方式 > nvdec 硬解 +# set hwdec "nvdec-copy" #menu: 视频 > 切换 解码方式 > nvdec-copy 硬解 +# set video-sync audio;show-text "帧同步模式:${video-sync}" #menu: 视频 > 切换 帧同步模式 > audio +# set video-sync display-resample;show-text "帧同步模式:${video-sync}" #menu: 视频 > 切换 帧同步模式 > display-resample +# set video-sync display-tempo;show-text "帧同步模式:${video-sync}" #menu: 视频 > 切换 帧同步模式 > display-tempo +# set video-sync display-vdrop;show-text "帧同步模式:${video-sync}" #menu: 视频 > 切换 帧同步模式 > display-vdrop +# set video-sync display-resample-vdrop;show-text "帧同步模式:${video-sync}" #menu: 视频 > 切换 帧同步模式 > display-resample-vdrop +# cycle-values video-sync display-resample display-tempo audio display-vdrop display-resample-vdrop;show-text "帧同步模式:${video-sync}" #menu: 视频 > 切换 帧同步模式 > 循环切换 +ALT+i cycle interpolation ;show-text "抖动补偿:${interpolation}" #menu: 视频 > 开/关 抖动补偿 #@state=(interpolation and 'checked') +d cycle deinterlace;show-text "去交错:${deinterlace}" #menu: 视频 > 开/关 反交错 #@state=(deinterlace and 'checked') +# cycle vd-lavc-assume-old-x264;show-text "兼容 x264 旧编码模式:${vd-lavc-assume-old-x264}" #menu: 视频 > 开/关 兼容 x264 旧编码模式 #@state=(vd_lavc_assume_old_x264 and 'checked') +# ignore #menu: 视频 > --- +s screenshot subtitles #menu: 视频 > 截屏 > 同源尺寸 - 有字幕 - 无 OSD-单帧 +S screenshot video #menu: 视频 > 截屏 > 同源尺寸 - 无字幕 - 无 OSD-单帧 +CTRL+s show-text "截屏" 400;script-message delay-command 0.5 screenshot window #menu: 视频 > 截屏 > 实际尺寸 - 有字幕 - 有 OSD-单帧 +ALT+s screenshot subtitles+each-frame #menu: 视频 > 截屏 > 同源尺寸 - 有字幕 - 无 OSD-逐帧 +ALT+S screenshot video+each-frame #menu: 视频 > 截屏 > 同源尺寸 - 无字幕 - 无 OSD-逐帧 +CTRL+S show-text "逐帧截屏" 400;script-message delay-command 0.5 screenshot window+each-frame #menu: 视频 > 截屏 > 实际尺寸 - 有字幕 - 有 OSD-逐帧 + +##⇘⇘uosc 一级菜单:音频 +# script-message-to uosc audio-device #menu: 音频 > 音频设备列表 #@audio-devices +# ignore #menu: 音频 > --- +y cycle audio;show-text "音轨切换为:${audio}" #menu: 音频 > 切换 音频轨 +m cycle mute;show-text "静音:${mute}" #menu: 音频 > 切换 静音 #@state=(mute and 'checked') +# ignore #menu: 音频 > --- +CTRL+, add audio-delay -0.1;show-text "音频延迟:${audio-delay}" #menu: 音频 > 延迟 -0.1 +CTRL+. add audio-delay 0.1;show-text "音频预载:${audio-delay}" #menu: 音频 > 延迟 +0.1 +; set audio-delay 0 ;show-text "重置音频延迟:${audio-delay}" #menu: 音频 > 延迟 重置 +# ignore #menu: 音频 > --- +# cycle audio-normalize-downmix;show-text "音频规格化:${audio-normalize-downmix}" #menu: 音频 > 切换 音频规格化 #@state=(audio_normalize_downmix and 'checked') +CTRL+y cycle audio-exclusive ;show-text "音频独占模式:${audio-exclusive}" #menu: 音频 > 切换 音频独占模式 #@state=(audio_exclusive and 'checked') +CTRL+Y cycle hr-seek-framedrop;show-text "音频同步模式:${hr-seek-framedrop}" #menu: 音频 > 切换 音频同步模式 #@state=(hr_seek_framedrop and 'checked') +# set audio-channels "7.1";show-text "音频通道输出方式:${audio-channels}" #menu: 音频 > 音频通道输出方式 > 7.1 声道输出 +# set audio-channels "5.1";show-text "音频通道输出方式:${audio-channels}" #menu: 音频 > 音频通道输出方式 > 5.1 声道输出 +# set audio-channels "stereo";show-text "音频通道输出方式:${audio-channels}" #menu: 音频 > 音频通道输出方式 > 双通道输出 +# set audio-channels "7.1,5.1,stereo";show-text "音频通道输出方式:${audio-channels}" #menu: 音频 > 音频通道输出方式 > 自动选择以上输出方式 +ALT+y cycle-values audio-channels "7.1,5.1,stereo" "7.1" "5.1" "stereo" "auto-safe" "auto";show-text "音频通道输出方式:${audio-channels}" #menu: 音频 > 音频通道输出方式 > 循环切换 +F2 cycle-values af "@dynaudnorm:lavfi=[dynaudnorm=f=500:g=31:p=0.5:m=5:r=0.9]" "@loudnorm:lavfi=[loudnorm=I=-16:TP=-1.5:LRA=11]" "" #menu: 音频 > 切换 下混滤镜 +ALT+` af clr "" #menu: 音频 > 清空 af 滤镜 + +##⇘⇘uosc 一级菜单:字幕 +j cycle sub;show-text "字幕切换为:${sub}" #menu: 字幕 > 切换 字幕轨 +k cycle secondary-sid;show-text "切换次字幕:${secondary-sid}" #menu: 字幕 > 切换 次字幕 +v cycle sub-visibility;show-text "字幕可见性:${sub-visibility}" #menu: 字幕 > 切换 字幕可见性 #@state=(sub_visibility and 'checked') +ALT+V cycle secondary-sub-visibility;show-text "次字幕可见性:${secondary-sub-visibility}" #menu: 字幕 > 切换 次字幕可见性 #@state=(secondary_sub_visibility and 'checked') +u cycle sub-ass-override;show-text "字幕渲染样式:${sub-ass-override}" #menu: 字幕 > 切换 渲染样式 +F cycle-values sub-font "Noto Sans CJK SC" "Noto Sans CJK KR" "Noto Serif CJK SC" "Noto Serif CJK KR";show-text "字幕字体:${sub-font}" #menu: 字幕 > 切换 默认字体 +CTRL+r sub-reload;show-text "重载当前字幕" #menu: 字幕 > 重载当前字幕 +# ignore #menu: 字幕 > --- +ALT+R cycle secondary-sub-ass-override;show-text "次字幕样式覆盖:${secondary-sub-ass-override}" #menu: 字幕 > 兼容性 > 切换 次字幕样式覆盖 #@state=(secondary_sub_ass_override and 'checked') +ALT+T cycle blend-subtitles;show-text "字幕混合视频帧:${blend-subtitles}" #menu: 字幕 > 兼容性 > 切换 字幕混合视频帧 #@state=(blend_subtitles and 'checked') +K cycle sub-fix-timing ;show-text "字幕时序修复:${sub-fix-timing}" #menu: 字幕 > 兼容性 > 切换 字幕时序修复 #@state=(sub_fix_timing and 'checked') +J cycle sub-ass-vsfilter-color-compat ;show-text "字幕颜色转换方式:${sub-ass-vsfilter-color-compat}" #menu: 字幕 > 兼容性 > 切换 字幕颜色转换方式 +V cycle sub-ass-use-video-data ;show-text "使用视频信息:${sub-ass-use-video-data}" #menu: 字幕 > 兼容性 > 切换 使用视频信息 +ALT+B cycle sub-vsfilter-bidi-compat ;show-text "bidi 双向检测兼容性:${sub-vsfilter-bidi-compat}" #menu: 字幕 > 兼容性 > 切换 bidi 双向检测兼容性 #@state=(sub_vsfilter_bidi_compat and 'checked') +ALT+X cycle-values sub-ass-style-overrides "ScaledBorderAndShadow=no" "ScaledBorderAndShadow=yes";show-text "强制替换 ass 样式:${sub-ass-style-overrides}" #menu: 字幕 > 兼容性 > 切换 ass 字幕阴影边框缩放 +H cycle sub-ass-force-margins ;show-text "ass 字幕输出黑边:${sub-ass-force-margins}" #menu: 字幕 > 兼容性 > 切换 ass 字幕输出到黑边 #@state=(sub_ass_force_margins and 'checked') +ALT+Z cycle sub-use-margins ;show-text "srt 字幕输出黑边:${sub-use-margins}" #menu: 字幕 > 兼容性 > 切换 srt 字幕输出到黑边 #@state=(sub_use_margins and 'checked') +P cycle stretch-image-subs-to-screen ;show-text "pgs 字幕输出黑边:${stretch-image-subs-to-screen}" #menu: 字幕 > 兼容性 > 切换 pgs 字幕输出到黑边 #@state=(stretch_image_subs_to_screen and 'checked') +p cycle sub-gray;show-text "pgs 字幕灰度转换:${sub-gray}" #menu: 字幕 > 兼容性 > 切换 pgs 字幕灰度转换 #@state=(sub_gray and 'checked') +# ignore #menu: 字幕 > --- +Y script-message sub-select toggle #menu: 字幕 > 切换 字幕选择脚本 +CTRL+f script-message-to sub_assrt sub-assrt #menu: 字幕 > 打开 字幕下载菜单 +CTRL+m script-message-to autosubsync autosubsync-menu #menu: 字幕 > 打开 字幕同步菜单 +CTRL+M script-binding select/select-subtitle-line #menu: 字幕 > 打开 字幕内容菜单 +ALT+m script-message-to sub_export export-selected-subtitles #menu: 字幕 > 导出当前内封字幕 +# ignore #menu: 字幕 > --- +r add sub-pos -1;show-text "字幕上移:${sub-pos}" #menu: 字幕 > 其他操作 > 字幕上移 +t add sub-pos +1;show-text "字幕下移:${sub-pos}" #menu: 字幕 > 其他操作 > 字幕下移 +R add secondary-sub-pos -1;show-text "次字幕上移:${secondary-sub-pos}" #menu: 字幕 > 其他操作 > 次字幕上移 +T add secondary-sub-pos +1;show-text "次字幕下移:${secondary-sub-pos}" #menu: 字幕 > 其他操作 > 次字幕下移 +z add sub-delay -0.1;show-text "字幕延迟:${sub-delay}" #menu: 字幕 > 其他操作 > 字幕延迟 -0.1 +x add sub-delay 0.1;show-text "字幕预载:${sub-delay}" #menu: 字幕 > 其他操作 > 字幕延迟 +0.1 +Z add secondary-sub-delay -0.1;show-text "次字幕延迟:${secondary-sub-delay}" #menu: 字幕 > 其他操作 > 次字幕延迟 -0.1 +X add secondary-sub-delay 0.1;show-text "次字幕预载:${secondary-sub-delay}" #menu: 字幕 > 其他操作 > 次字幕延迟 +0.1 +ALT+j add sub-scale -0.1;show-text "字幕缩小:${sub-scale}" #menu: 字幕 > 其他操作 > 字号 -0.1 +ALT+k add sub-scale 0.1;show-text "字幕放大:${sub-scale}" #menu: 字幕 > 其他操作 > 字号 +0.1 +CTRL+j sub-seek -1 #menu: 字幕 > 其他操作 > 跳转上一条字幕 +CTRL+k sub-seek 1 #menu: 字幕 > 其他操作 > 跳转下一条字幕 +SHIFT+BS set sub-pos 100;set sub-scale 1.0;set sub-delay 0;show-text "重置字幕状态" #menu: 字幕 > 其他操作 > 恢复初始 + +##⇘⇘uosc 一级菜单:视频滤镜 +CTRL+` vf clr "" #menu: 视频滤镜 > 清空 +ALT+v vf toggle deblock=filter=weak:block=4 #menu: 视频滤镜 > 开/关 去色块滤镜 +! vf toggle format=colorlevels=limited #menu: 视频滤镜 > 开/关 动态范围限制 +@ vf toggle vflip #menu: 视频滤镜 > 开/关 垂直翻转 +SHARP vf toggle hflip #menu: 视频滤镜 > 开/关 水平翻转 +$ vf toggle rotate=angle=180*PI/180 #menu: 视频滤镜 > 开/关 旋转 180 +% vf toggle format:gamma=gamma2.2 #menu: 视频滤镜 > 开/关 伽马修正 2.2 +^ vf toggle fps=fps=60/1.001 #menu: 视频滤镜 > 开/关 强制帧数 59.94 +* vf toggle pad=aspect=16/9:x=-1:y=-1 #menu: 视频滤镜 > 开/关 填充 16:9 的黑边并居中 +& vf toggle colortemperature=temperature=6500 #menu: 视频滤镜 > 开/关 色温修正 6500 + +##⇘⇘uosc 一级菜单:着色器 +CTRL+0 change-list glsl-shaders clr "" #menu: 着色器 > 清空 +CTRL+1 change-list glsl-shaders toggle "~~/shaders/igv/KrigBilateral.glsl" #menu: 着色器 > IGV > 开/关 KrigBilateral +CTRL+2 change-list glsl-shaders toggle "~~/shaders/igv/SSimSuperRes.glsl" #menu: 着色器 > IGV > 开/关 SSimSuperRes +CTRL+3 change-list glsl-shaders toggle "~~/shaders/igv/SSimDownscaler.glsl" #menu: 着色器 > IGV > 开/关 SSimDownscaler +CTRL+4 change-list glsl-shaders toggle "~~/shaders/igv/adaptive-sharpen.glsl" #menu: 着色器 > IGV > 开/关 自适应锐化 +# change-list glsl-shaders toggle "~~/shaders/igv/adaptive-sharpen_luma.glsl" #menu: 着色器 > IGV > 开/关 自适应锐化-luma +CTRL+5 change-list glsl-shaders toggle "~~/shaders/igv/FSRCNNX_x2_8-0-4-1.glsl" #menu: 着色器 > FSRCNNX > 开/关 FSRCNNX +# change-list glsl-shaders toggle "~~/shaders/igv/FSRCNNX_x2_16-0-4-1.glsl" #menu: 着色器 > FSRCNNX > 开/关 FSRCNNX-16x +CTRL+6 change-list glsl-shaders toggle "~~/shaders/igv/FSRCNNX_x1_16-0-4-1_distort.glsl" #menu: 着色器 > FSRCNNX > 开/关 FSRCNNX-distort +CTRL+7 change-list glsl-shaders toggle "~~/shaders/nnedi3/nnedi3-nns32-win8x4.glsl" #menu: 着色器 > NNEDI3 > 开/关 nns32-4 +# change-list glsl-shaders toggle "~~/shaders/nnedi3/nnedi3-nns32-win8x6.glsl" #menu: 着色器 > NNEDI3 > 开/关 nns32-6 +# change-list glsl-shaders toggle "~~/shaders/nnedi3/nnedi3-nns64-win8x4.glsl" #menu: 着色器 > NNEDI3 > 开/关 nns64-4 +# change-list glsl-shaders toggle "~~/shaders/nnedi3/nnedi3-nns64-win8x6.glsl" #menu: 着色器 > NNEDI3 > 开/关 nns64-6 +# change-list glsl-shaders toggle "~~/shaders/nnedi3/nnedi3-nns128-win8x4.glsl" #menu: 着色器 > NNEDI3 > 开/关 nns128-4 +# change-list glsl-shaders toggle "~~/shaders/nnedi3/nnedi3-nns128-win8x6.glsl" #menu: 着色器 > NNEDI3 > 开/关 nns128-6 +CTRL+8 change-list glsl-shaders toggle "~~/shaders/ravu/ravu-zoom-ar-r3.glsl" #menu: 着色器 > RAVU > 开/关 ravu-zoom-ar +# change-list glsl-shaders toggle "~~/shaders/ravu/ravu-lite-ar-r3.glsl" #menu: 着色器 > RAVU > 开/关 ravu-lite-ar +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Restore/Anime4K_Clamp_Highlights.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 去伪影 +CTRL+9 change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Restore/Anime4K_Restore_CNN_Soft_M.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 抗锯齿 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Restore/Anime4K_Restore_CNN_Soft_VL.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 中强度抗锯齿 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Restore/Anime4K_Restore_CNN_Soft_UL.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 高强度抗锯齿 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Experimental-Effects/Anime4K_Darken_HQ.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 深线 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Experimental-Effects/Anime4K_Thin_HQ.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 收线 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Denoise/Anime4K_Denoise_Bilateral_Mode.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 降噪 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Deblur/Anime4K_Deblur_DoG.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 去糊 +# change-list glsl-shaders toggle "~~/shaders/Anime4K/glsl/Upscale/Anime4K_Upscale_CNN_x2_S.glsl" #menu: 着色器 > Anime4K > 开/关 Anime4K 放大 +# change-list glsl-shaders toggle "~~/shaders/other/PixelClipper.glsl" #menu: 着色器 > Other > 开/关 抗振铃 +# script-message cycle-commands "change-list glsl-shaders pre '~~/shaders/other/nlmeans_luma.glsl'" "change-list glsl-shaders remove '~~/shaders/other/nlmeans_luma.glsl'" #menu: 着色器 > Other > 开/关 nlmeans-luma 降噪 + +##⇘⇘uosc 一级菜单:其它 +CTRL+P script-message cycle-commands "apply-profile FSRCNNX;show-text 配置组:FSRCNNX" "apply-profile FSRCNNX+;show-text 配置组:FSRCNNX+" "apply-profile NNEDI3;show-text 配置组:NNEDI3" "apply-profile ravu-zoom;show-text 配置组:ravu-zoom" "apply-profile Anime4K;show-text 配置组:Anime4K" #menu: 其它 > 常规配置组 > 切换 指定配置组 +ALT+1 apply-profile FSRCNNX;show-text "配置组:FSRCNNX" #menu: 其它 > 常规配置组 > 切换 FSRCNNX 配置 +ALT+2 apply-profile FSRCNNX+;show-text "配置组:FSRCNNX+" #menu: 其它 > 常规配置组 > 切换 FSRCNNX+ 配置 +ALT+3 apply-profile ravu-zoom;show-text "配置组:ravu-zoom" #menu: 其它 > 常规配置组 > 切换 Ravu-zoom 配置 +ALT+4 apply-profile Ani4K;show-text "配置组:Ani4K" #menu: 其它 > 常规配置组 > 切换 Ani4K 配置 +ALT+5 apply-profile AniSD;show-text "配置组:AniSD" #menu: 其它 > 常规配置组 > 切换 AniSD 配置 +ALT+6 apply-profile Anime4K;show-text "配置组:Anime4K" #menu: 其它 > 常规配置组 > 切换 Anime4k 配置 +ALT+7 apply-profile NNEDI3;show-text "配置组:NNEDI3" #menu: 其它 > 常规配置组 > 切换 NNEDI3 配置 +ALT+8 apply-profile NNEDI3+;show-text "配置组:NNEDI3+" #menu: 其它 > 常规配置组 > 切换 NNEDI3+ 配置 +# apply-profile SSIM;show-text "配置组:SSIM" #menu: 其它 > 常规配置组 > 切换 SSIM 配置 +# cycle border;show-text "显示边框:${border}" #menu: 其它 > 切换 边框模式 #@state=(border and 'checked') +CTRL+B cycle title-bar;show-text "显示标题栏:${title-bar}" #menu: 其它 > 切换 标题栏 #@state=(title_bar and 'checked') +# cycle-values title ${media-title} ${filename} #menu: 其它 > 切换 媒体标题 +~ script-binding console/enable #menu: 其它 > 打开 控制台 +CTRL+R cycle-values reset-on-next-file "all" "no" "vf,af,loop-file,deinterlace,border,contrast,brightness,gamma,saturation,hue,video-zoom,video-rotate,video-pan-x,video-pan-y,panscan,speed,audio,sub,audio-delay,sub-pos,sub-scale,sub-delay,sub-speed,sub-visibility";show-text "播放下一个文件时重置以下选项:${reset-on-next-file}" #menu: 其它 > 重置播放中更改项 + +##⇘⇘uosc 一级菜单:工具 +Ctrl+p script-message-to command_palette show-command-palette "Command Palette" #menu: 工具 > 打开命令面板 +# set clipboard/text ${filename} #menu: 工具 > 复制文件信息 > 复制当前文件名 +# set clipboard/text ${path} #menu: 工具 > 复制文件信息 > 复制当前文件路径 +CTRL+ALT+t set clipboard/text ${time-pos} #menu: 工具 > 复制文件信息 > 复制当前时间 +CTRL+ALT+s set clipboard/text ${sub-text} #menu: 工具 > 复制文件信息 > 复制当前字幕内容 +# script-message-to uosc open-config-directory #menu: 工具 > 定位配置文件 +M script-message manager-update-all ;show-text "更新脚本着色器" #menu: 工具 > 一键更新脚本和着色器 +CTRL+d script-message-to uosc_danmaku show_danmaku_keyboard #menu: 工具 > 弹幕功能 > 开/关 弹幕显示 +CTRL+D script-message-to uosc_danmaku open_add_total_menu #menu: 工具 > 弹幕功能 > 打开弹幕综合菜单 +CTRL+ALT+d script-message danmaku-delay 1 ${=time-pos} #menu: 工具 > 弹幕功能 > 弹幕延迟 +1 秒 +CTRL+ALT+a script-message danmaku-delay -1 ${=time-pos} #menu: 工具 > 弹幕功能 > 弹幕延迟 -1 秒 +_ script-message-to uosc_danmaku immediately_save_danmaku #menu: 工具 > 弹幕功能 > 保存当前弹幕 +# ignore #menu: --- + +##⇘⇘uosc 一级菜单 +b cycle window-minimized #menu: 最小化 +q quit #menu: 退出程序 +Q quit-watch-later # 退出并保存当前状态 + +##⇘⇘以下键位不显示在 uosc 菜单中 +MENU script-message-to uosc menu-blurred # 开/关 uosc 菜单 +POWER quit +PLAY cycle pause;script-message-to uosc flash-pause-indicator +PAUSE cycle pause;script-message-to uosc flash-pause-indicator +PLAYPAUSE cycle pause;script-message-to uosc flash-pause-indicator +STOP quit +FORWARD seek 30 +REWIND seek -30 +NEXT playlist-next +PREV playlist-prev + +SPACE cycle pause;script-message-to uosc flash-pause-indicator + +MBTN_LEFT cycle pause;script-message-to uosc flash-pause-indicator +MBTN_LEFT_DBL ignore +MBTN_Right script-message-to uosc menu-blurred # 开/关 uosc 菜单 +MBTN_FORWARD playlist-next;show-text "播放列表:${playlist-pos-1}/${playlist-count}" # 前进键 切换到列表中的下个文件 +MBTN_BACK playlist-prev;show-text "播放列表:${playlist-pos-1}/${playlist-count}" # 后退键 切换到列表中的上个文件 +MBTN_Right_DBL ignore +Wheel_Up no-osd add volume 10; script-message-to uosc flash-volume +Wheel_Down no-osd add volume -10; script-message-to uosc flash-volume +ESC set fullscreen no;set window-maximized no + +9 no-osd add volume -1; script-message-to uosc flash-volume # 音量 -1 +0 no-osd add volume 1; script-message-to uosc flash-volume # 音量 +1 diff --git a/inputevent_key.conf b/inputevent_key.conf new file mode 100644 index 0000000..eac4f6e --- /dev/null +++ b/inputevent_key.conf @@ -0,0 +1,29 @@ +##⇘⇘以下为基于 inputevent.lua 脚本实现的增强式功能键位绑定 +## '#event:click'用于指定同键位单击时的操作,'#event:double_click'用于指定同键位双击时的操作,'#event:press'用于指定同键位长按时的操作,'#event:release'用于指定同键位长按释放时的操作 +## 更多的键位动作请参考脚本上游说明:https://github.com/zhongfly/InputEvent/tree/property-expansion +##! 注意:并非所有键位都具有以上不同的触发动作 +## 同时脚本支持同一种动作根据条件触发不同的命令,条件的语法等同于 profile-cond(自动 profile 的条件语句) +## 即脚本语法升级为 '#event:动作|条件'(原先的#event:动作视为无条件执行命令),命令执行的优先级是从下到上按顺序,执行第一个满足条件的命令 + +RIGHT seek 5 #event:click +RIGHT script-message-to evafast speedup #event:press +RIGHT script-message-to evafast slowdown #event:release + +TAB script-message-to uosc open-file #event:click +TAB script-message-to uosc toggle-ui #event:press +TAB script-message-to uosc toggle-ui #event:release + +PGDWN add chapter -1 #event:click +PGDWN playlist-prev;show-text 播放列表:${playlist-pos-1}/${playlist-count} #event:click|chapter == 0 +PGDWN playlist-prev;show-text 播放列表:${playlist-pos-1}/${playlist-count} #event:press +PGUP add chapter 1 #event:click +PGUP playlist-next;show-text 播放列表:${playlist-pos-1}/${playlist-count} #event:click|chapter+1 == chapters +PGUP playlist-next;show-text 播放列表:${playlist-pos-1}/${playlist-count} #event:press + +SPACE cycle pause;script-message-to uosc flash-pause-indicator #event:click +SPACE script-binding simplehistory/history-load-last #event:click|idle_active +SPACE no-osd set speed 3; set pause no #event:press +SPACE ignore #event:release + +MBTN_LEFT cycle pause;script-message-to uosc flash-pause-indicator #event:click +MBTN_LEFT cycle fullscreen #event:double_click diff --git a/manager.json b/manager.json new file mode 100644 index 0000000..c759388 --- /dev/null +++ b/manager.json @@ -0,0 +1,120 @@ +[ + { + "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" + } +] diff --git a/mpv.conf b/mpv.conf new file mode 100644 index 0000000..a107d22 --- /dev/null +++ b/mpv.conf @@ -0,0 +1,434 @@ +# ===== 基础设置 ===== + +vo=gpu-next # 视频输出驱动 +gpu-api=vulkan # 图形绘制接口 +input-ime=no # 仅文本输入时激活 IME +autofit-smaller=40%x30% # 窗口最小占屏比例 +idle=yes # 播放结束后保持运行 +ontop # 窗口置顶 +hr-seek=yes # 精确跳转 +hr-seek-framedrop=no # 跳转时不丢帧,利于修正音频延迟 +save-position-on-quit=yes # 退出时记住播放进度 +write-filename-in-watch-later-config # 播放记录中写入文件名 +resume-playback-check-mtime=yes # 校验文件修改时间防止误恢复 +watch-later-dir="~~/cache/watch_later" +watch-later-options=start,vid,aid,sid +save-watch-history=yes # 保存播放历史(内置 select 脚本可浏览) +watch-history-path=~~/files/watch_history.jsonl +reset-on-next-file=vid,aid,sid,secondary-sid,vf,af,loop-file,deinterlace,contrast,brightness,gamma,saturation,hue,video-zoom,video-rotate,video-pan-x,video-pan-y,panscan,speed,audio-delay,sub-pos,sub-scale,sub-delay,sub-speed,sub-visibility,secondary-sub-visibility +input-ipc-server=/tmp/mpvsocket # IPC 套接字 +directory-mode=ignore # 打开目录时忽略子目录 +metadata-codepage=auto # 元数据编码自动检测 +msg-level=all=info,auto_profiles=warn +title=${?pause==yes:⏸}${?mute==yes:🔇}${?ontop==yes:📌}${?demuxer-via-network==yes:${media-title}}${?demuxer-via-network==no:${filename}} + +# ===== OSD ===== + +no-osd-bar +osd-on-seek=msg-bar +osd-bar-w=100 +osd-bar-h=2 +osd-bar-align-y=-1 +osd-font="Noto Sans CJK SC;Noto Color Emoji" +osd-font-size=24 +osd-color="#FFFFFF" +osd-outline-size=1.0 +osd-outline-color="#1C1B1F" +osd-shadow-offset=0 +osd-back-color="#1C1B1F" +osd-border-style=outline-and-shadow +osd-playlist-entry=filename +osd-status-msg=${playback-time/full} / ${duration/full} (${percent-pos}%)\nframe: ${estimated-frame-number} / ${estimated-frame-count} +osd-fractions=yes +osd-duration=2000 + +# ===== 色彩管理 ===== + +icc-profile-auto # 自动检测系统 ICC 配置文件 +icc-intent=0 # 感知度映射意图 +icc-force-contrast=1000 # 解决校色文件对比度问题 +icc-3dlut-size=128x128x128 # 3D LUT 精度 +icc-cache-dir="~~/cache/icc_cache" +use-embedded-icc-profile=yes # 使用嵌入式 ICC 配置文件 +inverse-tone-mapping=yes # SDR→HDR 反向映射(仅 HDR 显示器有效) +target-colorspace-hint=auto # 自动配置显示器输出色彩空间 +hdr-contrast-recovery=0.30 # HDR 对比度恢复强度 +hdr-compute-peak=yes # 动态峰值检测 + +# ===== 音频 ===== + +audio-device=auto +audio-channels=7.1,5.1,stereo # 按优先级回退,避免多声道下混丢声道 +ao=alsa +audio-exclusive=yes # 独占音频通道 +audio-samplerate=96000 # 重采样至 96kHz +audio-format=s32 # 32位有符号整数 +replaygain=album # 专辑增益优先,无专辑增益时回退到曲目增益 +gapless-audio=no # 避免采样率锁定导致音质下降 +audio-file-auto=fuzzy # 自动加载同名外部音轨 +audio-file-paths=audio;audios;audio 5.1;audios 5.1;audio 7.1;audios 7.1;音轨 +alang=japanese,jpn,jap,ja,jp,english,eng,en + +# ===== 字幕 ===== + +sub-codepage=gb18030 # 非 UTF-8 字幕首先尝试 GB18030 +sub-auto=fuzzy # 自动加载同名外部字幕 +sub-file-paths=sub;subs;subtitles;字幕 +slang=chs,sc,zh-Hans,zh-CN,cht,tc,zh-Hant,zh-HK,zh-TW,chi,zho,zh +sub-font="Noto Sans CJK SC;Noto Color Emoji" +sub-font-size=50 +sub-bold=yes +sub-color="#FFFFFF" +sub-outline-size=0.5 +sub-outline-color="#000000" +sub-shadow-offset=0.5 +sub-back-color="#000000" + +# ===== 截图 ===== + +screenshot-format=webp +screenshot-webp-quality=85 +screenshot-webp-compression=6 +screenshot-tag-colorspace=no +screenshot-template="~~/files/screen/%{media-title}-%P-%n" + +# ===== 脚本与着色器 ===== + +gpu-shader-cache-dir="~~/cache/shaders_cache" +osc=no # 禁用内置 OSC,使用 uosc +ytdl=yes +ytdl-format=bestvideo[height<=?2160][vcodec!=?vp9.2][vcodec!=?vp9]+bestaudio/best +ytdl-raw-options-append=cookies-from-browser=Firefox +input-default-bindings=no # 禁用内置键位,在 input.conf 中自定义 + +# ===== 外部配置 ===== + +include="~~/profiles.conf" # 场景预设(游戏/电影/动画等,手动激活) + +# ========================================= +# Profile 激活 +# ========================================= + +# 色彩管理(ICC 和 Target 二选一) +#profile=ICC # ICC 色彩管理,使用系统 ICC 配置文件 +#profile=ICC+ # ICC 色彩管理,使用自定义 ICC 文件 +profile=Target # Target 色彩管理,直接指定目标色彩空间 + +profile=Dither # 抖动算法(fruit) +#profile=Dither+ # 抖动算法(error-diffusion,更耗能) + +profile=Tscale # 时域插值(oversample) +#profile=Tscale+ # 时域插值(sphinx,更平滑但略模糊) + +profile=HQ # 高质量缩放算法组合 +profile=DeBand-low # 去色带(低强度) +#profile=DeBand-medium +#profile=DeBand-high + +profile=HDR2SDR # HDR 映射 SDR 参数 +#profile=SDR2HDR # SDR 反向映射 HDR(仅 HDR 显示器) +#profile=SWscaler # 软件缩放备选方案 + +# 着色器(选一) +#profile=NNEDI3 # 通用场景(NNEDI3-32) +profile=NNEDI3+ # 通用场景(NNEDI3-64,更耗能) +#profile=ravu-zoom # 通用场景(ravu-zoom) +#profile=FSRCNNX # HD 场景 +#profile=FSRCNNX+ # SD 场景(FSRCNNX 去伪影) +#profile=Ani4K # 动画(Ani4K V2,高性能开销) +#profile=AniSD # SD 动画(AniSD,高性能开销) +#profile=Anime4K # 动画(Anime4K 修复 + 去伪影) +#profile=SSIM # 低性能消耗 + +# ========================================= +# Profile 定义:常规 +# ========================================= + +[ICC] + # 使用系统 ICC 配置文件进行色彩管理 + icc-profile="" + icc-profile-auto + icc-intent=0 + icc-force-contrast=1000 + icc-3dlut-size=auto + icc-cache-dir="~~/cache/icc_cache" + +[ICC+] + # 使用自定义 ICC 文件(如 color.org 泛 ICC 或专业校色文件) + icc-profile="~~/icc/ITU-RBT709ReferenceDisplay.icc" + icc-intent=0 + icc-force-contrast=no + icc-3dlut-size=auto + icc-cache-dir="~~/cache/icc_cache" + +[Target] + # 不使用 ICC,直接指定目标色彩空间参数 + icc-profile="" + icc-profile-auto=no + target-prim=auto + target-contrast=auto + #target-trc=gamma2.2 # 非 OLED 显示器建议启用 + #target-peak=203 # SDR 显示器默认 203 nit + +[Dither] + dither-depth=auto + dither=fruit + dither-size-fruit=6 + +[Dither+] + dither-depth=auto + dither=error-diffusion + error-diffusion=floyd-steinberg + +[Tscale] + video-sync=display-resample + interpolation + tscale=oversample + +[Tscale+] + video-sync=display-resample + interpolation + tscale=sphinx + tscale-blur=0.65 + +[HQ] + scale=ewa_lanczossharp + cscale=bilinear + dscale=catmull_rom + scale-antiring=0.5 + dscale-antiring=0.5 + linear-upscaling=no + sigmoid-upscaling=yes + correct-downscaling=yes + linear-downscaling=no + deband=no + +[DeBand-low] + deband-iterations=1 + deband-threshold=48 + deband-range=16 + deband-grain=16 + +[DeBand-medium] + deband-iterations=2 + deband-threshold=64 + deband-range=16 + deband-grain=24 + +[DeBand-high] + deband-iterations=3 + deband-threshold=64 + deband-range=16 + deband-grain=24 + +[HDR2SDR] + tone-mapping=auto + gamut-mapping-mode=auto + hdr-contrast-recovery=0.30 + hdr-compute-peak=auto + hdr-peak-percentile=99.995 + hdr-peak-decay-rate=100 + hdr-scene-threshold-low=5.5 + hdr-scene-threshold-high=10 + allow-delayed-peak-detect=no + +[SDR2HDR] + # SDR 反向映射 HDR,仅 HDR 显示器有效 + icc-profile="" + icc-profile-auto=no + target-prim=auto + target-trc=auto + target-peak=auto + target-colorspace-hint=auto + inverse-tone-mapping=yes + +[SWscaler] + sws-allow-zimg=no + sws-scaler=bicublin + zimg-scaler-chroma=bicubic + zimg-scaler=bicubic + zimg-scaler-param-a=1/3 + zimg-scaler-param-b=1/3 + zimg-fast=no + +# --- 着色器 Profile --- + +[NNEDI3] + profile-desc=通用场景(NNEDI3-32 + 自适应锐化) + glsl-shaders-append="~~/shaders/nnedi3/nnedi3-nns32-win8x4.glsl" + glsl-shaders-append="~~/shaders/igv/adaptive-sharpen_luma.glsl" + +[NNEDI3+] + profile-desc=通用场景(NNEDI3-64 + 自适应锐化) + glsl-shaders-append="~~/shaders/nnedi3/nnedi3-nns64-win8x4.glsl" + glsl-shaders-append="~~/shaders/igv/adaptive-sharpen_luma.glsl" + +[ravu-zoom] + profile-desc=通用场景(ravu-zoom + 自适应锐化) + glsl-shaders-append="~~/shaders/ravu/ravu-zoom-ar-r3.glsl" + glsl-shaders-append="~~/shaders/igv/adaptive-sharpen_luma.glsl" + +[FSRCNNX] + profile-desc=HD 场景(FSRCNNX + 自适应锐化) + glsl-shaders-append="~~/shaders/igv/FSRCNNX_x2_8-0-4-1.glsl" + glsl-shaders-append="~~/shaders/igv/adaptive-sharpen_luma.glsl" + +[FSRCNNX+] + profile-desc=SD 场景(NNEDI3 + FSRCNNX 去伪影) + glsl-shaders-append="~~/shaders/nnedi3/nnedi3-nns32-win8x4.glsl" + glsl-shaders-append="~~/shaders/igv/FSRCNNX_x1_16-0-4-1_distort.glsl" + +[Ani4K] + profile-desc=动画(Ani4K V2,高性能开销) + glsl-shaders-append="~~/shaders/Ani4K/Ani4Kv2_ArtCNN_C4F32_i2.glsl" + +[AniSD] + profile-desc=SD 动画(AniSD,高性能开销) + glsl-shaders-append="~~/shaders/Ani4K/AniSD_ArtCNN_C4F32_i4.glsl" + +[Anime4K] + profile-desc=动画(Anime4K 修复 + 去伪影) + glsl-shaders-append="~~/shaders/igv/KrigBilateral.glsl" + glsl-shaders-append="~~/shaders/Anime4K/glsl/Restore/Anime4K_Restore_CNN_Soft_M.glsl" + glsl-shaders-append="~~/shaders/Anime4K/glsl/Restore/Anime4K_Clamp_Highlights.glsl" + +[SSIM] + profile-desc=低性能消耗(SSIM 超分 + 缩小) + glsl-shaders-append="~~/shaders/igv/SSimSuperRes.glsl" + glsl-shaders-append="~~/shaders/igv/SSimDownscaler.glsl" + +# ========================================= +# Profile 定义:条件触发 +# ========================================= + +[SD] + # 低清源(≤720p)自动启用 FSRCNNX+ 增强 + profile-cond=height <= 720 or width <= 720 + profile-restore=copy + profile=FSRCNNX+ + +[Deband] + # YUV420P10 以下自动开启去色带 + profile-cond=get("video-params/average-bpp") < 24 + profile-restore=copy + deband=yes + +[hdr-2390] + profile-cond=p.tone_mapping == "bt.2390" and p.current_vo == "gpu-next" + profile-restore=copy + tone-mapping-param=2.0 + +[peak-percentile] + profile-cond=get("video-params/avg-pq-y") < 0.21 and p.current_vo == "gpu-next" + profile-restore=copy + hdr-peak-percentile=99.8 + +[SDR-gamut] + # SDR 非 BT.709 内容的色域映射 + profile-cond=get("video-params/primaries") ~= "bt.709" and get("video-params/gamma") == "bt.1886" + profile-restore=copy + gamut-mapping-mode=clip + +[SDR-target] + # SDR 显示目标配置 + profile-cond=not get("video-params/max-luma") and not get("inverse-tone-mapping") and p.current_vo == "gpu-next" + profile-restore=copy + target-colorspace-hint=no + +[HDR] + # HDR 内容自动配置 + profile-cond=get("video-params/max-luma") > 203 + profile-restore=copy + target-peak=auto + target-colorspace-hint=auto + blend-subtitles=no + deband=no + vf="" + +[HDR-PASS] + # HDR 直通(仅 HDR 显示模式下生效) + profile-cond=get("video-params/max-luma") > 203 and get("video-target-params/max-luma") > 203 and p.current_vo == "gpu-next" + profile-restore=copy + icc-profile="" + icc-profile-auto=no + target-colorspace-hint=auto + inverse-tone-mapping=no + target-prim=auto + target-trc=auto + target-peak=auto + target-contrast=auto + +[video-sync] + # 音频调速超过阈值时切换同步模式,避免明显音高变化 + profile-cond=(speed * audio_speed_correction) > 0 and ((speed * audio_speed_correction) < 0.96 or (speed * audio_speed_correction) > 1.04) and not (get("estimated-vf-fps") > 240 or get("display-fps") > 240) + profile-restore=copy-equal + video-sync=display-tempo + +[fps-fix] + # 极高帧率/刷新率时使用 audio 同步避免异常 + profile-cond=get("estimated-vf-fps") > 240 or get("display-fps") > 240 + profile-restore=copy + video-sync=audio + +[pgs-fix] + # 修复宽屏视频 PGS 字幕比例错位 + profile-cond=get("video-params/aspect") > 16 / 9 + profile-restore=copy + stretch-image-subs-to-screen=yes + +[audio-filter] + # 多声道音频自动启用动态范围调节(适用于双声道设备) + profile-cond=get("audio-params/channel-count") > 2 + profile-restore=copy-equal + af-pre=@dynaudnorm:lavfi=[dynaudnorm=f=500:g=31:p=0.5:m=5:r=0.9] + +[pause] + # 暂停时取消置顶 + profile-cond=pause + profile-restore=copy + ontop=no + +[maximized] + # 最大化时禁止窗口自动调整大小 + profile-cond=window_maximized and vid and not get("current-tracks/video/albumart") + profile-restore=copy-equal + auto-window-resize=no + +[minimized] + # 最小化时自动暂停 + profile-cond=window_minimized and vid and not get("current-tracks/video/albumart") + profile-restore=copy-equal + pause + +[end] + # 播放列表结束后退出全屏 + profile-cond=idle_active + no-fullscreen + no-window-maximized + +[media-title] + # 网络/磁力链接显示媒体标题 + profile-cond=path:find('://') ~= nil or path:find('^magnet:') ~= nil + profile-restore=copy + title=${?pause==yes:⏸}${?mute==yes:🔇}${?ontop==yes:📌}${media-title} + osd-playlist-entry=title + +# ========================================= +# Profile 定义:网络优化 +# ========================================= + +[network-optimize] + # 网络播放时自动启用 + profile-cond=demuxer_via_network + profile-restore=copy + cache=yes + cache-secs=600 + demuxer-max-bytes=1GiB + demuxer-readahead-secs=120 + network-timeout=60 + stream-buffer-size=2MiB + prefetch-playlist=yes + stream-lavf-o-append=reconnect=1 + stream-lavf-o-append=reconnect_at_eof=1 + stream-lavf-o-append=reconnect_streamed=1 + stream-lavf-o-append=multiple_requests=1 diff --git a/profiles.conf b/profiles.conf new file mode 100644 index 0000000..40a622d --- /dev/null +++ b/profiles.conf @@ -0,0 +1,105 @@ +# 场景预设,手动激活:profile=game 等 + +[game] +profile-desc=低延迟,高性能 +hwdec=auto-safe +video-sync=display-resample +interpolation=no +deband=no +video-latency-hacks=yes +opengl-pbo=yes +gpu-api=vulkan +gpu-context=wayland +cache=no +demuxer-max-bytes=8MiB +demuxer-max-back-bytes=4MiB + +[movie] +profile-desc=高质量画质 +hwdec=auto-copy-safe +video-sync=display-resample +interpolation=yes +deband=yes +deband-iterations=4 +deband-threshold=35 +deband-range=16 +deband-grain=4 +icc-profile-auto=yes +target-colorspace-hint=yes +hdr-compute-peak=yes +tone-mapping=hable +target-peak=100 + +[anime] +profile-desc=动画优化 +hwdec=auto-safe +video-sync=display-resample +interpolation=yes +deband=yes +deband-iterations=3 +deband-threshold=48 +deband-range=16 +deband-grain=6 +icc-profile-auto=yes +glsl-shaders="~~/shaders/Anime4K/glsl/Restore/Anime4K_Restore_CNN_Soft_M.glsl;~~/shaders/Anime4K/glsl/Deblur/Anime4K_Deblur_DoG.glsl" + +[lowpower] +profile-desc=省电模式 +hwdec=no +video-sync=audio +interpolation=no +deband=no +icc-profile-auto=no +vd-lavc-threads=2 +vd-lavc-skiploopfilter=all +vd-lavc-fast=yes +scale=bilinear +dscale=bilinear +cscale=bilinear + +[stream] +profile-desc=网络流媒体优化 +hwdec=auto-safe +video-sync=display-resample +cache=yes +cache-secs=300 +demuxer-max-bytes=64MiB +demuxer-max-back-bytes=32MiB +network-timeout=60 +ytdl=yes +ytdl-format=bestvideo[height<=?1080][vcodec!=?vp9]+bestaudio/best + +[HDR-scene] +profile-desc=HDR 手动预设 +hwdec=auto-copy-safe +target-colorspace-hint=yes +hdr-compute-peak=yes +tone-mapping=hable +target-peak=203 +gamut-mapping-mode=relative +icc-profile-auto=yes +glsl-shaders="~~/shaders/other/PixelClipper.glsl" + +[screenshot-hq] +profile-desc=高质量截图 +screenshot-format=png +screenshot-png-compression=9 +screenshot-png-filter=5 +screenshot-tag-colorspace=yes +screenshot-high-bit-depth=yes +screenshot-sw=no +scale=lanczos +dscale=mitchell +cscale=mitchell + +[live] +profile-desc=直播低延迟 +hwdec=auto-safe +video-sync=display-resample +cache=no +demuxer-max-bytes=2MiB +demuxer-max-back-bytes=1MiB +video-latency-hacks=yes +opengl-pbo=yes +network-timeout=30 +stream-lavf-o=reconnect_streamed=1,reconnect_delay_max=30 diff --git a/script-modules/extended-menu.lua b/script-modules/extended-menu.lua new file mode 100644 index 0000000..1b8f925 --- /dev/null +++ b/script-modules/extended-menu.lua @@ -0,0 +1,932 @@ +-- 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' + +-- create namespace with default values +local em = { + + -- customisable values ------------------------------------------------------ + + loop_when_navigating = false, -- Loop when navigating through list + lines_to_show = 17, -- NOT including search line + pause_on_open = true, + resume_on_exit = "only-if-was-paused", -- another possible value is true + + -- styles (earlyer it was a table, but required many more steps to pass def-s + -- here from .conf file) + font_size = 21, + --font size scales by window + scale_by_window = false, + -- cursor 'width', useful to change if you have hidpi monitor + cursor_x_border = 0.3, + line_bottom_margin = 1, -- basically space between lines + text_color = { + default = 'ffffff', + accent = 'd8a07b', + current = 'aaaaaa', + comment = '636363', + }, + menu_x_padding = 5, -- this padding for now applies only to 'left', not x + menu_y_padding = 2, -- but this one applies to both - top & bottom + + + -- values that should be passed from main script ---------------------------- + + search_heading = 'Default search heading', + -- 'full' is required from main script, 'current_i' is optional + -- others are 'private' + list = { + full = {}, filtered = {}, current_i = nil, pointer_i = 1, show_from_to = {} + }, + -- field to compare with when searching for 'current value' by 'current_i' + index_field = 'index', + -- fields to use when searching for string match / any other custom searching + -- if value has 0 length, then search list item itself + filter_by_fields = {}, + + + -- 'private' values that are not supposed to be changed from the outside ---- + + is_active = false, + -- https://mpv.io/manual/master/#lua-scripting-mp-create-osd-overlay(format) + ass = mp.create_osd_overlay("ass-events"), + was_paused = false, -- flag that indicates that vid was paused by this script + + line = '', + -- if there was no cursor it wouldn't have been needed, but for now we need + -- variable below only to compare it with 'line' and see if we need to filter + prev_line = '', + cursor = 1, + history = {}, + history_pos = 1, + key_bindings = {}, + insert_mode = false, + + -- used only in 'update' func to get error text msgs + error_codes = { + no_match = 'Match required', + no_submit_provided = 'No submit function provided' + } +} + +-- PRIVATE METHODS ------------------------------------------------------------ + +local ime_active = mp.get_property_native("input-ime") + +-- declare constructor function +function em:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + + -- some options might be customised by user in .conf file and read as strings + -- in that case parse those + if type(o.filter_by_fields) == 'string' then + o.filter_by_fields = utils.parse_json(o.filter_by_fields) + end + + if type(o.text_color) == 'string' then + o.text_color = utils.parse_json(o.text_color) + end + + return o +end + +-- this func is just a getter of a current list depending on search line +function em:current() + return self.line == '' and self.list.full or self.list.filtered +end + +-- REVIEW: how to get rid of this wrapper and handle filter func sideeffects +-- in a more elegant way? +function em:filter_wrapper() + -- handles sideeffect that are needed to be run on filtering list + -- cuz the filter func may be redefined in main script and therefore needs + -- to be straight forward - only doing filtering and returning the table + + -- passing current query just in case, so ppl can use it in their custom funcs + self.list.filtered = self:filter(self.line) + + self.prev_line = self.line + self.list.pointer_i = 1 + self:set_from_to(true) +end + +function em:set_from_to(reset_flag) + -- additional variables just for shorter var name + local i = self.list.pointer_i + local to_show = self.lines_to_show + local total = #self:current() + + if reset_flag or to_show >= total then + self.list.show_from_to = { 1, math.min(to_show, total) } + return + end + + -- If menu is opened with something already selected we want this 'selected' + -- to be displayed close to the middle of the menu. That's why 'show_from_to' + -- is not initially set, so we can know - if show_from_to length is 0 - it is + -- first call of this func in cur. init + if #self.list.show_from_to == 0 then + -- set show_from_to so chosen item will be displayed close to middle + local half_list = math.ceil(to_show / 2) + if i < half_list then + self.list.show_from_to = { 1, to_show } + elseif total - i < half_list then + self.list.show_from_to = { total - to_show + 1, total } + else + self.list.show_from_to = { i - half_list + 1, i - half_list + to_show } + end + else + table.unpack = table.unpack or unpack -- 5.1 compatibility + local first, last = table.unpack(self.list.show_from_to) + + -- handle cursor moving towards start / end bondary + if first ~= 1 and i - first < 2 then + self.list.show_from_to = { first - 1, last - 1 } + end + if last ~= total and last - i < 2 then + self.list.show_from_to = { first + 1, last + 1 } + end + + -- handle index jumps from beginning to end and backwards + if i > last then + self.list.show_from_to = { i - to_show + 1, i } + end + if i < first then self.list.show_from_to = { 1, to_show } end + end +end + +function em:change_selected_index(num) + self.list.pointer_i = self.list.pointer_i + num + if self.loop_when_navigating then + if self.list.pointer_i < 1 then + self.list.pointer_i = #self:current() + elseif self.list.pointer_i > #self:current() then + self.list.pointer_i = 1 + end + else + if self.list.pointer_i < 1 then + self.list.pointer_i = 1 + elseif self.list.pointer_i > #self:current() then + self.list.pointer_i = #self:current() + end + end + self:set_from_to() + self:update() +end + +-- Render the REPL and console as an ASS OSD +function em:update(err_code) + -- ASS tags documentation here - https://aegi.vmoe.info/docs/3.0/ASS_Tags/ + + -- do not bother if function was called to close the menu.. + if not self.is_active then + em.ass:remove() + return + end + + local line_height = self.font_size + self.line_bottom_margin + local _, h, aspect = mp.get_osd_size() + local wh = self.scale_by_window and 720 or h + local ww = wh * aspect + + -- '+ 1' below is a search string + local menu_y_pos = + wh - (line_height * (self.lines_to_show + 1) + self.menu_y_padding * 2) + + -- didn't find better place to handle filtered list update + if self.line ~= self.prev_line then self:filter_wrapper() end + + local function get_background() + local a = self:ass_new_wrapper() + a:append('{\\1c&H1c1c1c\\1a&H19}') -- background color & opacity + a:pos(0, 0) + a:draw_start() + a:rect_cw(0, menu_y_pos, ww, wh) + a:draw_stop() + return a.text + end + + local function get_search_header() + local a = self:ass_new_wrapper() + + a:pos(self.menu_x_padding, menu_y_pos + self.menu_y_padding) + + local search_prefix = table.concat({ + self:get_font_color('accent'), + (#self:current() ~= 0 and self.list.pointer_i or '!'), + '/', #self:current(), '\\h\\h', self.search_heading, ':\\h' + }); + + a:append(search_prefix) + -- reset font color after search prefix + a:append(self:get_font_color 'default') + + -- Create the cursor glyph as an ASS drawing. ASS will draw the cursor + -- inline with the surrounding text, but it sets the advance to the width + -- of the drawing. So the cursor doesn't affect layout too much, make it as + -- thin as possible and make it appear to be 1px wide by giving it 0.5px + -- horizontal borders. + local cheight = self.font_size * 8 + -- TODO: maybe do it using draw_rect from ass? + local cglyph = '{\\r' .. -- styles reset + '\\1c&Hffffff&\\3c&Hffffff' .. -- font color and border color + '\\xbord' .. self.cursor_x_border .. '\\p4\\pbo24}' .. -- xborder, scale x8 and baseline offset + 'm 0 0 l 0 ' .. cheight .. -- drawing just a line + '{\\p0\\r}' -- finish drawing and reset styles + local before_cur = self:ass_escape(self.line:sub(1, self.cursor - 1)) + local after_cur = self:ass_escape(self.line:sub(self.cursor)) + + a:append(table.concat({ + before_cur, cglyph, self:reset_styles(), + self:get_font_color('default'), after_cur, + (err_code and '\\h' .. self.error_codes[err_code] or "") + })) + + return a.text + + -- NOTE: perhaps this commented code will some day help me in coding cursor + -- like in M-x emacs menu: + -- Redraw the cursor with the REPL text invisible. This will make the + -- cursor appear in front of the text. + -- ass:new_event() + -- ass:an(1) + -- ass:append(style .. '{\\alpha&HFF&}> ' .. before_cur) + -- ass:append(cglyph) + -- ass:append(style .. '{\\alpha&HFF&}' .. after_cur) + end + + local function get_list() + local a = assdraw.ass_new() + + local function apply_highlighting(y) + a:new_event() + a:append(self:reset_styles()) + a:append('{\\1c&Hffffff\\1a&HE6}') -- background color & opacity + a:pos(0, 0) + a:draw_start() + a:rect_cw(0, y, ww, y + self.font_size) + a:draw_stop() + end + + -- REVIEW: maybe make another function 'get_line_str' and move there + -- everything from this for loop? + -- REVIEW: how to use something like table.unpack below? + for i = self.list.show_from_to[1], self.list.show_from_to[2] do + local value = assert(self:current()[i], 'no value with index ' .. i) + local y_offset = menu_y_pos + self.menu_y_padding + + (line_height * (i - self.list.show_from_to[1] + 1)) + + if i == self.list.pointer_i then apply_highlighting(y_offset) end + + a:new_event() + a:append(self:reset_styles()) + a:pos(self.menu_x_padding, y_offset) + a:append(self:get_line(i, value)) + end + + return a.text + end + + em.ass.res_x = ww + em.ass.res_y = wh + em.ass.data = table.concat({ + get_background(), + get_search_header(), + get_list() + }, "\n") + + em.ass:update() +end + +-- params: +-- - data : {list: {}, [current_i] : num} +function em:init(data) + self.list.full = data.list or {} + self.list.current_i = data.current_i or nil + self.list.pointer_i = data.current_i or 1 + self:set_active(true) +end + +function em:exit() + self:undefine_key_bindings() + collectgarbage() +end + +-- TODO: write some idle func like this +-- function idle() +-- if pending_selection then +-- gallery:set_selection(pending_selection) +-- pending_selection = nil +-- end +-- if ass_changed or geometry_changed then +-- local ww, wh = mp.get_osd_size() +-- if geometry_changed then +-- geometry_changed = false +-- compute_geometry(ww, wh) +-- end +-- if ass_changed then +-- ass_changed = false +-- mp.set_osd_ass(ww, wh, ass) +-- end +-- end +-- end +-- ... +-- and handle it as follows +-- init(): +-- mp.register_idle(idle) +-- idle() +-- exit(): +-- mp.unregister_idle(idle) +-- idle() +-- And in these observers he is setting a flag, that's being checked in func above +-- mp.observe_property("osd-width", "native", mark_geometry_stale) +-- mp.observe_property("osd-height", "native", mark_geometry_stale) + +-- PRIVATE METHODS END -------------------------------------------------------- + +-- PUBLIC METHODS ------------------------------------------------------------- + +function em:filter() + -- default filter func, might be redefined in main script + local result = {} + + local function get_full_search_str(v) + local str = '' + for _, key in ipairs(self.filter_by_fields) do str = str .. (v[key] or '') end + return str + end + + for _, v in ipairs(self.list.full) do + -- if filter_by_fields has 0 length, then search list item itself + if #self.filter_by_fields == 0 then + if self:search_method(v) then table.insert(result, v) end + else + -- NOTE: we might use search_method on fiels separately like this: + -- for _,key in ipairs(self.filter_by_fields) do + -- if self:search_method(v[key]) then table.insert(result, v) end + -- end + -- But since im planning to implement fuzzy search in future i need full + -- search string here + if self:search_method(get_full_search_str(v)) then + table.insert(result, v) + end + end + end + return result +end + +-- TODO: implement fuzzy search and maybe match highlights +function em:search_method(str) + -- also might be redefined by main script + + -- convert to string just to make sure.. + return tostring(str):lower():find(self.line:lower(), 1, true) +end + +-- this module requires submit function to be defined in main script +function em:submit() self:update('no_submit_provided') end + +function em:update_list(list) + -- for now this func doesn't handle cases when we have 'current_i' to update + -- it + self.list.full = list + if self.line ~= self.prev_line then self:filter_wrapper() end +end + +-- PUBLIC METHODS END --------------------------------------------------------- + +-- HELPER METHODS ------------------------------------------------------------- + +function em:get_line(_, v) -- [i]ndex, [v]alue + -- this func might be redefined in main script to get a custom-formatted line + -- default implementation of this func supposes that value.content field is a + -- String + local a = assdraw.ass_new() + local style = (self.list.current_i == v[self.index_field]) + and 'current' or 'default' + + a:append(self:reset_styles()) + a:append(self:get_font_color(style)) + -- content as default field, which is holding string + -- no point in moving it to main object since content itself is being + -- composed in THIS function, that might (and most likely, should) be + -- redefined in main script + a:append(v.content or 'Something is off in `get_line` func') + return a.text +end + +-- REVIEW: for now i don't see normal way of mergin this func with below one +-- but it's being used only once +function em:reset_styles() + local a = assdraw.ass_new() + -- alignment top left, no word wrapping, border 0, shadow 0 + a:append('{\\an7\\q2\\bord0\\shad0}') + a:append('{\\fs' .. self.font_size .. '}') + return a.text +end + +-- function to get rid of some copypaste +function em:ass_new_wrapper() + local a = assdraw.ass_new() + a:new_event() + a:append(self:reset_styles()) + return a +end + +function em:get_font_color(style) + return '{\\1c&H' .. self.text_color[style] .. '}' +end + +-- HELPER METHODS END --------------------------------------------------------- + + +--[[ + The below code is a modified implementation of text input from mpv's console.lua: + https://github.com/mpv-player/mpv/blob/87c9eefb2928252497f6141e847b74ad1158bc61/player/lua/console.lua + + 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 -- +------------------------------------------------------------------------------- + +-- Copyright (C) 2019 the mpv developers +-- +-- Permission to use, copy, modify, and/or distribute this software for any +-- purpose with or without fee is hereby granted, provided that the above +-- copyright notice and this permission notice appear in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +-- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +function em:detect_platform() + local o = {} + -- Kind of a dumb way of detecting the platform but whatever + if mp.get_property_native('options/vo-mmcss-profile', o) ~= o then + return 'windows' + elseif mp.get_property_native('options/macos-force-dedicated-gpu', o) ~= o then + return 'macos' + elseif os.getenv('WAYLAND_DISPLAY') then + return 'wayland' + end + return 'x11' +end + +-- Escape a string for verbatim display on the OSD +function em:ass_escape(str) + -- There is no escape for '\' in ASS (I think?) but '\' is used verbatim if + -- it isn't followed by a recognised character, so add a zero-width + -- non-breaking space + str = str:gsub('\\', '\\\239\187\191') + str = str:gsub('{', '\\{') + str = str:gsub('}', '\\}') + -- Precede newlines with a ZWNBSP to prevent ASS's weird collapsing of + -- consecutive newlines + str = str:gsub('\n', '\239\187\191\\N') + -- Turn leading spaces into hard spaces to prevent ASS from stripping them + str = str:gsub('\\N ', '\\N\\h') + str = str:gsub('^ ', '\\h') + return str +end + +-- Set the REPL visibility ("enable", Esc) +function em:set_active(active) + if active == self.is_active then return end + if active then + if ime_active == false then + mp.set_property_bool("input-ime", true) + end + self.is_active = true + self.insert_mode = false + mp.enable_messages('terminal-default') + self:define_key_bindings() + + -- set flag 'was_paused' only if vid wasn't paused before EM init + if self.pause_on_open and not mp.get_property_bool("pause", false) then + mp.set_property_bool("pause", true) + self.was_paused = true + end + + self:set_from_to() + self:update() + else + -- no need to call 'update' in this block cuz 'clear' method is calling it + if ime_active == false then + mp.set_property_bool("input-ime", false) + end + self.is_active = false + self:undefine_key_bindings() + + if self.resume_on_exit == true or + (self.resume_on_exit == "only-if-was-paused" and self.was_paused) then + mp.set_property_bool("pause", false) + end + + self:clear() + collectgarbage() + end +end + +-- Naive helper function to find the next UTF-8 character in 'str' after 'pos' +-- by skipping continuation bytes. Assumes 'str' contains valid UTF-8. +function em:next_utf8(str, pos) + if pos > str:len() then return pos end + repeat + pos = pos + 1 + until pos > str:len() or str:byte(pos) < 0x80 or str:byte(pos) > 0xbf + return pos +end + +-- As above, but finds the previous UTF-8 charcter in 'str' before 'pos' +function em:prev_utf8(str, pos) + if pos <= 1 then return pos end + repeat + pos = pos - 1 + until pos <= 1 or str:byte(pos) < 0x80 or str:byte(pos) > 0xbf + return pos +end + +-- Insert a character at the current cursor position (any_unicode) +function em:handle_char_input(c) + if self.insert_mode then + self.line = self.line:sub(1, self.cursor - 1) .. c .. self.line:sub(self:next_utf8(self.line, self.cursor)) + else + self.line = self.line:sub(1, self.cursor - 1) .. c .. self.line:sub(self.cursor) + end + self.cursor = self.cursor + #c + self:update() +end + +-- Remove the character behind the cursor (Backspace) +function em:handle_backspace() + if self.cursor <= 1 then return end + local prev = self:prev_utf8(self.line, self.cursor) + self.line = self.line:sub(1, prev - 1) .. self.line:sub(self.cursor) + self.cursor = prev + self:update() +end + +-- Remove the character in front of the cursor (Del) +function em:handle_del() + if self.cursor > self.line:len() then return end + self.line = self.line:sub(1, self.cursor - 1) .. self.line:sub(self:next_utf8(self.line, self.cursor)) + self:update() +end + +-- Toggle insert mode (Ins) +function em:handle_ins() + self.insert_mode = not self.insert_mode +end + +-- Move the cursor to the next character (Right) +function em:next_char() + self.cursor = self:next_utf8(self.line, self.cursor) + self:update() +end + +-- Move the cursor to the previous character (Left) +function em:prev_char() + self.cursor = self:prev_utf8(self.line, self.cursor) + self:update() +end + +-- Clear the current line (Ctrl+C) +function em:clear() + self.line = '' + self.prev_line = '' + + self.list.current_i = nil + self.list.pointer_i = 1 + self.list.filtered = {} + self.list.show_from_to = {} + + self.was_paused = false + + self.cursor = 1 + self.insert_mode = false + self.history_pos = #self.history + 1 + + self:update() +end + +-- Run the current command and clear the line (Enter) +function em:handle_enter() + if #self:current() == 0 then + self:update('no_match') + return + end + + if self.history[#self.history] ~= self.line then + self.history[#self.history + 1] = self.line + end + + self:submit(self:current()[self.list.pointer_i]) + self:set_active(false) +end + +-- Go to the specified position in the command history +function em:go_history(new_pos) + local old_pos = self.history_pos + self.history_pos = new_pos + + -- Restrict the position to a legal value + if self.history_pos > #self.history + 1 then + self.history_pos = #self.history + 1 + elseif self.history_pos < 1 then + self.history_pos = 1 + end + + -- Do nothing if the history position didn't actually change + if self.history_pos == old_pos then + return + end + + -- If the user was editing a non-history line, save it as the last history + -- entry. This makes it much less frustrating to accidentally hit Up/Down + -- while editing a line. + if old_pos == #self.history + 1 and self.line ~= '' and self.history[#self.history] ~= self.line then + self.history[#self.history + 1] = self.line + end + + -- Now show the history line (or a blank line for #history + 1) + if self.history_pos <= #self.history then + self.line = self.history[self.history_pos] + else + self.line = '' + end + self.cursor = self.line:len() + 1 + self.insert_mode = false + self:update() +end + +-- Go to the specified relative position in the command history (Up, Down) +function em:move_history(amount) + self:go_history(self.history_pos + amount) +end + +-- Go to the first command in the command history (PgUp) +function em:handle_pgup() + -- Determine the number of items to move up (half a page) + local half_page = math.ceil(self.lines_to_show / 2) + + -- Move the history position up by half a page + self:change_selected_index(-half_page) +end + +-- Stop browsing history and start editing a blank line (PgDown) +function em:handle_pgdown() + -- Determine the number of items to move down (half a page) + local half_page = math.ceil(self.lines_to_show / 2) + + -- Move the history position down by half a page + self:change_selected_index(half_page) +end + +-- Move to the start of the current word, or if already at the start, the start +-- of the previous word. (Ctrl+Left) +function em:prev_word() + -- This is basically the same as next_word() but backwards, so reverse the + -- string in order to do a "backwards" find. This wouldn't be as annoying + -- to do if Lua didn't insist on 1-based indexing. + self.cursor = self.line:len() - select(2, self.line:reverse():find('%s*[^%s]*', self.line:len() - self.cursor + 2)) + 1 + self:update() +end + +-- Move to the end of the current word, or if already at the end, the end of +-- the next word. (Ctrl+Right) +function em:next_word() + self.cursor = select(2, self.line:find('%s*[^%s]*', self.cursor)) + 1 + self:update() +end + +-- Move the cursor to the beginning of the line (HOME) +function em:go_home() + self.cursor = 1 + self:update() +end + +-- Move the cursor to the end of the line (END) +function em:go_end() + self.cursor = self.line:len() + 1 + self:update() +end + +-- Delete from the cursor to the beginning of the word (Ctrl+Backspace) +function em:del_word() + local before_cur = self.line:sub(1, self.cursor - 1) + local after_cur = self.line:sub(self.cursor) + + before_cur = before_cur:gsub('[^%s]+%s*$', '', 1) + self.line = before_cur .. after_cur + self.cursor = before_cur:len() + 1 + self:update() +end + +-- Delete from the cursor to the end of the word (Ctrl+Del) +function em:del_next_word() + if self.cursor > self.line:len() then return end + + local before_cur = self.line:sub(1, self.cursor - 1) + local after_cur = self.line:sub(self.cursor) + + after_cur = after_cur:gsub('^%s*[^%s]+', '', 1) + self.line = before_cur .. after_cur + self:update() +end + +-- Delete from the cursor to the end of the line (Ctrl+K) +function em:del_to_eol() + self.line = self.line:sub(1, self.cursor - 1) + self:update() +end + +-- Delete from the cursor back to the start of the line (Ctrl+U) +function em:del_to_start() + self.line = self.line:sub(self.cursor) + self.cursor = 1 + self:update() +end + +-- Returns a string of UTF-8 text from the clipboard (or the primary selection) +function em:get_clipboard(clip) + -- Pick a better default font for Windows and macOS + local platform = self:detect_platform() + + if platform == 'x11' then + local res = utils.subprocess({ + args = { 'xclip', '-selection', clip and 'clipboard' or 'primary', '-out' }, + playback_only = false, + }) + if not res.error then + return res.stdout + end + elseif platform == 'wayland' then + local res = utils.subprocess({ + args = { 'wl-paste', clip and '-n' or '-np' }, + playback_only = false, + }) + if not res.error then + return res.stdout + end + elseif platform == 'windows' then + local res = utils.subprocess({ + args = { 'powershell', '-NoProfile', '-Command', [[& { + Trap { + Write-Error -ErrorRecord $_ + Exit 1 + } + + $clip = "" + if (Get-Command "Get-Clipboard" -errorAction SilentlyContinue) { + $clip = Get-Clipboard -Raw -Format Text -TextFormatType UnicodeText + } else { + Add-Type -AssemblyName PresentationCore + $clip = [Windows.Clipboard]::GetText() + } + + $clip = $clip -Replace "`r","" + $u8clip = [System.Text.Encoding]::UTF8.GetBytes($clip) + [Console]::OpenStandardOutput().Write($u8clip, 0, $u8clip.Length) + }]] }, + playback_only = false, + }) + if not res.error then + return res.stdout + end + elseif platform == 'macos' then + local res = utils.subprocess({ + args = { 'pbpaste' }, + playback_only = false, + }) + if not res.error then + return res.stdout + end + end + return '' +end + +-- Paste text from the window-system's clipboard. 'clip' determines whether the +-- clipboard or the primary selection buffer is used (on X11 and Wayland only.) +function em:paste(clip) + local text = self:get_clipboard(clip) + local before_cur = self.line:sub(1, self.cursor - 1) + local after_cur = self.line:sub(self.cursor) + self.line = before_cur .. text .. after_cur + self.cursor = self.cursor + text:len() + self:update() +end + +-- List of input bindings. This is a weird mashup between common GUI text-input +-- 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 }, + } + + for i = 0, 9 do + bindings[#bindings + 1] = + { 'kp' .. i, function() self:handle_char_input('' .. i) end } + end + + return bindings +end + +function em:text_input(info) + if info.key_text and (info.event == "press" or info.event == "down" + or info.event == "repeat") + then + self:handle_char_input(info.key_text) + end +end + +function em:define_key_bindings() + if #self.key_bindings > 0 then + return + end + for _, bind in ipairs(self:get_bindings()) do + -- Generate arbitrary name for removing the bindings later. + local name = "search_" .. (#self.key_bindings + 1) + self.key_bindings[#self.key_bindings + 1] = name + mp.add_forced_key_binding(bind[1], name, bind[2], { repeatable = true }) + end + mp.add_forced_key_binding("any_unicode", "search_input", function(...) + self:text_input(...) + end, { repeatable = true, complex = true }) + self.key_bindings[#self.key_bindings + 1] = "search_input" +end + +function em:undefine_key_bindings() + for _, name in ipairs(self.key_bindings) do + mp.remove_key_binding(name) + end + self.key_bindings = {} +end + +------------------------------------------------------------------------------- +-- END ORIGINAL MPV CODE -- +------------------------------------------------------------------------------- + +return em diff --git a/script-opts/README.md b/script-opts/README.md new file mode 100644 index 0000000..eb0be2c --- /dev/null +++ b/script-opts/README.md @@ -0,0 +1,19 @@ +### 该文件夹下存放mpv脚本的对应设置文件 + +通常脚本设置文件名与所属脚本文件同名,注意脚本文件名中的`-`默认需转译成`_`。实际以脚本开发者设定为准。 + +脚本设置文件切勿美化格式(例如加入无意义的空格);切勿在参数后注释(应单独另起一行写注释)。 + +脚本及其设置文件可能不支持windows的CRLF换行(尝试更改为LF)。 + +以上所述情况在自行修改的过程中都可能导致脚本设置文件(部分)失效。 + +以下为mpv内置脚本所使用的设置文件: + +``` +console.conf +osc.conf +stats.conf +ytdl_hook.conf +``` + diff --git a/script-opts/auto_save_state.conf b/script-opts/auto_save_state.conf new file mode 100644 index 0000000..ad69b83 --- /dev/null +++ b/script-opts/auto_save_state.conf @@ -0,0 +1,4 @@ +# 设置自动保存文件播放进度及状态的时间间隔,单位为秒。默认值:60 秒 +save_interval=60 +# 设置文件播放进度的百分比,满足时自动删除文件播放进度及状态。默认值:99 +percent_pos=99 \ No newline at end of file diff --git a/script-opts/autoload.conf b/script-opts/autoload.conf new file mode 100644 index 0000000..427d34d --- /dev/null +++ b/script-opts/autoload.conf @@ -0,0 +1,34 @@ +###不支持参数后注释,须另起一行 + +##禁用所有自动加载相关功能,默认:no +#disabled=yes + +##是否自动加载当前目录(不含子目录)所有图片到播放列表,默认:yes +#images=no + +##是否自动加载当前目录(不含子目录)所有视频到播放列表,默认:yes +#videos=no + +##是否自动加载当前目录(不含子目录)所有音频到播放列表,默认:yes +#audio=no + +##指定额外需要用于加载的图片、视频和音频扩展白名单 +additional_image_exts=jfif +additional_video_exts=asf,f4v,rm,ts,vob +additional_audio_exts=dsf,spx + +## 打开文件时,选择递归、懒惰或忽略全部子目录 +directory_mode=ignore + +##是否掠过隐藏文件,默认:yes +#ignore_hidden=no + +##指定需要略过的文件名模式,多个模式之间用逗号分隔。默认值为空 +##支持 lua 模式写法,可使用 % 转义 , +#ignore_patterns=^~,^bak-,%.bak$ + +#是否只自动载入相同类型的文件(视频、音频、图片),默认:no +same_type=yes + +#是否只自动载入相似系列的文件,默认:no +#same_series=yes \ No newline at end of file diff --git a/script-opts/autosubsync.conf b/script-opts/autosubsync.conf new file mode 100644 index 0000000..d1f3f29 --- /dev/null +++ b/script-opts/autosubsync.conf @@ -0,0 +1,28 @@ +# 手动指定可执行文件的绝对路径,如果以下程序不存在于环境变量中 + +# 1. ffmpeg +#ffmpeg_path=C:/Program Files/ffmpeg/bin/ffmpeg.exe +ffmpeg_path=ffmpeg + +# 2. ffsubsync +#ffsubsync_path=C:/Program Files/ffsubsync/ffsubsync.exe +#ffsubsync_path=/home/user/.local/bin/ffsubsync + +# 3. alass +#alass_path=C:/Program Files/ffmpeg/bin/alass.exe +#alass_path=/usr/bin/alass +##⇘⇘以下路径设置为在 mpv 程序所在的根目录下查找指定程序 +alass_path=alass + +# 首选的字幕同步工具。允许选项:'ffsubsync','alass','ask'. +# 如果设置为“ask”,脚本每次都会要求选择工具: + +# 1. 用于与音频同步的首选工具。('ffsubsync','alass','ask') +audio_subsync_tool=alass + +# 2. 用于与字幕同步的首选工具。('ffsubsync','alass','ask') +altsub_subsync_tool=alass + +# 禁用原字幕 (yes,no) +# 尝试字幕同步操作完成后,告诉 mpv 忽略原来的字幕轨道 +unload_old_sub=no \ No newline at end of file diff --git a/script-opts/blacklist_extensions.conf b/script-opts/blacklist_extensions.conf new file mode 100644 index 0000000..69afb59 --- /dev/null +++ b/script-opts/blacklist_extensions.conf @@ -0,0 +1,12 @@ +# 黑名单或白名单只需设置其中一种 + +# 白名单,只允许视频格式 +#whitelist=3gp,amr,amv,asf,avi,avi,bdmv,f4v,flv,ifo,iso,m2ts,m4v,mkv,mov,mp4,mpeg,mpg,ogv,rm,rmvb,ts,vob,webm,wmv + +# 或者,视频附近常见的黑名单格式 +blacklist=mpls,mks,mka,weba,aqt,ass,gsub,idx,jss,lrc,mks,pgs,pjs,psb,rt,slt,smi,sub,sup,sbv,srt,ssa,ssf,ttxt,txt,usf,vt,vtt + +remove_files_without_extension=yes + +# 脚本仅在播放开始时生效,禁用则在播放列表更改时也会生效 +oneshot=no diff --git a/script-opts/chapter_make_read.conf b/script-opts/chapter_make_read.conf new file mode 100644 index 0000000..4990653 --- /dev/null +++ b/script-opts/chapter_make_read.conf @@ -0,0 +1,29 @@ +#是否启用自动读取并加载外部章节文件。默认:yes +autoload=yes +#是否启用自动导出章节文件 (当章节信息更改后)。默认:no +autosave=no +#是否使用外部章节信息覆盖视频内部章节信息。默认:no +force_overwrite=no +#指定外部章节文件的标识及扩展名 +chapter_file_ext=.chp +#选择外部章节文件是否需要匹配源文件的扩展名。默认:yes +basename_with_ext=yes +#从视频文件同目录下的指定子目录读取外部章节文件 +#注意:脚本优先从指定的子目录读取外部章节文件 +#当子目录的文件不存在时会继续尝试在视频文件同目录中读取外部章节文件 +external_chapter_subpath=chapters +#是否将章节文件统一存储在配置的全局目录中,网络文件将始终使用全局目录。默认:no +global_chapters=no +#指定章节文件的全局目录的路径。可以是 mpv 支持的相对路径或绝对路径 +global_chapters_dir=~~/files/chapters +#是否在全局目录中使用哈希值保存章节文件名。默认:no +##如果设置为'no',章节文件将以相应的媒体文件命名,可能会导致冲突 +##使用哈希可防止同名但位于不同目录中的媒体文件获取相同的章节文件 +##但如果您将文件移动到不同的目录,哈希值将更改导致无法加载章节文件 +hash=no +#设置创建新章节时是否默认打开重命名输入功能。默认:yes +ask_for_title=yes +#设置询问新章节标题时的占位符名称 +placeholder_title=Chapter +#设置询问章节标题时是否暂停播放。默认:yes +pause_on_input=yes \ No newline at end of file diff --git a/script-opts/chapterskip.conf b/script-opts/chapterskip.conf new file mode 100644 index 0000000..29b9a23 --- /dev/null +++ b/script-opts/chapterskip.conf @@ -0,0 +1,8 @@ +# 是否启用自动跳过。默认:no +enabled=no +# 每个章节名仅跳过一次。默认:yes +skip_once=yes +# 章节名匹配规则(Lua 正则) +categories=opening>^OP/ OP$/^[Oo]pening/[Oo]pening$/^Intro%s*Start/オープニング$/^片头$/片头开始$; ending>^ED/ ED$/^[Ee]nding/[Ee]nding$/エンディング$; credits>^[Cc]redits/[Cc]redits$; prologue>^[Pp]rologue/^[Ii]ntro$; preview>[Pp]review$/^[Pp]review/予告$/預告$; PartAB>Part [AB]/Ending 1; PartC>Part C +# 需要跳过的章节类别 +skip=opening;ending;credits;prologue;preview diff --git a/script-opts/command_palette.conf b/script-opts/command_palette.conf new file mode 100644 index 0000000..8a50dff --- /dev/null +++ b/script-opts/command_palette.conf @@ -0,0 +1,8 @@ +#指定命令面板的字体大小,默认值:16 +font_size=26 +#指定字体大小是否随窗口大小缩放,默认值:no +scale_by_window=yes +#指定命令面板的菜单项的显示数量,默认值:12 +lines_to_show=12 +#指定是否在打开命令面板时暂停播放,默认值:no +pause_on_open=yes \ No newline at end of file diff --git a/script-opts/commands.conf b/script-opts/commands.conf new file mode 100644 index 0000000..17d5de7 --- /dev/null +++ b/script-opts/commands.conf @@ -0,0 +1,6 @@ +###此配置不支持参数后注释,须另起一行 + +# 是否将命令历史记录保存到文件并加载它。默认:no +persist_history=yes +# 命令历史记录文件的路径。默认:~~state/command_history.txt +history_path=~~/files/command_history.txt \ No newline at end of file diff --git a/script-opts/console.conf b/script-opts/console.conf new file mode 100644 index 0000000..bcc22ba --- /dev/null +++ b/script-opts/console.conf @@ -0,0 +1,37 @@ +###此配置不支持参数后注释,须另起一行 + +# 指定控制台显示补全时使用的等宽字体。其他情况使用 --osd-font +#monospace_font=Noto Sans Mono CJK SC +# 字体大小默认 24。最终大小将与缩放率相乘 +#font_size=24 +# 设置用于 REPL 和控制台的字体边框大小。默认值:1.32 +border_size=1.3 +# 菜单背景的透明度。范围从 0(不透明)到 255(完全透明)。默认值:80 +background_alpha=50 +# 菜单的内边距。默认值:10 +#padding=10 +# 菜单边框的大小。默认值:0 +#menu_outline_size=0 +# 菜单边框的颜色。默认值:#FFFFFF +#menu_outline_color=#FFFFFF +# 菜单的圆角半径。默认值:8 +#orner_radius=8 +# 菜单所选项的颜色。默认值:#222222 +#selected_color=#222222 +# 菜单所选项的背景颜色。默认值:#FFFFFF +#selected_back_color=#FFFFFF +# 与搜索字符串匹配的字符的颜色。默认值:#0088FF +#match_color=#0088FF +# 是否使用窗口高度缩放控制台。可以是 yes、no 或 auto,取决于--osd-scale-by-window 选项。默认值:auto +#scale_with_window=auto +# 查询时是否使用精确搜索而非模糊搜索,默认值:no +# 在查询前加上 ' 字符可强制启用精确匹配 +#exact_match=no +# 设置 Tab 自动补全是否区分大小写。仅适用于 ASCII 字符 +## 默认值:在 Windows 上为 no,在其他平台上为 yes +#case_sensitive=no +# 删除历史记录中的重复条目,以便仅保留最新的条目。默认:yes +history_dedup=yes +# 设置字体高度与字体宽度的比率,调整完成建议的表格宽度。默认值:auto +## 1.8-2.5 范围内的值对于常见的等宽字体有用 +#font_hw_ratio=auto diff --git a/script-opts/dyn_menu.conf b/script-opts/dyn_menu.conf new file mode 100644 index 0000000..e1270a4 --- /dev/null +++ b/script-opts/dyn_menu.conf @@ -0,0 +1,14 @@ +##! 注意这个菜单脚本只支持 windows 系统 +## 指定是否使用 mpv 内部的上下文菜单实现。默认值为 yes +## 需使用包含上游提交 https://github.com/mpv-player/mpv/commit/3c1e983 的 mpv 版本 +use_mpv_impl=no +### 指定是否启用 uosc 的菜单语法支持。与默认支持的 mpv.net 菜单语法不兼容,但是可以使用 uosc 的菜单语法。默认值为 no +uosc_syntax=yes +## 指定是否启用菜单标题转义。默认值为 yes +escape_title=yes +## 指定菜单标题的最大长度。默认值为 80。如果标题长度超过这个值,将会被截断 +## 设为 0 表示不限制标题长度 +max_title_length=80 +## 指定播放列表菜单项的最大数量。默认值为 20 +## 设为 0 表示禁用播放列表菜单 +max_playlist_items=20 diff --git a/script-opts/evafast.conf b/script-opts/evafast.conf new file mode 100644 index 0000000..ae9f96f --- /dev/null +++ b/script-opts/evafast.conf @@ -0,0 +1,35 @@ +# 脚本键位按下时要跳多远 +seek_distance=5 + +# 播放速度调整量,每 'speed_interval' 应用一次,直到达到上限 +speed_increase=0.1 +speed_decrease=0.1 + +# 以什么间隔应用速度调整量 +speed_interval=0.05 + +# 播放速度上限 +speed_cap=3 + +# 显示字幕时的播放速度上限,'no' 表示与 'speed_cap' 相同 +subs_speed_cap=1.5 + +# 调整前将当前速度乘以速度调整量(指数加速)。默认:no +# 使用比默认值低得多的值,例如 speed_increase=0.05, speed_decrease=0.025 +multiply_modifier=no + +# 在 OSD 上显示当前速度(如果使用 uosc,则闪烁显示速度)。默认:yes +show_speed=yes + +# 速度切换时在 OSD 上显示当前速度(如果使用 uosc,则闪烁显示速度)。默认:yes +show_speed_toggled=yes + +# 在 osd 上显示搜索操作(如果使用 uosc,则闪烁显示时间线)。默认:yes +show_seek=yes + +# 设置 'subs_speed_cap' 项时提前查看以实现更平滑的过渡。默认:no +subs_lookahead=no + +# 设置 osd 消息显示的符号,示例即默认值 +#osd_symbol={\fnmpv-osd-symbols} {\r} +#osd_rewind={\fnmpv-osd-symbols} {\r} \ No newline at end of file diff --git a/script-opts/file-browser-keybinds.json b/script-opts/file-browser-keybinds.json new file mode 100644 index 0000000..8a6f246 --- /dev/null +++ b/script-opts/file-browser-keybinds.json @@ -0,0 +1,193 @@ +[ + { + "key": "WHEEL_UP", + "command": ["script-binding", "file_browser/dynamic/scroll_up"] + }, + { + "key": "WHEEL_DOWN", + "command": ["script-binding", "file_browser/dynamic/scroll_down"] + }, + { + "key": "MBTN_LEFT", + "command": ["script-binding", "file_browser/dynamic/down_dir"] + }, + { + "key": "MBTN_RIGHT", + "command": ["script-binding", "file_browser/dynamic/up_dir"] + }, + { + "key": "MBTN_MID", + "command": ["script-binding", "file_browser/dynamic/play"] + }, + + { + "key": "KP1", + "command": ["print-text", "files: %n"], + "filter": "file", + "multiselect": true, + "multi-type": "concat", + "concat-string": "\n" + }, + { + "key": "KP1", + "command": ["print-text", "directories: %n"], + "filter": "dir", + "multiselect": true, + "multi-type": "concat", + "concat-string": "\n" + }, + { + "key": "KP1", + "command": ["print-text", "%f"], + "passthrough": true, + "name": "thing" + }, + { + "key": "KP2", + "command": ["print-text", "name: %n"], + "multiselect": true + }, + { + "key": "KP3", + "command": ["print-text", "open directory: %p"] + }, + { + "key": "KP4", + "command": ["print-text", "directory name: %d"] + }, + { + "key": "KP5", + "command": ["print-text", "escape the code: %%f"], + "multiselect": true + }, + { + "key": "KP6", + "command": ["print-text", "full filepath via concatenation: %p%n"], + "multiselect": true + }, + { + "key": "KP7", + "command": ["print-text", "quote/escape filepath: %F"], + "multiselect": true + }, + { + "key": "KP8", + "command": ["print-text", "%r"] + }, + + { + "key": "Alt+DEL", + "command": ["run", "powershell", "-command", "rm", "%F"], + "filter": "file", + "multiselect": true, + "multi-type": "concat" + }, + { + "key": "Ctrl+ENTER", + "command": ["run", "powershell", "-command", "mpv.exe", "%F"], + "multiselect": true, + "multi-type": "concat" + }, + { + "key": "Ctrl+c", + "command": [ + ["run", "powershell", "-command", "Set-Clipboard", "%F"], + ["print-text", "copied filepath to clipboard"] + ], + "multiselect": true, + "delay": 0.3 + }, + { + "key": "Ctrl+v", + "command": ["run", "powershell", "-command", "cp", "-LiteralPath", "(Get-Clipboard)", "%P"], + "multiselect": false + }, + { + "key": "Ctrl+x", + "command": ["run", "powershell", "-command", "mv", "-LiteralPath", "(Get-Clipboard)", "%P"], + "multiselect": false + }, + { + "key": "INS", + "command": ["run", "powershell", "-command", "Set-Content", "-LiteralPath", "( %P + '/.ordered-chapters.m3u' )", "-Value", "( %N )"], + "multiselect": true, + "multi-type": "concat", + "concat-string": "+'\n'+" + }, + { + "key": "Ctrl+INS", + "command": ["run", "powershell", "-command", "rm", "-LiteralPath", "( %P + '/.ordered-chapters.m3u' )", "-Force"], + "multiselect": false + }, + { + "key": "Ctrl+o", + "command": ["run", "powershell", "-command", "explorer.exe", "(( %P ).TrimEnd('/') -replace '/', '\\' )"], + "multiselect": false + }, + { + "key": "Ctrl+O", + "command": ["run", "powershell", "-command", "explorer.exe", "(( %F ).TrimEnd('/') -replace '/', '\\' )"], + "filter": "dir", + "multiselect": true + }, + { + "key": "Ctrl+O", + "command": ["run", "powershell", "-command", "explorer.exe", "'/select,'", "( %F -replace '/', '\\' )"], + "filter": "file", + "multiselect": true + }, + { + "key": "Ctrl+o", + "command": ["run", "powershell", "-command", "& 'C:/Program Files/Mozilla Firefox/firefox.exe' %P"], + "multiselect": false, + "parser": "ftp" + }, + { + "key": "Ctrl+O", + "command": ["run", "powershell", "-command", "& 'C:/Program Files/Mozilla Firefox/firefox.exe' %F"], + "filter": "dir", + "multiselect": true, + "parser": "ftp" + }, + { + "key": "DEL", + "command": [ + ["run", "powershell", "-command", "(New-Object -ComObject 'Shell.Application').NameSpace(0).ParseName((%F -replace '/', '\\' )).InvokeVerb('delete')"], + ["script-message", "delay-command", "4", "script-binding", "file_browser/dynamic/reload"], + ["show-text", "删除 %f"] + ], + "multiselect": true, + "multi-type": "repeat" + }, + + { + "key": "F", + "command": ["script-message", "favourites/add_favourite", "%f"] + }, + { + "key": "F", + "command": ["script-message", "favourites/remove_favourite", "%f"], + "parser": "favourites" + }, + { + "key": "Ctrl+UP", + "command": [ + ["script-message", "favourites/move_up", "%f"] + ], + "parser": "favourites" + }, + { + "key": "Ctrl+DOWN", + "command": [ + ["script-message", "favourites/move_down", "%f"] + ], + "parser": "favourites" + }, + { + "key": "Ctrl+r", + "command": [ + ["script-message", "winroot/import_root_drives"] + ], + "parser": "root" + } +] \ No newline at end of file diff --git a/script-opts/file_browser_favourites.txt b/script-opts/file_browser_favourites.txt new file mode 100644 index 0000000..e69de29 diff --git a/script-opts/hdr_mode.conf b/script-opts/hdr_mode.conf new file mode 100644 index 0000000..b13bbac --- /dev/null +++ b/script-opts/hdr_mode.conf @@ -0,0 +1,15 @@ +# 指定脚本的工作方式,有三种模式可选:noth、pass、switch。默认值:noth +## noth:什么也不做 +## pass:当显示器处于 HDR 模式时,为 HDR 内容传递 HDR 信号 +## switch:根据 mpv 播放的视频内容在显示器的 HDR 模式和 SDR 模式之间自动切换,在 Windows 10 及更高版本的系统上可用 +hdr_mode=noth +# 指定是否仅在全屏或窗口最大化时自动切换 HDR 模式。仅在 hdr_mode=switch 时生效,默认值:no +fullscreen_only=no +# 用于指定你的 HDR 显示器的目标峰值,默认值:203 +#! 提醒:此项必须指定显示器的真实峰值亮度,否则会导致 HDR 内容显示不正确。默认值 203 会视为 SDR 显示器处理 +target_peak=203 +# 用于指定你的 HDR 显示器的最大对比度数值,默认值:auto,即无限对比度(OLED) +#! 提醒:此项必须指定为显示器的最大对比度,否则无法正确实施黑位补偿 +## 例如 100000 表示显示器最大对比度为 100000:1 +## OLED 显示器无需更改此项,使用默认值即可 +target_contrast=auto \ No newline at end of file diff --git a/script-opts/inputevent.conf b/script-opts/inputevent.conf new file mode 100644 index 0000000..4e8300d --- /dev/null +++ b/script-opts/inputevent.conf @@ -0,0 +1,7 @@ +#是否使用外部配置文件设置增强式键位动作,默认:no +enable_external_config=yes +#指定外部配置文件的路径,可以是 mpv 支持的相对路径或绝对路径 +#注意:启用外部配置文件功能时请确保该文件存在 +external_config=~~/inputevent_key.conf +#指定键位事件的识别前缀,默认:event +prefix=event \ No newline at end of file diff --git a/script-opts/modernf.conf b/script-opts/modernf.conf new file mode 100644 index 0000000..55ab565 --- /dev/null +++ b/script-opts/modernf.conf @@ -0,0 +1,83 @@ +#choose a layout(reduced/original/mid) +#layout=original + +#show OSC when windowed? yes/no +#showwindowed= + +#show OSC when fullscreen? yes/no +#showfullscreen= + +#scaling of the controller when windowed +scalewindowed=1 + +#scaling of the controller when fullscreen +scalefullscreen=1 + +#scaling when rendered on a forced window +scaleforcedwindow=1.5 + +#scale the controller with the video? yes/no +#vidscale= + +#duration in ms until the OSC hides if no mouse movement. enforced non-negative for the user but internally negative is 'always-on'. +#hidetimeout=500 + +#duration of fade out in ms 0=no fade +#fadeduration=200 + +#minimum amount of pixels the mouse has to move between ticks to make the OSC show up +#minmousemove=3 + +#use native mpv values and disable OSC internal track list management (and some functions that depend on it) yes/no +#amaprogrammer= + +#default osc font +#font='mpv-osd-symbols' + +#show seekrange overlay yes/no +#seekrange= + +#color of seekbar and knot,there is no # before value +#seekbarfg_color="7FFFD4" + +#transparency of seekranges +seekrangealpha=128 + +#use keyframes when dragging the seekbar yes/no +#seekbarkeyframes= + +#string compatible with property-expansion to be shown as OSC title +#title='${media-title}' + +#show osc and no hide timeout on pause yes/no +showonpause=no + +#display timecodes with milliseconds yes/no +#timems=false + +#display total time instead of remaining time? yes/no +#timetotal=no + +#how mpv logo on idle +#idlescreen=yes + +#only used at init to set visibility_mode(...) auto/always/never +#visibility=always + +#whether to show window controls auto/yes/no +#windowcontrols= + +#whether to show mute button and volumne slider yes/no +#volumecontrol= + +#volume bar show processd volume yes/no +#processvolume= + +#eng=English chs=Chinese eng/chs +#language=chs + +#alpha of the background box,0 (opaque) to 255 (fully transparent) +boxalpha=128 + +#hight of deadzone,from bottom to top +#deadzone=200 diff --git a/script-opts/persist_properties.conf b/script-opts/persist_properties.conf new file mode 100644 index 0000000..3e26274 --- /dev/null +++ b/script-opts/persist_properties.conf @@ -0,0 +1,5 @@ +# options to pass to wget +## 设置 mpv 需全局记忆的选项状态 +properties=volume +## 保存文件路径 +properties_path=files/persistent_config.json \ No newline at end of file diff --git a/script-opts/playlistmanager.conf b/script-opts/playlistmanager.conf new file mode 100644 index 0000000..30e97b4 --- /dev/null +++ b/script-opts/playlistmanager.conf @@ -0,0 +1,157 @@ +###此配置不支持在激活的参数后进行注释,如有注释需求应另起一行 + +#### ------- Mpv-Playlistmanager configuration ------- #### + +#### ------- FUNCTIONAL ------- #### + +#navigation 键绑定仅在播放列表可见时强制覆盖 +#设置"no",则可以通过任何导航键显示播放列表 +dynamic_binds=yes + +#主菜单键位绑定 +key_showplaylist= + +#按住键位时显示播放列表 +key_peek_at_playlist= + +## 动态绑定键位 不应在 input.conf 中设置(不与静态绑定的键位冲突) +## 可以绑定多个键位,用空格分离 +key_moveup=UP WHEEL_UP +key_movedown=DOWN WHEEL_DOWN +key_movepageup=PGUP MBTN_BACK +key_movepagedown=PGDWN MBTN_FORWARD +key_movebegin=HOME +key_moveend=END +key_selectfile=RIGHT +key_unselectfile=LEFT +key_playfile=ENTER MBTN_LEFT +key_removefile=DEL BS +key_closeplaylist=ESC MBTN_RIGHT + +## 额外的功能键位动态绑定 +## 可以绑定多个键位,用空格分离 +key_sortplaylist=s +key_shuffleplaylist=r R +key_reverseplaylist=S +key_loadfiles=l L +key_saveplaylist=p P + +# json 替换格式,请查看.lua 以获取说明 +# example json=[{"ext":{"all":true},"rules":[{"_":" "}]},{"ext":{"mp4":true,"mkv":true},"rules":[{"^(.+)%..+$":"%1"},{"%s*[%[%(].-[%]%)]%s*":""},{"(%w)%.(%w)":"%1 %2"}]},{"protocol":{"http":true,"https":true},"rules":[{"^%a+://w*%.?":""}]}] +# 空值,无需更换 +filename_replace=[{"protocol":{"all":true},"rules":[{"%%(%x%x)":"hex_to_char"}]},{"protocol":{"http":true,"https":true},"rules":[{"^%a[%a%d]+://localhost:.*/":""}]}] + +## 指定从目录中搜索和加载的文件类型。注:此项与 autoload.lua 脚本功能重复 +#loadfiles_filetypes=["3gp","amr","amv","asf","avi","avi","bdmv","f4v","flv","ifo","iso","m2ts","m4v","mkv","mov","mp4","mpeg","mpg","ogv","rm","rmvb","ts","vob","webm","wmv"] +#在启动时加载 1 个或多个文件到播放列表。注:此项与 autoload.lua 脚本功能重复 +loadfiles_on_start=no + +#空闲启动时从工作目录加载文件 +loadfiles_on_idle_start=no + +#总是在当前播放文件后放置加载的文件 +loadfiles_always_append=no + +#指定在初始加载后将任何文件添加到播放列表时是否进行自然排序 +sortplaylist_on_file_add=no + +#指定使用排序功能时需使用的排序方法,必须是其中之一:"name-asc", "name-desc", "date-asc", "date-desc", "size-asc", "size-desc". +default_sort=name-asc + +#linux | windows | auto +system=auto + +#Use ~ 用于主目录。留空以使用 mpv/playlists +playlist_savepath= + +#播放列表打开时同步当前播放文件所在位置(pos) +sync_cursor_on_load=yes + +#每次加载新文件时显示文件标题 +show_title_on_file_load=no +#每次加载新文件时显示播放列表 +show_playlist_on_file_load=no +#选择播放文件后关闭播放列表 +close_playlist_on_playfile=no + +##是否光标移动到末尾自动切换到首位条目 +loop_cursor=yes + +#当播放列表不可见时重置光标导航 +reset_cursor_on_close=yes + +#允许播放列表管理器在文件之间导航时编写稍后观看配置 +allow_write_watch_later_config=no + +#在保存、随机播放、反转播放列表时向 OSD 输出视觉反馈 +display_osd_feedback=no + +#prefer 以显示以下文件的标题:"all","url","none"。排序仍使用文件名 +prefer_titles=url + +#指定要用于标题解析的 ytdl 可执行文件,可以是绝对路径。默认:yt-dlp +youtube_dl_executable=yt-dlp + +#使用 youtube-dl/yt-dlp 解析播放列表中网址的标题,默认:no +#prefer_titles 必须设置为 "url" 或"all" 才能正常工作 +resolve_url_titles=yes + +#指定播放列表中 url 标题解析的超时时长,默认值:15s +resolve_title_timeout=15 + +#指定同时解析 url 媒体标题的数量。较高的数字可能会导致卡明显的卡顿 +concurrent_title_resolve_limit=10 + +##播放列表在 OSD 显示的时长,默认值:5s +playlist_display_timeout=5 + +##播放列表将呈现的最大行数。特殊值 -1 将自动计算,默认值:-1 +showamount=13 + +##播放列表的字体样式 +#example {\fnUbuntu\fs10\b0\bord1} equals: font=Ubuntu, size=10, bold=no, border=1 +#read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags +#no 值默认为 mpv.conf 中的 OSD 设置 +style_ass_tags={\fnNoto Sans CJK SC\fs26\b1\bord0.5} + +##左上方的边距 +text_padding_x=10 +text_padding_y=15 + +#菜指定单打开时屏幕的不透明度,值:0.0 - 1.0(0 表示透明(默认),1 表示不透明) +curtain_opacity=0.0 + +##是否修改 MPV 的窗口标题 +set_title_stripped=no +title_prefix= +title_suffix= - mpv + +##是否切断长文件名,最大显示字符数 +slice_longfilenames=yes +slice_longfilenames_amount=100 + +##播放列表标题 +#%mediatitle or %filename = 播放文件的标题或名称 +#%pos = 播放文件的位置 +#%cursor = 导航的位置 +#%plen = 播放列表长度 +#%N = 换行符 +playlist_header=播放列表 [%cursor/%plen] + +##播放列表模板 +#%pos = 播放文件的位置 +#%name = 文件的标题或名称 +#%N = 换行符 +#也可以使用上面提到的 ASS 标签。例如: +# selected_file={\c&HFF00FF&}➔ %name | 为所选文件添加颜色 +#使用 ASS 标签,你需要为每一行重置它们 (see https://github.com/jonniek/mpv-playlistmanager/issues/20) +normal_file={\c&HFFFFFF&}□ %name +hovered_file={\c&H33FFFF&}■ %name +selected_file={\c&C1C1FF&}☑ %name +playing_file={\c&HAAAAAA&}▷ %name +playing_hovered_file={\c&H00FF00&}▶ %name +playing_selected_file={\c&C1C1FF&}☑ %name + +##播放列表被截断时的显示 +playlist_sliced_prefix=▲ +playlist_sliced_suffix=▼ diff --git a/script-opts/quality-menu.conf b/script-opts/quality-menu.conf new file mode 100644 index 0000000..3d4453b --- /dev/null +++ b/script-opts/quality-menu.conf @@ -0,0 +1,81 @@ +###### 键绑定 ###### +# 向上移动菜单光标 +up_binding=UP WHEEL_UP +# 向下移动菜单光标 +down_binding=DOWN WHEEL_DOWN +# 选择菜单项 +select_binding=ENTER MBTN_LEFT +# 关闭质量菜单 +close_menu_binding=ESC MBTN_RIGHT CTRL+F ALT+F +###### 键绑定 ###### + +# 字体大小按窗口缩放,如果为否需要更大的字体和填充大小 +scale_playlist_by_window=yes + +# 播放列表屁股样式覆盖大括号内。\keyvalue 是一个字段,额外 \ 用于 lua 中的转义 +# example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1 +# 标签参考 https://aegi.vmoe.info/docs/3.0/ASS_Tags/ +# 未声明的标签将使用默认的 osd 设置 +# 这些样式将用于整个播放列表。更具体的样式实现方式并不优雅 +# 建议使用等宽字体,保持样式美观 +style_ass_tags={\\fnNoto Sans CJK SC,Noto Color Emoji\\fs25\\bord0.5} + +# 自定义游标 +# 也可以使用上面提到的 ASS 标签。例如: +# selected_and_inactive={\c&H33FFFF&}● - | 为所选格式添加颜色 +# 使用 ASS 标签,你需要为每一行重置它们 +selected_and_active={\c&H00FF00&}▶ - +selected_and_inactive={\c&H33FFFF&}● - +unselected_and_active={\c&HAAAAAA&}▷ - +unselected_and_inactive={\c&HFFFFFF&}○ - + +# 移位绘图坐标。mpv.net 兼容性所必需的 +shift_x=0 +shift_y=0 + +# 左上角的填充 +text_padding_x=5 +text_padding_y=10 + +# 菜单打开时屏幕变暗 +curtain_opacity=0.7 + +# 质量菜单超时的秒数 +menu_timeout=6 + +# 使用 youtube-dl 获取可用格式的列表(覆盖 quality_strings),默认:yes +fetch_formats=yes + +# 可供选择的 ytdl 格式字符串列表 +quality_strings_video=[ {"4320p" : "bestvideo[height<=?4320p]"}, {"2160p" : "bestvideo[height<=?2160]"}, {"1440p" : "bestvideo[height<=?1440]"}, {"1080p" : "bestvideo[height<=?1080]"}, {"720p" : "bestvideo[height<=?720]"}, {"480p" : "bestvideo[height<=?480]"}, {"360p" : "bestvideo[height<=?360]"}, {"240p" : "bestvideo[height<=?240]"}, {"144p" : "bestvideo[height<=?144]"} ] +quality_strings_audio=[ {"default" : "bestaudio"} ] + +# 打开网络视频后显示视频格式菜单,默认:yes +start_with_menu=no + +# 在列表中包含未知格式,不幸的是,选择视频或音频格式并不总是完美的 +# 设置为 yes 以确保您不会错过任何格式,但随后列表还可能包括实际上不是视频或音频的格式。已知不是视频或音频的格式仍会被过滤掉 +include_unknown=no + +# 隐藏所有格式都相同的列,默认:yes +hide_identical_columns=yes + +# 指定列的属性以什么顺序显示,使用','分隔列表,属性前加'-'可使该列左对齐 +# 对于 uosc 集成,可以将文本分成标题和提示 +## 这是通过用'|'而不是逗号分隔两列来实现的 +##可用属性有: +#resolution, width, height, fps, dynamic_range, tbr, vbr, abr, asr, +#filesize, filesize_approx, vcodec, acodec, ext, video_ext, audio_ext, +#language, format, format_note, quality +##以下属性经过特殊处理 +#size, frame_rate, bitrate_total, bitrate_video, bitrate_audio, +#codec_video, codec_audio, audio_sample_rate +columns_video=-resolution,frame_rate|dynamic_range,bitrate_video,size,-codec_video,-ext +columns_audio=language,audio_sample_rate,bitrate_audio|size,-codec_audio,-ext + +# 用于排序的列,有关可用列,请参阅'columns_video' +# 逗号分隔列表,前缀列带“-”以反转排序顺序 +# 将此内容留空可保留 yt-dlp/youtube-dl 的顺序 +# 注:拼写错误的列不会导致错误,但它们可能会影响结果 +sort_video= +sort_audio= diff --git a/script-opts/read_file.conf b/script-opts/read_file.conf new file mode 100644 index 0000000..465d0c0 --- /dev/null +++ b/script-opts/read_file.conf @@ -0,0 +1,2 @@ +# options to pass to wget +#wget_opts= \ No newline at end of file diff --git a/script-opts/select.conf b/script-opts/select.conf new file mode 100644 index 0000000..157d54a --- /dev/null +++ b/script-opts/select.conf @@ -0,0 +1,7 @@ +###此配置不支持参数后注释,须另起一行 + +# 指定历史记录条目的日期格式。这被传递给 Lua 的 os.date +# 这使用与 strftime(3)相同的格式 +history_date_format=%Y-%m-%d %H:%M:%S +# 是否仅显示具有相同路径的最后一个历史记录条目,默认:yes +hide_history_duplicates=yes \ No newline at end of file diff --git a/script-opts/simplehistory.conf b/script-opts/simplehistory.conf new file mode 100644 index 0000000..2de9a87 --- /dev/null +++ b/script-opts/simplehistory.conf @@ -0,0 +1,305 @@ +####------脚本设置-----#### + +#--打开 mpv 且没有加载视频/文件时自动运行列表。'none'表示禁用。或者选择:all, recents, distinct, protocols, fileonly, titleonly, timeonly, keywords. +auto_run_list_idle=none + +#--mpv 启动且未加载任何内容时的行为。'none'表示禁用。'resume'以自动恢复您上次播放的项目。'resume-notime'以恢复您上次播放的项目,但从头开始 +startup_idle_behavior=none + +#--在打开和关闭菜单时隐藏 OSC 空闲屏幕消息(如果多个脚本触发 osc-空闲屏幕关闭,可能会导致意外行为) +toggle_idlescreen=no + +#--更改为 0,以便项目从确切位置恢复,或减小值,以便在加载恢复点之前为您提供一些预览 +resume_offset=-10 + +#--yes 用于在发生操作时显示 OSD 消息。更改为 no 将禁用从此脚本生成的所有 osd 消息 +osd_messages=yes + +#--none: :用于禁用。notification:将触发一条消息以恢复上一个到达的时间。force:根据阈值强制恢复上次播放 +resume_option=none + +#--0 在之前播放过同一视频时始终触发恢复选项,如果上次播放时间在视频的 5% 之后开始并在完成 5% 之前结束,则值(如 5)将仅触发恢复选项 +resume_option_threshold=5 + +#--yes 用于将历史记录时间标记为章节。no 禁用标记为章节的行为 +mark_history_as_chapter=no + +#--yes: 反转黑名单为白名单,以便将诸如路径/网址之类的东西添加到 history_blacklist 中以保存到历史记录中 +invert_history_blacklist=no + +#--设置黑名单:Paths / URLs / Websites / Files / Protocols / Extensions, 黑名单中的类型或路径将不会添加到历史记录中 +##例如:["c:\\users\\eisa01\\desktop", "c:\\users\\eisa01\\desktop\\*", "c:\\temp\\naruto-01.mp4", "youtube.com", "https://dailymotion.com/", "avi", "https://www.youtube.com/watch?v=e8YBesRKq_U", ".jpeg", "magnet:", "https://", "ftp"] +history_blacklist=[""] + +#--键绑定,用于在没有视频播放时立即加载和恢复最后一项。如果视频正在播放,它将恢复到上次找到的位置 +##! 注意:该绑定将覆盖 input.conf 中的同键位,推荐留空在 input.conf 中绑定该功能 +history_resume_keybind=[""] + +#--键绑定,用于在没有播放视频时立即加载最后一项而不恢复。如果视频正在播放,那么它将添加到播放列表中 +##! 注意:该绑定将覆盖 input.conf 中的同键位,推荐留空在 input.conf 中绑定该功能 +history_load_last_keybind=[""] + +#--键绑定,将用于打开列表以及指定的筛选器。可用的过滤器:"all", "recents", "distinct", "protocols", "fileonly", "titleonly", "timeonly", "keywords". +##! 注意:该绑定将覆盖 input.conf 中的同键位,推荐留空在 input.conf 中绑定该功能 +open_list_keybind=[ ["", "distinct"], ["", "recents"] ] + +#--动态键绑定,在列表打开时使用以跳转到特定筛选器(它还允许按两次筛选器键绑定以关闭列表)。可用的过滤器:"all", "recents", "distinct", "protocols", "fileonly", "titleonly", "timeonly", "keywords". +list_filter_jump_keybind=[ ["a", "all"], ["r", "recents"], ["d", "distinct"], ["f", "fileonly"], ["p", "protocols"], ["t", "titleonly"], ["l", "playing"] ] + +####------隐身设置-----#### + +#--指定是否在 MPV 启动时自动启动隐身模式 +auto_run_incognito_mode=no + +#--yes:以便自动从历史记录中删除触发隐身模式的文件,no:将文件保留在隐身模式触发的历史记录中 +delete_incognito_entry=yes + +#--"none"表示禁用,"deleted-restore"以便自动恢复进入隐身时删除的文件,"always"表示退出隐身模式后始终立即更新历史记录中的条目 +restore_incognito_entry=always + +#--键绑定,触发隐身模式。启用后播放的文件不会添加到历史记录中,直到禁用此模式 +##! 注意:该绑定将覆盖 input.conf 中的同键位,推荐留空在 input.conf 中绑定该功能 +history_incognito_mode_keybind=[""] + +####------日志记录设置------#### + +#--指定书签日志文件的保存路径。更改为'/:dir%script%'以将其放置在脚本的同一目录中,或者更改为'/:dir%mpvconf%'以将其放置在 mpv portable_config 目录中。 +##或者使用'/:var'写入任何变量,然后使用变量'/:var%APPDATA%',您也可以使用路径,例如:'/:var%APPDATA%\mpv'或'/:var%HOME%/mpv'或指定绝对路径,例如:'C:\Users\Eisa01\Desktop\' +log_path=/:dir%mpvconf%/files + +#--名称 + 将用于存储日志数据的文件的扩展名 +log_file=mpvHistory.log + +#--日志中的日期格式(请参阅 lua 日期格式),例如:"%d/%m/%y %X" or "%d/%b/%y %X" +date_format=%A/%B %d/%m/%Y %X + +#--在 all, protocols, none 中选择保存媒体标题的类型。此选项会将媒体标题存储在日志文件中,这对于网站/协议很有用,因为标题无法仅从链接中解析 +file_title_logging=protocols + +#--在下面(逗号后)添加您希望将其标题存储在日志文件中的任何协议。这仅对 (file_title_logging = "protocols" or file_title_logging = "all") 有效 +logging_protocols=["://", "magnet:"] + +#--指定显示文件名而不是标题的范围。在 local, protocols, all, 和 none 之间进行选择 +## "local"更喜欢非协议视频的文件名。"protocols"将仅首选协议的文件名。"all"将始终使用文件名而不是标题。"none"将始终使用标题而不是文件名 +prefer_filename_over_title=local + +#--限制保存具有相同路径的条目:-1 表示无限制,0 将始终更新相同路径的条目,例如值 3 将限制为 3,然后它将在第 4 个条目开始更新旧值 +same_entry_limit=2 + +####------列表设置-------#### + +#--设置是否启用光标循环滚动 +loop_through_list=yes + +#--设置是否在到达列表中间后更新显示新项目 +list_middle_loader=yes + +#--显示文件路径而不是媒体标题 +show_paths=no + +#--在显示其名称和值之前显示每个项目的编号 +show_item_number=yes + +#--设置是否按下面指定的字符数量对长文件名进行切片 +slice_longfilenames=yes + +#--用于切片长文件名的字符数量 +slice_longfilenames_amount=80 + +#--更改最大数量以在当前列表显示更多项目 +list_show_amount=10 + +#--是否启用动态选择键绑定,条目从 0 到 9,用于在列表打开时快速选择(list_show_amount = 10 是此功能工作的最大值) +quickselect_0to9_keybind=yes + +#--是否启用双击主列表时退出列表的功能,即使列表是通过其他过滤器访问的 +main_list_keybind_twice_exits=yes + +#--巧妙地将搜索设置为不键入(当搜索框打开时),而无需按 ctrl+enter 键 +search_not_typing_smartly=yes + +#--"specific"查找日期、标题、路径/URL、时间的匹配项。"any"以根据日期,标题,路径/ URL 和时间的组合查找任何键入的搜索。"any-notime"根据日期、标题和路径/URL 的组合查找任何键入的搜索,但不查找时间(这是为了减少不需要的结果) +search_behavior=any + +####------过滤器设置-------#### +##--可用过滤器:"all"以显示所有项目。或"keybinds"以显示使用键绑定插槽过滤的列表。或"recents"以显示最近添加的要记录的项目而不重复。或"distinct"以显示不同路径中文件的最近保存条目。 +##或"fileonly"以显示没有时间保存的文件。或"timeonly"以显示只有时间的文件。或"keywords"以显示具有配置中指定的匹配关键字的文件。或"playing"以显示当前播放文件的列表。 + +#--跳转到以下过滤器,并在通过左右键导航时按显示的顺序跳转。您可以更改顺序并删除不需要的筛选器 +filters_and_sequence=["all", "recents", "distinct", "protocols", "playing", "fileonly", "titleonly", "keywords"] + +#--键绑定,将用于根据 filters_and_sequence 跳转到下一个可用筛选器 +next_filter_sequence_keybind=["RIGHT", "MBTN_FORWARD"] + +#--键绑定,将用于根据 filters_and_sequence 跳转到上一个可用筛选器 +previous_filter_sequence_keybind=["LEFT", "MBTN_BACK"] + +#--是否启用循环访问过滤器的行为 +loop_through_filters=yes + +#--为您想要的"keywords"中创建一个过滤器,例如:youtube.com 将过滤掉 YouTube 上的视频。您还可以插入文件名或标题的一部分,或扩展名或路径的完整路径/部分。例如: ["youtube.com", "mp4", "naruto", "c:\\users\\eisa01\\desktop"]. 留空已禁用关键词过滤器 +keywords_filter_list=["youtube.com"] + +####------排序设置-------#### +##--可用排序:added-asc 用于首先显示最新添加的项目。或者 added-desc 用于显示添加顺序。或者 alphanum-asc 用于 A 到 Z 方法,文件名和集数先降低。或者 alphanum-desc 是它的 Z 到 A 方法。或 time-asc,time-desc 根据时间对列表进行排序 + +#--指定列表中所有不同筛选器的默认排序方法。选择范围:added-asc, added-desc, time-asc, time-desc, alphanum-asc, alphanum-desc +list_default_sort=added-asc + +#--指定特定过滤器的默认排序,例如:[ ["all", "alphanum-asc"], ["playing", "added-desc"] ] +list_filters_sort=[ ["keybinds", "keybind-asc"], ["fileonly", "alphanum-asc"], ["playing", "time-asc"] ] + +#--键绑定,用于在列表打开时循环浏览不同的可用排序 +list_cycle_sort_keybind=["alt+s"] + +####------列表设计设置------#### + +#--指定列表的对齐方式,使用数字键盘位置从 1-9 中选择,或 0 以禁用。例如:7 左上对齐,8 中上对齐,9 右上角对齐 +list_alignment=7 + +#--列表中项目显示的时间类型。选择:duration, length, remaining. +text_time_type=duration + +#--指定在保存的时间之前显示的时间分隔符样式 +time_seperator= 🕒 + +#--指定表示上面有更多项目的文本时的样式。\n 用于换行。\h 代表空格 +list_sliced_prefix=...\h\N + +#--指定表示下面有更多项目的文本时的样式 +list_sliced_suffix=... + +#--yes 启用前文本,用于在列表之前显示快速选择键绑定。no 禁用 +quickselect_0to9_pre_text=no + +#--指定列表的文本颜色,BGR 十六进制 +text_color=ffffff + +#--列表文本的字体大小 +text_scale=80 + +#--列表文本的黑色边框大小 +text_border=0.5 + +#--前光标位置的文本颜色,BGR 十六进制 +text_cursor_color=ffbf7f + +#--列表中当前光标位置的文本的字体大小 +text_cursor_scale=90 + +#--列表中当前光标位置的文本的黑色边框大小 +text_cursor_border=0.7 + +#--突出显示的多选项目的前置文本 +text_highlight_pre_text=✅ + +#--在打字模式下搜索框的颜色 +search_color_typing=ffffaa + +#--处于打字模式且处于活动状态时搜索框的颜色 +search_color_not_typing=00bfff + +#--列表标题颜色,BGR 十六进制 +header_color=00bfff + +#--列表的标题文本大小 +header_scale=100 + +#--列表标题的黑色边框大小 +header_border=0.6 + +#--要显示为列表标题的文本 +#--可用标头变量:%cursor%, %total%, %highlight%, %filter%, %search%, %listduration%, %listlength%, %listremaining% +#--仅在触发变量时显示的用户定义文本:%prefilter%, %afterfilter%, %prehighlight%, %afterhighlight% %presearch%, %aftersearch%, %prelistduration%, %afterlistduration%, %prelistlength%, %afterlistlength%, %prelistremaining%, %afterlistremaining% +#--变量说明:%cursor:显示列表中光标位置的数量。%total:当前列表中的项目总数。%highlight%:突出显示的项目总数。%filter:显示筛选器名称,%search:显示键入的搜索。仅在触发用户变量时才显示的用户定义文本示例:%prefilter:显示筛选器之前的用户定义文本,%afterfilter:显示筛选器后的用户定义文本 + +header_text=⌛ 历史菜单 [%cursor%/%total%]%prehighlight%%highlight%%afterhighlight%%prelistduration%%listduration%%afterlistduration%%prefilter%%filter%%afterfilter%%presort%%sort%%aftersort%%presearch%%search%%aftersearch% + +#--指定使用 %sort% 变量时从标头中隐藏的排序方法 +header_sort_hide_text=added-asc + +#--设置在标头中触发变量之前或之后显示的文本 +header_sort_pre_text= \{ +header_sort_after_text=} +header_filter_pre_text= [Filter: +header_filter_after_text=] +header_search_pre_text=\h\N[Search= +header_search_after_text=..] +header_highlight_pre_text=✅ +header_highlight_after_text= +header_list_duration_pre_text= 🕒 +header_list_duration_after_text= +header_list_length_pre_text= 🕒 +header_list_length_after_text= +header_list_remaining_pre_text= 🕒 +header_list_remaining_after_text= + +####-----时间格式设置-----#### +##--在第一个参数中,您可以从可用样式中定义:default, hms, hms-full, timestamp, timestamp-concise。"default"以 HH:MM:SS.sss 格式显示。"hms"以 1h 2m 3.4s 格式显示。"hms-full"与 hms 相同,但当小时和分钟为 0 时保持恒定。"timestamp"将总时间显示为时间戳 123456.700 格式。"timestamp-concise"以 123456.7 格式显示总时间(根据可用性显示和隐藏小数)。 +##--在第二个参数中,您可以定义是显示毫秒、舍入毫秒还是截断毫秒。可用选项:'truncate'以删除毫秒并保留秒数。0 删除毫秒并将秒舍入。1 或大于是要显示的毫秒数。默认值为 3 毫秒。 +##--在第三个参数中,您可以在 hour:minute:second(小时:分钟:秒) 之间定义分隔符。"default"样式自动设置为":","hms","hms-full"自动设置为" "。您可以定义自己的。一些例子: ["default",3, "-"],["hms-full",5, "."],["hms", "truncate", ":"],["timestamp-concise"],["timestamp", ["timestamp",0],["timestamp", "truncate"],["timestamp",5] + +osd_time_format=["default", "truncate"] +list_time_format=["default", "truncate"] +header_duration_time_format=["hms", "truncate", ":"] +header_length_time_format=["hms", "truncate", ":"] +header_remaining_time_format=["hms", "truncate", ":"] + + +####------列出键绑定设置------#### +#--在下面(逗号后)添加要绑定的任何其他键绑定。或者更改引号内的字母以更改键绑定 +#--更改和添加键绑定的示例:--从 ["b", "B"] 到 ["b"]. --从 [""] 到 ["alt+b"]. --从 [""] 到 ["a" "ctrl+a", "alt+a"] + +#--键绑定,将用于在列表中向上导航 +list_move_up_keybind=["UP", "WHEEL_UP"] + +#--键绑定,将用于在列表中向下导航 +list_move_down_keybind=["DOWN", "WHEEL_DOWN"] + +#--键绑定,将用于转到列表上显示的页面的第一项 +list_page_up_keybind=["PGUP"] + +#--键绑定,将用于转到列表上显示的页面的最后一项 +list_page_down_keybind=["PGDWN"] + +#--键绑定,将用于导航到列表中的第一项 +list_move_first_keybind=["HOME"] + +#--密钥绑定,将用于导航到列表中的最后一项 +list_move_last_keybind=["END"] + +#--按键绑定,用于在按下导航键绑定时突出显示,按住 shift,然后按任何导航键绑定,例如:up, down, home, pgdwn 等。 +list_highlight_move_keybind=["SHIFT"] + +#--键绑定,将用于突出显示列表中所有显示的项目 +list_highlight_all_keybind=["ctrl+a"] + +#--键绑定,将用于从列表中删除所有当前突出显示的项目 +list_unhighlight_all_keybind=["ctrl+d"] + +#--键绑定,将用于根据光标位置加载条目 +list_select_keybind=["ENTER", "MBTN_MID"] + +#--键绑定,将用于根据光标位置向播放列表添加条目 +list_add_playlist_keybind=["CTRL+ENTER"] + +#--键绑定,将用于将所有突出显示的条目添加到播放列表 +list_add_playlist_highlighted_keybind=["SHIFT+ENTER"] + +#--将用于关闭列表的键绑定(如果搜索打开,则首先关闭搜索) +list_close_keybind=["ESC", "MBTN_RIGHT"] + +#--键绑定,将用于根据光标位置删除条目 +list_delete_keybind=["DEL"] + +#--密钥绑定,将用于从列表中删除所有突出显示的条目 +list_delete_highlighted_keybind=["SHIFT+DEL"] + +#--将用于触发搜索的密钥绑定 +list_search_activate_keybind=["ctrl+f"] + +#--键绑定,将用于在保持搜索打开的同时退出搜索的键入模式 +list_search_not_typing_mode_keybind=["ALT+ENTER"] + +#--列表打开时忽略的键绑定 +list_ignored_keybind=[""] diff --git a/script-opts/stats.conf b/script-opts/stats.conf new file mode 100644 index 0000000..ee02bcf --- /dev/null +++ b/script-opts/stats.conf @@ -0,0 +1,91 @@ +###不支持参数后注释,须另起一行 + +# -- 动态键位绑定(对应五个不同的信息页) +#key_page_1=1 +#key_page_2=2 +#key_page_3=3 +#key_page_4=4 +#key_page_0=0 + +# -- 动态键位绑定(部分页面支持上下翻页) +#key_scroll_up=UP +#key_scroll_down=DOWN +##设置滚动一次的行数。默认值:1 +#scroll_lines=1 + +##短暂显示的持续时间(秒)。默认值:4 +#duration=4 +##常驻显示的数据刷新间隔(秒),设为 0 会有 bug。默认值:1 +#redraw_delay=1 +##文本格式化(ASS)。默认值:yes +##ass_formatting=yes +##禁止其它 OSD 文本覆盖 stats 信息。默认值:no +#persistent_overlay=yes +##设为 yes 将输出传递的完整信息。默认值:no +#print_perfdata_passes=no +##如果过滤器列表的长度超过这个数目,则每行显示一个过滤器。默认值:128 +#filter_params_max_length=128 +##启用调试输出。默认值:100 +#debug=no + +# -- 图形选项和样式 +##显示性能数据的图表。默认值:no +#plot_perfdata=yes +##显示垂直同步和抖动值的图形(仅在统计信息常驻显示时)。默认值:no +#plot_vsync_ratio=yes +#plot_vsync_jitter=yes +##显示缓存值图表(第 3 页),仅在切换时显示。默认值:no +#plot_cache=no +##自动启用色调映射 LUT 可视化(仅在统计信息常驻显示时)。默认值:no +#plot_tonemapping_lut=no + +#skip_frames=5 +#global_max=yes +##切换时清除数据缓冲区。默认值:yes +#flush_graph_data=yes +#plot_bg_border_width=1.25 +#plot_bg_border_color=0000FF +#plot_bg_color=262626 +#plot_color=FFFFFF + +##指定是否使用视频缩放文本和图形。no 尝试保持大小不变,auto 使用 OSD 缩放文本和图形 +##而 OSD 使用 window 或保持恒定大小,具体取决于 --osd-scale-by-window 选项。默认值:auto +#vidscale=auto + +# -- 字体相关设定 +font=Noto Sans CJK SC,Noto Color Emoji +font_mono=Noto Sans CJK SC,Noto Color Emoji +##字体大小,默认 20 +#font_size=20 +##字体颜色 +font_color=FFFFFF +##字体边框粗细,默认 1.2 +border_size=1.5 +##字体边框颜色,默认 262626 +border_color=000000 +shadow_x_offset=0.1 +shadow_y_offset=0.1 +shadow_color=000000 +##<0-99> 字体透明度,似乎是百分比,默认 11 +alpha=0 + +# -- 自定义标头,用于设置 ASS 标签的文本输出样式 +# -- 指定此参数将忽略上面的文本样式值并使用这个字符串代替 +#custom_header= + +# -- 文本格式(ASS) +#ass_nl=\\N +#ass_indent=\\h\\h\\h\\h\\h +#ass_prefix_sep=\\h\\h +#ass_b1={\\b1} +#ass_b0={\\b0} +#ass_it1={\\i1} +#ass_it0={\\i0} +# -- Without ASS +#no_ass_nl=\n +#no_ass_indent=\t +#no_ass_prefix_sep= +#no_ass_b1=\027[1m +#no_ass_b0=\027[0m +#no_ass_it1=\027[3m +#no_ass_it0=\027[0m diff --git a/script-opts/sub-select.json b/script-opts/sub-select.json new file mode 100644 index 0000000..0f59b7a --- /dev/null +++ b/script-opts/sub-select.json @@ -0,0 +1,208 @@ +[ + { + "alang": "*", + "slang": ["chs", "sc", "zho?%-cn", "zho?%-hans", "cht", "tc", "zho?%-hant", "zho?%-tw", "zho?%-hk", "zho?%-", "chi", "zho?", "und"], + "whitelist": ["chs&j[ap]n?"], + "condition": "sub.codec ~= 'null'" + }, + { + "inherit": "^", + "whitelist": ["sc&j[ap]n?"] + }, + { + "inherit": "^", + "whitelist": ["cht&j[ap]n?"] + }, + { + "inherit": "^", + "whitelist": ["ch&j[ap]n?"] + }, + { + "inherit": "^", + "whitelist": ["tc&j[ap]n?"] + }, + { + "inherit": "^", + "whitelist": ["zh&j[ap]n?"] + }, + { + "inherit": "^", + "whitelist": ["chs&eng?"] + }, + { + "inherit": "^", + "whitelist": ["sc&eng?"] + }, + { + "inherit": "^", + "whitelist": ["cht&eng?"] + }, + { + "inherit": "^", + "whitelist": ["ch&eng?"] + }, + { + "inherit": "^", + "whitelist": ["tc&eng?"] + }, + { + "inherit": "^", + "whitelist": ["zh&eng?"] + }, + { + "inherit": "^", + "whitelist": ["中日"] + }, + { + "inherit": "^", + "whitelist": ["中英"] + }, + { + "inherit": "^", + "whitelist": ["中上英下"] + }, + { + "inherit": "^", + "whitelist": ["简英"] + }, + { + "inherit": "^", + "whitelist": ["双语"] + }, + { + "inherit": "^", + "whitelist": ["特效"] + }, + { + "inherit": "^", + "whitelist": ["简体&英文"] + }, + { + "inherit": "^", + "whitelist": ["繁英"] + }, + { + "inherit": "^", + "whitelist": ["繁体&英文"] + }, + { + "inherit": "^", + "whitelist": ["繁體&英文"] + }, + { + "inherit": "^", + "whitelist": ["chs"] + }, + { + "inherit": "^", + "whitelist": ["sc"] + }, + { + "inherit": "^", + "whitelist": ["cn"] + }, + { + "inherit": "^", + "whitelist": ["hans"] + }, + { + "inherit": "^", + "whitelist": ["cht"] + }, + { + "inherit": "^", + "blacklist": ["dutch"], + "whitelist": ["tc"] + }, + { + "inherit": "^", + "whitelist": ["hant"] + }, + { + "inherit": "^", + "whitelist": ["hk"] + }, + { + "inherit": "^", + "whitelist": ["tw"] + }, + { + "inherit": "^", + "whitelist": ["简"] + }, + { + "inherit": "^", + "whitelist": ["中"] + }, + { + "inherit": "^", + "whitelist": ["繁"] + }, + { + "alang": "*", + "slang": "und", + "blacklist": [ "sign", "song", "comment", "danmaku", "danmu", "xml" ], + "condition": "sub.codec ~= 'null'" + }, + { + "alang": "*", + "slang": ["chi", "zho?", "und"], + "whitelist": ["simplified"], + "condition": "sub.codec ~= 'null'" + }, + { + "inherit": "^", + "whitelist": ["traditional"] + }, + { + "alang": "*", + "slang": "zho?%-cn", + "condition": "sub.codec ~= 'null'" + }, + { + "inherit": "^", + "slang": "zho?%-hans" + }, + { + "inherit": "^", + "slang": "zho?%-hant" + }, + { + "inherit": "^", + "slang": "zho?%-hk" + }, + { + "inherit": "^", + "slang": "zho?%-tw" + }, + { + "inherit": "^", + "slang": "zho?%-" + }, + { + "inherit": "^", + "slang": "chi" + }, + { + "inherit": "^", + "slang": "zho?" + }, + { + "inherit": "^", + "slang": "default" + }, + { + "inherit": "^", + "slang": "forced" + }, + { + "inherit": "^", + "slang": "j[ap]n?", + "blacklist": [ "sign", "song" ] + }, + { + "inherit": "^", + "slang": "eng?", + "blacklist": [ "sign", "song" ] + } +] \ No newline at end of file diff --git a/script-opts/sub_assrt.conf b/script-opts/sub_assrt.conf new file mode 100644 index 0000000..f5aa2ed --- /dev/null +++ b/script-opts/sub_assrt.conf @@ -0,0 +1,7 @@ +# API token, 可以在 https://assrt.net 上注册账号后在个人界面获取 +#示例为脚本内预设的 key +#api_token=tNjXZUnOJWcHznHDyalNMYqqP6IdDdpQ +# 是否使用 https,默认 yes +#use_https=no +# 代理设置 +#proxy= \ No newline at end of file diff --git a/script-opts/sub_export.conf b/script-opts/sub_export.conf new file mode 100644 index 0000000..22b90a4 --- /dev/null +++ b/script-opts/sub_export.conf @@ -0,0 +1,4 @@ +#ffmpeg 所在绝对路径,或者放入环境变量 +ffmpeg_path=ffmpeg +#指定脚本在 OSD 和控制台显示的文本使用的语言,eng=English, chs=Chinese。默认值:eng +language=chs \ No newline at end of file diff --git a/script-opts/sub_select.conf b/script-opts/sub_select.conf new file mode 100644 index 0000000..2844b9c --- /dev/null +++ b/script-opts/sub_select.conf @@ -0,0 +1,24 @@ +####################################################### +## Default configuration file for mpv-sub-select ## +## https://github.com/CogentRedTester/mpv-sub-select ## +####################################################### + +# 强制启用脚本 +#! 注意:这不会覆盖 sid 选项的显式指定 +force_enable=yes + +# 基于偏好 json 文件的实验性音轨选择 +select_audio=no + +#observe 音频开关,并在 alang 更改时重新选择字幕 +observe_audio_switches=yes + +# 仅选择用字幕轨道中明确说明的强制字幕。 +# 默认情况下,在搜索特定语言的字幕轨道时, +# 强制字幕将包含在搜索结果中,并与其他曲目相同。 +# 这意味着没有办法编写专门排除强制字幕轨道的规则 +# 通过启用强制字幕,除非有规则在`slang`中明确包含"forced",否则永远不会选择强制字幕 +explicit_forced_subs=no + +# 指定包含 "sub-select.json" 文件的文件夹 +config=~~/script-opts \ No newline at end of file diff --git a/script-opts/thumbfast.conf b/script-opts/thumbfast.conf new file mode 100644 index 0000000..dd9c486 --- /dev/null +++ b/script-opts/thumbfast.conf @@ -0,0 +1,42 @@ +# Socket 路径 (留空自动设置) +socket= + +# 缩略图缓存路径 (留空自动设置) +thumbnail= + +# 最大缩略图大小(以像素为单位)(缩小以适合) +# 当启用 hidpi 时此值会自适应缩放 +max_height=200 +max_width=200 + +# 叠加 ID +overlay_id=42 + +# 在文件加载时生成缩略图器,以更快地获得初始缩略图。默认禁用 +spawn_first=no + +# 是否退出超时未活动的缩略图进程(秒),默认 0 即禁用 +quit_after_inactivity=0 + +# 在网络播放时启用。默认禁用 +network=no + +# 在音频播放时启用。默认禁用 +audio=no + +# 启用硬件解码生成缩略图。默认禁用 +# 注意:硬解在高端显卡上可以加速生成缩略图,但在低端显卡上可能会出问题 +hwdec=yes + +# 仅限 Windows:使用原生 Windows API 写入管道(需要 LuaJIT)。默认禁用 +direct_io=yes + +# 指定 mpv 可执行文件的自定义路径。默认:mpv +mpv_path=mpv + +# 指定需要忽略的视频扩展名黑名单,这些文件无法正常生成缩略图 +blacklist_ext=bdmv,ifo + +## 指定需忽略的共享盘(挂载盘)的路径/目录(缩略图生成性能差) +## windows 示例:excluded_dir=["X:", "Z:", "F:/Download/", "Download"] +#excluded_dir=[] \ No newline at end of file diff --git a/script-opts/trackselect.conf b/script-opts/trackselect.conf new file mode 100644 index 0000000..6c7afdd --- /dev/null +++ b/script-opts/trackselect.conf @@ -0,0 +1,30 @@ +# Options are slash-separated lists of words and languages +#是否启用脚本,默认 yes +enabled=yes +#同步选择曲目,与其他脚本一起更好地工作,默认 yes +hook=yes +#模仿 mpv 的曲目列表信息,以保留用户在文件中选择的曲目,默认 no +#注意此项必须设为 no,否则脚本功能无法真正生效 +fingerprint=no +#覆盖用户的显式曲目选择,默认 no +force=no +#如果 mpv 无法做到这一点,请尝试重新选择最后一个轨道,例如当信息更改时,默认 no +smart_keep=no +## 指定需忽略的特殊协议 +special_protocols=["://", "^magnet:"] + +#视频轨道筛选项设置 +#preferred_video_lang= +#excluded_video_words= +#expected_video_words= + +#音频轨道筛选项设置 +preferred_audio_lang=japanese/jpn/jap/ja/jp/english/eng/en +preferred_audio_channels=8/6/3/2 +excluded_audio_words=commentary/cast/staff/dub/guide +expected_audio_words= + +#字幕轨道筛选项设置 +#preferred_sub_lang=chs/sc/zh-CN/zh-Hans/cht/tc/zh-Hant/zh-HK/zh-TW/chi/zh +#excluded_sub_words= +#expected_sub_words=中日/中英/中上英下/双语/特效/简/繁/中 diff --git a/script-opts/uosc.conf b/script-opts/uosc.conf new file mode 100644 index 0000000..fcbf699 --- /dev/null +++ b/script-opts/uosc.conf @@ -0,0 +1,241 @@ +# 时间轴中当前位置的显示样式。可用:line, bar +timeline_style=bar +# 时间线(line)宽度(窗口/全屏模式) +timeline_line_width=2 +# 进度条完全展开时的时间轴大小,以像素为单位,0 表示禁用 +timeline_size=30 +# 背景颜色的顶部边框,有助于在视觉上将时间轴与视频分开 +timeline_border=1 +# 指定在时间线上使用鼠标滚轮时,跳转的步进秒数。默认:5 +# 默认使用快速查找。添加 '!' 后缀以启用精确查找。示例:'5!' +timeline_step=5 +# 是否在时间轴上显示网络内容的渲染缓存指标,默认:yes +timeline_cache=yes +# 设置时间轴应始终可见的状态。使用逗号分隔,可用:paused, audio, image, video, idle, windowed, fullscreen +timeline_persistency= +# 设置何时显示始终可见的进度条(最小化时间线)。可以是:windowed(默认值), fullscreen, always, never +# 也可以使用 `toggle-progress` 命令按需切换 +progress=windowed +progress_size=2 +progress_line_width=10 + +# 以逗号分隔的项列表,用于构造时间轴上方的控制栏。设置为`never`以禁用 +# 参数规范:括在`{}`中表示值,括在`[]`中表示可选 +# 完整的条目语法:`[<[!]{disposition1}[,[!]{dispositionN}]>]{element}[:{paramN}][#{badge}[>{limit}]][?{tooltip}]` +# +# 常用属性参考: +# `{icon}` 指定图标名称的参数(例如 face)这里查询所有可用的值 https://fonts.google.com/icons?icon.platform=web&icon.set=Material+Icons&icon.style=Rounded +# `{element}`的参数及介绍: +# `{shorthand}` - 以下的可用值都是预配置好的快捷指令,可作为按钮: +# play-pause(播放/暂停)menu(菜单)subtitles(字幕轨列表)audio(音轨列表)video(视频轨列表)playlist(播放列表)chapters(章节列表)editions(版本列表) +# stream-quality(流式传输品质偏好)open-file(文件浏览器)items(播放列表/文件浏览器) +# next(跳转下一个)prev(上一个)first(首位)last(末位)audio-device(音频输出设备列表) +# fullscreen(切换全屏)loop-playlist(切换列表循环)loop-file(切换单曲循环)shuffle(切换乱序播放)autoload(自动加载文件) +# +# speed[:{scale}] (速度滑块 其中控件系数的尺寸,默认 1.3) +# command:{icon}:{command} (按下该按钮时执行的指令) +# toggle:{icon}:{prop} (切换 mpv 属性的按钮) +# +# cycle:{default_icon}:{prop}:{value1}[={icon1}][!]/{valueN}[={iconN}][!] +# 在不同 mpv 属性的值之间循环的按钮,每个值都可以选择不同的 {icon} 和激活标记。结尾处赋予可选的半角感叹号,将使该按钮成为可激活的样式。 +# +# gap[:{scale}] (留出一个间隔 其中系数的尺寸,默认 0.3) +# space(填补上两个控件之间的所有空间,对于将条目右对齐非常有用。用多个 space 可在它们之间分配空间,可用于居中对齐) +# +# 控件条目的可见性控制: +## `<[!]{disposition1}[+[!]{dispositionN}][,{more_dispositions}]>` - 可选的前缀是用于控制 {element} 的可见性 +# - `+` 创建 AND 条件,`,` 拆分为 OR 组。示例:`` -> `foo OR (bar AND baz)` +# - `{disposition}` 的可用值: +## idle 如果 mpv 处于空闲状态则为 true +## image 如果当前文件为单帧图片则为 true +## audio 如果当前文件为纯音频则为 true +## video 如果当前文件存在视频轨则为 true +## has_many_video 如果当前文件存在多个视频轨则为 true +## has_image 如果当前文件带有封面或其他图像轨道则为 true +## has_audio 如果当前文件存在音轨则为 true +## has_many_audio 如果当前文件存在多个音轨则为 true +## has_sub 如果当前文件存在字幕轨则为 true +## has_many_sub 如果当前文件存在多个字幕轨则为 true +## has_many_edition 如果当前文件存在多个版本则为 true +## has_chapter 如果当前文件存在章节则为 true +## stream 如果当前文件为流则为 true +## has_playlist 如果当前列表存在多个文件则为 true +## {mpv_prop} 任何 mpv 属性(注意:可以在脚本中设置 `user-data/foo` 以添加自定义属性) +## 可选的`!`前缀可用来反转所需的处理方式 +## 示例: +## - `stream-quality` - 仅对流媒体显示“流式传输品质偏好”按钮 +## - `audio` - 对所有存在音轨的文件显示“音轨列表”按钮,但不包括纯音频的文件 +# +# 将 `#{badge}[>{limit}]` 放在 `{element}` 参数后,可赋予它一个徽章标记。可用的 `badge` 值: +## `sub`, `audio`, `video` - 轨道计数值 +## `{mpv_prop}` - 如果 mpv 的属性值是一个数组,将显示其大小。可用的属性参见:https://mpv.io/manual/master/#property-list +## `>{limit}` 只有当它的数值高于此阈值时,才会显示徽章标记 +## 示例:`#audio>1` +# +# 将 `?{tooltip}` 放在 `{element}` 的设置后面,赋予它一个工具提示 +## 示例:`stream-quality?Stream quality` +# +# 一些可用的快捷指令的实现示范: +## menu = command:menu:script-binding uosc/menu-blurred?Menu +## subtitles = command:subtitles:script-binding uosc/subtitles#sub>1?Subtitles +## 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,open-file,command:history:script-binding recentmenu/open?最近播放,command:bookmarks:script-binding simplebookmark/open-list?书签菜单,command:file_copy:script-binding smartcopypaste_II/open-list?剪贴菜单,gap,command:analytics:script-binding stats/display-stats-toggle?统计,stream-quality,command:image:script-binding uosc/video#video?封面,editions,