如何使mpv在新加载文件时仅使用一个实例而不是多个?

(使用的是mpv-lazy项目)
如题,我问了gpt,他给的两个方案一个lua脚本一个conf文件均失效……
现在的状态使是没有用conf,用了lua脚本,但仍然多个实例同时运行

附:

解决方案1

conf文件添加一行
single-instance=yes

解决方案2

新建一lua脚本至 '~\portable_config\scripts' 目录下

local mp = require 'mp'

function focus_existing_instance()
    local running = mp.command_native({"get_property", "pid"})
    if running then
        mp.command_native({"run", "wmctrl", "-a", "mpv"})
        os.exit()
    end
end

mp.register_event("file-loaded", focus_existing_instance)

但经过测试,两种方法均失效,求问原因。

附:

conf文件内容
### https://github.com/hooke007/MPV_lazy/blob/main/portable_config/mpv.conf


 input-conf = "~~/input_uosc.conf"
 include = "~~/profiles.conf"
 include = "~~/script-opts.conf"
 use-filedir-conf = yes
#log-file = "~~desktop/mpv-lazy.log"

 ########
 # 基础 #
 ########

#vo = gpu-next
#gpu-context = winvk
#d3d11-exclusive-fs = yes
#d3d11-flip = no
 
#single-instance=yes
 hwdec = auto-copy
 hwdec-codecs = h264,hevc,vp8,vp9,av1,prores

#d3d11-adapter = "NVIDIA GeForce RTX 2070 Super"
#vulkan-device = "NVIDIA GeForce RTX 2070 Super"


 ########
 # 功能 #
 ########

 idle = yes
#input-ipc-server = mpvpipe
 input-builtin-bindings = no
 pause = no

 hr-seek-framedrop = no
 save-position-on-quit = yes
 watch-later-options = start,vid,aid,sid
 loop-playlist = yes

 keep-open = yes
#ontop = yes
#border = no
 autofit-smaller = 40%x40%
 keepaspect-window = no
 auto-window-resize = yes
 hidpi-window-scale = no

 demuxer-max-bytes = 1024MiB
 icc-cache-dir = "~~/_cache/icc"
 gpu-shader-cache-dir = "~~/_cache/shader"
 watch-later-directory = "~~/_cache/watch_later"
 

 #######
 # OSD #
 #######

 osd-on-seek = msg
#osd-blur = 1
 osd-bar-w = 100
 osd-bar-h = 1.5
 osd-bar-align-y = -1
 osd-color = "#672168"
 osd-border-color = "#FFFFFF"
 osd-border-size = 1
 osd-font-size = 40
 osd-fractions = yes
 osd-playing-msg = "${filename}"
 osd-duration = 2000
 osd-playing-msg-duration = 3000


 ########
 # 音频 #
 ########

 ao = wasapi
#audio-device = "wasapi/{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
 audio-exclusive = no

 volume = 100
 volume-max = 120
 audio-channels = stereo
 alang = chs,sc,zh,chi,zho
 audio-file-auto = fuzzy
 audio-pitch-correction = yes


 ########
 # 视频 #
 ########

#icc-profile-auto = yes

#target-prim = display-p3

 video-sync = display-resample
 video-sync-max-video-change = 5
 interpolation = yes
 tscale = linear

 cscale = bilinear
 scale = spline36
 dscale = bicubic
#sigmoid-upscaling = yes
#correct-downscaling = yes

#dither-depth = 10
#dither = error-diffusion
#deband = yes

#tone-mapping = bt.2390
 tone-mapping-mode = hybrid
 gamut-mapping-mode = clip


 ####################
 # 脚本 滤镜 着色器 #
 ####################

 osc = no
#ytdl-raw-options-append = cookies-from-browser=edge

#load-scripts = no

 glsl-shaders-append = "~~/shaders/AMD_FSR_EASU_rgb.glsl"


 ########
 # 字幕 #
 ########

 sub-auto = fuzzy
 sub-file-paths = sub;subtitles
 slang = chs,sc,zh,chi,zho
#blend-subtitles = video

 sub-font = "LXGW WenKai Mono"
 sub-font-size = 44
#sub-scale-with-window = no
 sub-border-size = 4
 sub-blur = 1
 sub-color = "#FFD766"
#sub-back-color = "#641C1C1C"
#sub-shadow-offset = 2
 sub-use-margins = yes

#sub-ass-override = force
#sub-ass-scale-with-window = yes
 sub-ass-force-margins = yes
#sub-ass-force-style = Fontname=LXGW WenKai Mono

#stretch-image-subs-to-screen = yes
#image-subs-video-resolution = yes


 ########
 # 截图 #
 ########

 screenshot-format = png

 screenshot-jpeg-quality = 100
