-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add video sync mode #1
Comments
Honestly, I PyUSB should be able to run on windows, so if this can be made to work it'd be an awesome alternative to LG's terrible UltraGear software! |
It's great to hear that this is useful to other people. I have Wireshark USB packet dumps saved from video sync in Windows, so I'll examine those and try to get it implemented tonight. |
I added a 'setVideoSync' command to the CLI. This will switch the monitor into video sync mode, like the set1-4 and setPeaceful/setDynamic command switch into those modes. The LEDs will automatically switch out of video sync mode into a 'disabled' sort of state if you don't feed it data for a few seconds. Setting into another mode will fix it. I haven't fully figured out how the colors are encoded. This is the raw HID data that's being sent - each set of three lines sets the ring to a different configuration. You can copy all three lines into your clipboard and paste them into the CLI to set the configuration. Copy/pasting one line at a time won't work; the timing matters with this. Entering just one or two lines does nothing; all three data packets must be sent for the monitor to update. I'll spend some more time doing more USB sniffing and trying to decipher this. Once that's done it's a matter of taking a X11 screen capture under Python and converting the screen color to this format. A Windows screen capture backend could also be nice to have in the future.
|
As for the color encoding: Do you remember what colors you were displaying? A full white/black/red/green/blue could maybe help to sort this out. I have been fiddeling around with some Tuya LED devices the other day and they use hex-encoded HSV values... |
That seems similar to the colors that the other commands accept. I'll take a further look at this when I have some time. |
Regarding Screen Capture: Why dont use Hyperion Protocol "simply" provide a "Hyperion Server"? Doing that this way, you would cirumvent the whole "grabbing/color extraction" action. Hyperion Project: https://hyperion-project.org/ |
First, thank you very much for making such a great program. Are there currently any updates for multi-monitor video sync? |
No, there's currently no video sync support at all. I haven't had the time or motivation to work on this. I only use static color mode on my monitor. If anyone has a PR for video sync I'm willing to integrate it, but until then video sync probably won't be implemented anytime soon. |
I don't know much about USB communication, but I'll try it if I have time. Thanks again for making a great program. |
I figured out how to send video sync data messages. However, I wasn't able to figure out what algorithm LG is using to provide the checksums in each message. Created issue #7, once that's resolved video sync will be ready. |
Great work @subraizada3 ! I found some old code using pyUSB and switched to hidapi by my own... And I found that you already did that :) I own a LG 38GN950-B and I can confirm that it works as well. However I use MacOs so it forced the usage of hidapi (hid devices access is forbiden using way pyUSB works). Overall I was planing to (wondering if capable) integrate with Prismatic API. Prismatic already provide advanced screen grabbing capabilities OS independent and python wrapper for it's telnet API. Only thing is to figure out how to control each led and stream it to devices. How do you sniff usb commands? I was thinking about VM with Windows with USB passthrough to try this. |
Good to hear that it also works with the 38GN950.
The LG software (both OSC and UltraGear Control Center) won't detect the monitor in a VM with USB passthrough. Not sure why. I booted to a 'real' Windows installation and used Wireshark with USBpcap (included as an option in the Wireshark installer). You can use a filter like:
The exact number (1.17.2) will depend on the topology of your USB bus. When you send commands via the LG software you'll need to see in Wireshark which src/dst it's generating packets to. Then with the filter in place, you can view the packets and look at the "Leftover Capture Data" field which contains the 64-byte HID data.
This is already implemented in lib27gn950.py, you can do Here's a test program which will flash the LED ring to random colors. The issue I'm facing right now is that some combinations of colors cause the monitor to basically 'crash' - it gets stuck on that pattern, then reverts to dynamic mode and stops accepting new commands or new color data. Recovering from that mode requires restarting the monitor with the joystick under the screen. For example, in this test program, it'll strobe between random colors for most of the LEDs in the ring, and use fixed colors for a few of the LEDs. But if you set the 40th LED to always be red (ff0000) then you will experience the freezing behavior. Or if you uncomment the line at the bottom which makes the entire LED ring red ( #!/usr/bin/env python3
import hid
import random
import string
from sys import exit
from time import sleep
from lib27gn950 import *
monitors = find_monitors()
with hid.Device(path=monitors[0]['path']) as dev:
send_command(control_commands['color_dynamic'], dev)
sleep(2)
send_command(control_commands['color_video_sync'], dev)
sleep(0.1)
count = 0
while True:
count += 1
sleep(0.06)
colors = []
for i in range(48):
c = ''.join(random.choices(string.hexdigits[:-6], k=6))
colors.append(c)
colors[ 0] = 'ff0000'
colors[ 5] = 'ff0000'
colors[10] = 'ff0000'
colors[15] = 'ff0000'
colors[30] = 'ff0000'
colors[35] = 'ff0000'
colors[40] = 'ffffff' # if this is red, it fails
colors[41] = 'ff0000'
colors[45] = 'ff0000'
#colors = ['ff0000']*48
#print(colors)
send_video_sync_data(colors, dev) |
I confirm - same behaviour here. I'll try to do some tests to debug this from my point of view. |
Black (#000000) for led #40 also freezes the ring but it gives blue color. However I was able to recover few times without reseting the screen. As last resort it may be needed to find closest safe color and just map problematic ones respectively. Overall I synced it with Prismatic/Lightpack using However I don't like unfinished bussines so we need to investigate why the heck it's so wacky. |
There is some kind of buffer overflow when using extreeme color comopnent values. I observe that problem occurs for different leds with different color components. it's safe to assume that we can't set values below
gives blue
gives green same is with colors[38] (it's a twice of 19)
However when you set base black color as #010101 everything seems to be fine P.S. in addition #!/usr/bin/env python3
from unittest.util import _count_diff_all_purpose
import hid
from rich import print
import random
import string
from sys import exit
from time import sleep
from lib27gn950 import *
monitors = find_monitors()
def rgb_to_hex(rgb):
return '%02x%02x%02x' % rgb
BASE_BLACK = '010101'
with hid.Device(path=monitors[0]['path']) as dev:
send_command(control_commands['color_dynamic'], dev)
sleep(1)
send_command(control_commands['color_video_sync'], dev)
while True:
# quit()
colors = []
colors = ['ffffff']*48
for rgb in range(0,4):
if rgb == 1:
col = 'ff0101'
elif rgb == 2:
col = '01ff01'
elif rgb == 3:
col = '0101ff'
else:
col = 'ffffff'
for bri in range(1,12, 3):
send_command(brightness_commands[bri],dev)
print (":sun: {}".format(bri), end ='\n')
for y in range(0,48):
colors = [BASE_BLACK]*48
colors[y] = col
sleep(0.01)
print ("[#{}]█[/#{}]".format(col,col), end ='')
send_video_sync_data(colors, dev)
print("\n")
print("\n")
colors = [BASE_BLACK]*48
for r in range(1,256,8):
for g in range(1,256,8):
for b in range(1,256,8):
#sleep(0.01)
#print (r,g,b)
colorcheck = rgb_to_hex((r,g,b))
colors[5] = colorcheck
colors[40] = colorcheck
colors[38] = colorcheck
colors[19] = colorcheck
print("[#{}]█[/#{}]".format(colorcheck,colorcheck),end='')
if 255 == b:
print ("\n")
send_video_sync_data(colors, dev)
So, yes. It turns out that we can't turn off any of the leds. Just put them into minimal state. |
Thanks for the help with that, imkebe. I added a patch to the If you set the entire screen to red, USB packet capture does show that the LG software sets the LEDs to [ff0000]*48... but this looks like a 'good enough' workaround, especially since we have limited debug capability in the montior. Now that the library has video sync fully implemented and working, I'm marking this issue as done. Created a new issue for 'implement a video sync GUI.' Also, feel free to submit a pull request for your Prismatic work, if that's something you want to have included in this repository once it's written. |
First - thank you so much for writing this program. It's a big help for me.
I see a TODO mentioning it, but do you have any plans to implement video sync mode? It's unfortunate that I don't have a way to provide this information unless I'm on Windows.
The text was updated successfully, but these errors were encountered: