首页
留言
动态
归档
推荐
音乐
工具
Search
1
Emby公益服-上万部电影电视剧免费看
67,728 阅读
2
openwrt-docker部署lxk0301京东自动签到脚本
12,971 阅读
3
QuantumultX-京东签到撸京东豆
11,232 阅读
4
LXK0301京东签到脚本-自动提交互助码
9,685 阅读
5
微信-域名被封监测以及自动更换被封域名
9,203 阅读
随便写写
科学上网
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
篇文章
累计收到
595
条评论
首页
栏目
随便写写
科学上网
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 = `[${timestamp}] ${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(`执行错误: ${error}`); // writeLog(`执行错误: ${error}`); // return; } console.log(`输出: ${stdout}`); // writeLog(`执行命令: ${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日
40 阅读
0 评论
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日
90 阅读
0 评论
0 点赞