#screenshot-jpeg-source-chroma = no
 screenshot-webp-lossless = yes
 screenshot-webp-compression = 0
 screenshot-jxl-distance = 0

 screenshot-tag-colorspace = no
 screenshot-high-bit-depth = no
 screenshot-template = "~~desktop/MPV-%P-N%n"

参考:

感谢 :sparkles:

终于明白了为啥不行了……mpv本身不支持,需要通过外挂cmd或者bat或者ps脚本解决……如果用的是官版或者微改版都不行……得找懒人包或者傻瓜特别版类似的才能做到……

果然,chatgpt又在胡扯 :joy:

千万不要问gpt的具体程序执行,纯胡扯和蒙。他能编一堆不存在的参数和命令

1 个赞

以前最开始用的是umpvw
然后用的mpv.net

解决了单实例的问题发现还要解决载入什么文件的问题…
umpvw时用的是autoload脚本
mpv.net有自带这功能
它们都会把所有支持的文件都载入到列表中…
音频,视频,图片全都载入…

然后还遇见了排序问题…
autoload和资源管理器中的顺序可能还是不一样的
假如视频命名是这样1,2... 10,11...
它可能会这样载入1,10,11,2....
mpv.net好一点是按照资源管理器命名排列的

mpv.net时用了一个很不优雅的方法解决载入什么文件编译了个自用版本

现在用的是AHK载入libmpv的方法,和mpv.net类似,但简陋了许多
受限于能力始终无法很好的解决事件循环…
用H版开新线程和开个C#线程去监控事件都有难以解决的问题
也没好办法像mpv.net那样劫持拖拽事件
弄这么复杂也就为了一些特殊需求
不同实例载入不同类型文件,排序,跳过片头等等.

20230502152220

纯粹胡扯,mpv文档久没有这个东西。。。mpv根本没做单实例模式。

事件循环有什么难点?

事件循环大概应该没问题
我照抄的mpv.net的代码

是主线程出现了一些莫名其妙的错误
比方说我会用这个整理视频文件
不需要的添加进一个数组中,然后在退出时批量删除它们
这些代码和mpv完全无关,但只要在新线程中开启了事件循环退出删除的代码直接就不运行了
还有我会监控当前文件夹,然后更新播放器列表,更新时直接就闪退了
只能临时暂停事件循环然后再更新.
甚至连AHK的run外部程序都出现了问题

以上都做过测试只要新开线程监控事件循环就偶尔会出错,即使事件循环里什么都不做
事件循环handle和namehandle都测试过,

感觉像是多线程冲突。我也是用 H 版创建新线程接收 mpv 回调。但回调线程除了把事件通过 SendMessage 发送给主线程外什么都不做,这避免了内存冲突。主线程作为一个交互外壳和操控者,对性能没有高需求。

对了,mpv.net的事件处理,是如何处理错误视频文件的?比如打开个0大小的视频文件,如何从事件得到错误消息?我目前只有这一个问题没解决。

我也没在事件循环进程中做任何处理呀…
甚至事件循环里什么都不做都不行,连消息类型都没判断

loop
{
     mpv_event := DllCall("libmpv-2.dll\mpv_wait_event", "ptr", namehandle, "double", 1, "Cdecl int")
}

很可能没处理.我看它把错误原因发送给了一个事件,
但该事件只暴露给了它的poweshell脚本.自己没有处理

不做任何处理。。。那这个H线程有什么意义?
你是保留了 mpv 原本的交互能力?我是把这部分完全弃用了的。mpv 只负责渲染视频,其他任何功能都由 AutoHotkey实现。

为了测试…
即使精简到这种地步还是会出错

保留了交互能力,加载配置,加载脚本,加载快捷键我都没动.
这样切换到其他版本也能快速使用
我只在AHK中实现了一部分不好在脚本中实现的功能.

你这样用变数就多了。我是把 mpv 当作一个图片控件来用,mpv 不会出错,我的脚本不出错就不会有任何问题。

这样做的好处在于只要改动不超过50行,就能无损切换至mpv.exe
当然切换后处理就慢很多了,是通过pipe连接的.

我的 mpv 脚本写好之后,重新使用其他播放器的机率就是 0 :innocent:

大悲伤,决定用aardio写一个后台程序自动拦截新实例运行并将旧实例用命令行更新……

完全没找到优雅的解决方案啊 :face_exhaling:

真的,我这么傻,本以为她能给我解决问题省去我大量查找资料时间的,但我没想到,这破玩意编的有模有样的……给我唬的一愣一愣的,查了半天自己的操作有没有问题,甚至怀疑到了自己的是不是把alpha替换了a导致出现的这种问题……反复排查没找到,官方文档也没看到他给的参数,我看他说的有鼻子有眼的,甚至以为是官方文档没来得及更新……

不想开新mpv窗口时,直接将要打开的文件拖入已有窗口,或者用file-browser脚本打开文件。我目前是这样用的

用多了就能发现这玩意坑人是一本正经的,甚至简单代码计算都能出错。

1 个赞