首页
留言
动态
归档
推荐
音乐
工具
Search
1
Emby公益服-上万部电影电视剧免费看
69,093 阅读
2
openwrt-docker部署lxk0301京东自动签到脚本
13,105 阅读
3
QuantumultX-京东签到撸京东豆
11,344 阅读
4
LXK0301京东签到脚本-自动提交互助码
9,762 阅读
5
微信-域名被封监测以及自动更换被封域名
9,269 阅读
随便写写
科学上网
Web开发
瞎折腾
Search
标签搜索
quantumultx
laravel
openwrt
laravel nova
laradock
telegram
DDC/CL
薅羊毛
google adsense
jd_scripts
京东签到
ubuntu
oh-my-zsh
web开发环境
nginx
工具
shadowsocks shadowsocksR
RBAC
权限管理
内网穿透
orzlee
世界上只有一个问题,那就是时间问题
累计撰写
46
篇文章
累计收到
596
条评论
首页
栏目
随便写写
科学上网
Web开发
瞎折腾
页面
留言
动态
归档
推荐
音乐
工具
搜索到
2
篇与
DDC/CL
的结果
2025-03-04
通过USB扩展坞代替KVM切换显示器输入源
前言 入了台新电脑,揪心事情就来了。两台显示器、一套键鼠怎么在都开机的情况共用两台主机呢?而且还有来回切换的场景。 上网查,发现有东西叫KVM切换器,原理就是两台主机显示接口接入KVM的显示输入接口,USB输入接口,然后KVM在出两根视频线给显示器。切换的时候应把A主机视频信号切断,通过硬件让显示器接入B主机输出的视频信号。线多点无所谓,切换过程耗时也能接受,继续查各网友使用反馈。得到的结论就是国内这东西无异于工业垃圾... 二进二出KVM对高帧率支持有限,EDID(在Windows下切换屏幕后系统桌面程序窗口还是之前一样,没有EDID切回就乱了,mac就算拔掉一个显示器,插回去还会恢复...)寥寥无几,更别提各种黑屏闪屏乱七八糟的问题,倒是价格三五百也还好。反正网上没有说非常满意的,最多也就是个能用。 灵机一动,我买个USB切换器,写个程序监测鼠标键盘插入拔出,通过DDC/CI直接切换显示器输入源不久OJBK了吗?买个KVM我实在都没真心满意的。两台4K显示器,LG的144HZ,另一台60HZ。要放弃144HZ选择还多点,不然没办法。而且支持EDID只有一款双HDMI的支持,其他不支持。 搞起 显示器必须支持DDC/CI,不支持都不用搞了。大厂应该都支持,小作坊就不保证了。Dell、LG两个在查资料过程还是看到不少关于这两显示器问题的。下个control_my_monitor打开看看吧。 我本来想用go来写的,结果go在winodws监听USB输入输出事件没有很简单的方法,不成熟。不过找了这么多资料总有点结果,nodejs有usb包支持usb热插拔事件。既然能支持,还管它什么语言,能解决问题就是好语言。 当USB切换器切换当前主机的键盘和鼠标USB会拔出,反之另一台会插入。基本逻辑就是插入鼠标键盘,DDC/CI切换显示器输入源为当前主机视频接口,两台主机一边一套,这样理论上支持无限台主机数量。其实只要有切换器,不一定要鼠标或者键盘,随便插个什么USB都行。 LG显示器DDC/CI切换输入源比较麻烦,可以看我上一篇文章解决LG显示器无法通过DDC/CL切换输入源,其他显示器可以看看输入源端口代码。 windows这边好弄,但是mac有点麻烦。因为macBetterDisplay只能登陆后启动,不能开机直接启动(可能有办法解决,没深入研究)。然后通过USB扩展坞扩展的视频接口是个残缺DDC/CI接,没法切换输入源,调节他亮度声音倒没什么问题。难道又买一根type-C to HDMI的线?另一台直连HDMI接口的显示没有问题。 干脆就到windows上跑nodejs好了,反正只有两台主机,插入就切windows主机,拔出切回去。 我用到了winddcutil(control_my_monitor也可以,无非就是换下命令)。nodejs需要安装usb包。 直接上代码: const usb = require('usb').usb; const { exec } = require('child_process'); const os = require('os'); // const fs = require('fs'); // const path = require('path'); const platform = os.platform(); // const LOG_FILE = path.join(__dirname, 'usb_switch_monitor.log'); const DEVICE_VENDOR_ID = 1507; const DEVICE_PRODUCT_ID = 1552; const WINDOWS_DIR = 'D:
\
xxx
\
xxx
\
'; // console.log('USB hot plug switch monitor service started...'); // console.log(usb.getDeviceList()); // 写入日志函数 // function writeLog(message) { // const timestamp = new Date().toISOString(); // const logMessage = `[
t
i
m
e
s
t
a
m
p
]
{message}\n`; // fs.appendFile(LOG_FILE, logMessage, (err) => { // if (err) { // console.error(`无法写入日志: ${err}`); // } // }); // } //执行命令函数 async function executeCommand(command) { exec(command, (error, stdout, stderr) => { if (error) { console.error(`执行错误:
执
行
错
误
e
r
r
o
r
‘
)
;
/
/
w
r
i
t
e
L
o
g
(
‘
执
行
错
误
:
{error}`); // return; } console.log(`输出:
执
行
命
令
s
t
d
o
u
t
‘
)
;
/
/
w
r
i
t
e
L
o
g
(
‘
执
行
命
令
:
{command}`); // writeLog(`输出: ${stdout}`); }); } // Listen for attach event usb.on('attach', (device) => { // console.log('USB attached:', device); console.log('attach Vendor ID:', device.deviceDescriptor.idVendor); console.log('attach Product ID:', device.deviceDescriptor.idProduct); if (device.deviceDescriptor.idVendor === DEVICE_VENDOR_ID && device.deviceDescriptor.idProduct === DEVICE_PRODUCT_ID) { console.log('检测到设备插入'); // writeLog('检测到设备插入'); if (platform === 'win32') { // 模拟鼠标移动唤醒屏幕 executeCommand('cmd /c '+ WINDOWS_DIR + 'nircmd-x64
\
nircmd.exe sendmouse move 10 10'); // writeLog('移动鼠标唤醒屏幕'); //切换LG显示器 DP端口 executeCommand('cmd /c '+ WINDOWS_DIR +'amdddc-windows.exe --i2c-source-addr 0x50 setvcp 5 0 0xD0'); // writeLog('切换LG屏幕已执行'); // 查看所有显示器 // executeCommand('cmd /c '+ WINDOWS_DIR +'winddcutil.exe detect'); executeCommand('cmd /c '+ WINDOWS_DIR +'winddcutil.exe setvcp 1 0x60 15'); // writeLog('切换屏幕已执行'); } // else if (platform === 'darwin') { // // macOS 的唤醒命令 // executeCommand('caffeinate -u -t 1'); // //切换HDMI-2 // executeCommand('ddcutil -d 1 setvcp xF4 x0091 --i2c-source-addr=x50 --noverify'); // //切换HDMI-1 // executeCommand('ddcutil -d 2 setvcp 60 0x11'); // // macOS 的熄屏命令 // // executeCommand('pmset displaysleepnow'); // } else { console.log('不支持的操作系统'); } } }); // Listen for detach event usb.on('detach', (device) => { // console.log('USB detached:', device); console.log('detach Vendor ID:', device.deviceDescriptor.idVendor); console.log('detach Product ID:', device.deviceDescriptor.idProduct); if (device.deviceDescriptor.idVendor === DEVICE_VENDOR_ID && device.deviceDescriptor.idProduct === DEVICE_PRODUCT_ID) { console.log('检测到设备拔出'); // writeLog('检测到设备插入'); if (platform === 'win32') { // writeLog('移动鼠标唤醒屏幕'); //切换DP executeCommand('cmd /c '+ WINDOWS_DIR +'amdddc-windows.exe --i2c-source-addr 0x50 setvcp 5 0 0x91'); // writeLog('切换LG屏幕已执行'); // executeCommand('cmd /c '+ WINDOWS_DIR +'winddcutil.exe detect'); executeCommand('cmd /c '+ WINDOWS_DIR +'winddcutil.exe setvcp 1 0x60 17'); // writeLog('切换屏幕已执行'); } // else if (platform === 'darwin') { // // macOS 的唤醒命令 // executeCommand('caffeinate -u -t 1'); // //切换HDMI-2 // executeCommand('ddcutil -d 1 setvcp xF4 x0091 --i2c-source-addr=x50 --noverify'); // //切换HDMI-1 // executeCommand('ddcutil -d 2 setvcp 60 0x11'); // // macOS 的熄屏命令 // // executeCommand('pmset displaysleepnow'); // } else { console.log('不支持的操作系统'); } } }); 开机启动 接下来就是开机启动脚本了。windows自定义开机启动还是比较方便的,有很多种方法。注册服务、任务调度、放到启动目录,很可惜都不行。前两个开机启动后后台运行,没有黑窗口,但是检测不到显示器了...放到启动目录只能开机登陆后启动,万一在另一台主机上,这台才开机切回来屏幕还是上一台主机的。 新建个文本文档: @echo off start /min cmd /k "node D:\xx\xx\脚本名字.js" 改名为xxx.bat 找到了个改注册表开机启动的方法(原文): 用户登陆时运行: 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run 不管用户是否登录都要运行: 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 两者配置方式相同,只是路径不同,以下是示例: 右键创建 "字符串值" 数值名称 随意 数值数据 指定文件路径(把bat路径填进去) 完美解决,就是会一直有一个黑窗口。不过也好,不用单独也日志,出现问题方便查看。 结语 终于都实现了,不用KVM,也不用手动切换显示器。总算完美了,切换过程丝和KVM一样会黑屏,全靠显示器切换速度。比KVM少两跟线,没有奇奇怪怪的显示问题,USB切换器也比KVM便宜,也支持高分辨率。windows屏幕没有断开,不需要EDID维持原窗口,随便怎么切都是原来的样子。缺点就是只支持两台主机,如果没有mac,那完全可以一台主机跑一套,只监听usb插入事件,支持<=USB扩展坞支持数量。 研究了好几天,中途都想放弃了,LG显示器太磨人了。不过好在还是找到了解决方法,简直大海捞针...
2025年03月04日
71 阅读
1 评论
0 点赞
2025-03-01
解决LG显示器无法通过DDC/CL切换输入源
前言 LG虽然是大厂,但是显示器DDC/CL却无法设置输入源。声音亮度等设置却没有问题,这是我目前最想要的功能。我有两个系统,共用两个显示器,不想买二进二出KVM切换器。国内这些KVM也就是个能用的程度。高刷和EDID几乎没有,就算有也不是所有接口都支持。 所以我有个想法,让系统来通过显示器DDC/CI控制切换,我再买个USB二进二出切换器,共用键盘和鼠标。写个程序监听USB设备,插入就通过电脑执行DDC/CI切换显示器输入源。 这样比KVM二进二出切换器多了很多优点: 少了连根视频线 显示器和主机直连兼容性更好 USB切换器便宜 支持高刷等显示器特性(EDID的话我目前切换没有乱桌面布局,我不确定) 我的两台显示器,一台是AOC,好多年了,DDC/CI没有任何问题。还有台LG 27GP95RP,这两年入的,DDC/CL能控制大部分功能,唯独输入源控制不了。国内LG DDC/CI相关讨论都很少,国外还是有讨论关于LG显示器DDC/CI的问题。 开搞 DDC/CI不支持,国外有大佬通过GPU来控制显示器切换。我不太懂,你可以看看这篇文章。虽然里面只列出少部分LG显示器型号,但是自己试试说不定也支持,27GP95RP上面就没有列出,但是确实可行。 先上输入源代码,其实很好区分,你先确定你的LG显示器有什么接口,例如两个HDMI和一个DP,HDMI就是0x90开始递增,DP接口就是0xD0递增,至于type-c就要自己找找了,应该是通过0xD0来递增,我这台显示器没有。 Input Source Value MONITOR_AUTO 0x0 MONITOR_DP1 0xD0 MONITOR_DP2 0xD1 MONITOR_DP3 0xD2 MONITOR_USB_C 0xD2 MONITOR_HDMI1 0x90 MONITOR_HDMI2 0x91 英伟达显卡可以通过NVapi-write-value-to-monitor项目来执行输入源切换。 你只需要修改两个参数,第一个参数0来选择显示器的序号,第二个参数是显示器的输入源(这里是切换到HDMI1,你要修改成自己想切换的输入源,看上面代码)。后面的0xF4 0x50不能动。我的是AMD显卡,具体显示器序号和他功能可以去项目里看作者的说明。 writeValueToDisplay.exe 0 0x90 0xF4 0x50 ADM显示可以通过amdddc-windows项目来执行输入源切换。可以执行文件在issue中找到,作者上传的txt文件,下载下来修改后缀exe即可。 先通过detect命令来查看显示器位置: amdddc-windows.exe detect 我这里适配器索引5,LG显示器是0,要切换的端口DP1 0xD0。你只用修改最后三个参数。下面通过命令来切换输入源到DP1接口: amdddc-windows.exe --i2c-source-addr 0x50 setvcp 5 0 0xD0 intel可以看看这个issue MAC OS mac os可以使用BetterDisplay或者m1ddc来控制,同一个作者。m1ddc我在M4 pro上使用过了没用,不管是不是LG显示器都无法切换,没有做过多研究。 BetterDisplay没有问题,但是发现了一个坑。如果使用扩展坞带的视频接口,那么大概率是残血DDC/CI,或者干脆不支持的。网上资料说是由于usb占用了两个引脚,导致功能残缺。我这边是发现不能切换,但可以调亮度和声音,这还是另一台支持DDC/CI切换输入源的显示上测试的。所以要转视频接口建议买质量好的type-C直接转HDMP或者DP,不要附带其他扩展接口。LG用HDMI直连所有功能都正常。 BetterDisplayLG显示器输入源:DisplayPort 1: 208, DisplayPort 2: 209, HDMI 1: 144, HDMI 2: 145, USB-C / DP 3: 210。CLI文档可以看文档。 显示器设备名称 UUID等信息去APP中可以看到,命令行的话看文档找找。 除了namelike,还有name uuid都可以指定显示器,ddcAlt就是输入源端口代码了。非LG显示器切换去掉两个参数Alt字母就好了--ddc=15 --vcp=inputSelect。 /Applications/BetterDisplay.app/Contents/MacOS/BetterDisplay set --namelike=ABC --ddcAlt=208 --vcp=inputSelectAlt 如果安装了betterdisplaycli可以简化命令,但是BetterDisplay不仅要装,还要启动,否则不行: betterdisplaycli set --namelike=ABC --ddcAlt=0x91 --vcp=inputSelectAlt Linux 我就是ddcutil的issues中找到windows切换LG输入源的,没有Linux需求,没有尝试,命令行参数对着上面的改。 -d就是显示器顺序号,x0090就是输入源端口代码,其他不动。 ddcutil -d 1 setvcp xF4 x0090 --i2c-source-addr=x50 --noverify 顺便把DDL/CI代码也贴一下好了: Input Source Value VGA-1 1 VGA-2 2 DVI-1 3 DVI-2 4 Composite video 1 5 Composite video 2 6 S-Video-1 7 S-Video-2 8 Tuner-1 9 Tuner-2 10 Tuner-3 11 Component video (YPrPb/YCrCb) 1 12 Component video (YPrPb/YCrCb) 2 13 Component video (YPrPb/YCrCb) 3 14 DisplayPort-1 15 DisplayPort-2 16 HDMI-1 17 HDMI-2 18 USB-C 27 DDC/CL切换用winddcutil或者ControlMyMonitor都行。 winddcutil查看显示2的60 输入源可能值,ControlMyMonitor有时候不准。 .\winddcutil.exe capabilities 2 (prot(monitor)type(LCD)model(U2790PQU)cmds(01 02 03 07 0C E3 F3)vcp(02 04 05 08 0C 10 12 14(01 05 06 08 0B) 16 18 1A 52 60(0F 11 12 ) 86(01 02 05 0B 0C 0D 0E 0F 10 11 12 13 14) AC AE B2 B6 C6 C8 CA CC(01 02 03 04 05 06 07 09 0A 0B 0D 0E 12 14 16 1E) D6(01 04 05) DC(00 0B 0C 0D 0E 0F 10) DF ED FF)mswhql(1)asset_eep(40)mccs_ver(2.2)) 60(0F 11 12 ) 代表十进制15 17 18,对应DP1、HDMI1、HDMI2 DDC/CI切换就要简单些,setvcp和/SetValue后面分别是 显示器、输入源切换代码不变、显示器输入源端口,可以看上面DDL/CI代码来尝试切换。 .\ControlMyMonitor.exe /SetValue "
\
.\DISPLAY2\Monitor0" 60 17 或 .\winddcutil.exe setvcp 1 0x60 17 结语 好了,差不多就这么多,看起来不复杂,但是找资料确实花了我好几个小时。 下面我就要开始写代码通过USB切换器来同时控制显示器切换了。目前已经在windows上成功,另一个系统还在路上。等都到齐了我再来多测测,到时候再分享出来! 2025-03-04 切换搞定了,效果不错,通过USB扩展坞代替KVM切换显示器输入源
2025年03月01日
145 阅读
0 评论
0 点赞