Windows 上的三种解决方案
方案一:WS_EX_TRANSPARENT
注意:可能不适用于Windows 7 或以下版本。
# Created by BaiJiFeiLong@gmail.com at 2022/2/10 23:31
import vlc
import win32con
import win32gui
from PySide2 import QtWidgets, QtCore
def togglePlaying():
player.get_state() == vlc.State.Ended and player.set_media(player.get_media())
player.get_state() == vlc.State.Playing and player.pause()
player.get_state() != vlc.State.Playing and player.play()
def onVideoOut(event):
hwnd = win32gui.GetWindow(player.get_hwnd(), win32con.GW_CHILD)
exStyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
exStyle |= win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, exStyle)
app = QtWidgets.QApplication()
window = QtWidgets.QMainWindow()
window.setCentralWidget(QtWidgets.QWidget())
window.centralWidget().mousePressEvent = lambda *args: togglePlaying()
window.setWindowFlags(QtCore.Qt.WindowType.WindowCloseButtonHint)
window.resize(854, 480)
window.show()
filename = r"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
player = vlc.MediaPlayer(filename)
player.set_hwnd(window.centralWidget().winId())
player.event_manager().event_attach(vlc.EventType.MediaPlayerVout, onVideoOut)
player.play()
app.exec_()
方案二:低级鼠标挂钩
# Created by BaiJiFeiLong@gmail.com at 2022/2/10 23:31
from ctypes import WINFUNCTYPE, c_int, Structure, cast, POINTER, windll
from ctypes.wintypes import LPARAM, WPARAM, DWORD, PULONG, LONG
import vlc
import win32con
import win32gui
from PySide2 import QtWidgets, QtCore
def genStruct(name="Structure", **kwargs):
return type(name, (Structure,), dict(
_fields_=list(kwargs.items()),
__str__=lambda self: "%s(%s)" % (name, ",".join("%s=%s" % (k, getattr(self, k)) for k in kwargs))
))
@WINFUNCTYPE(LPARAM, c_int, WPARAM, LPARAM)
def hookProc(nCode, wParam, lParam):
msg = cast(lParam, POINTER(HookStruct))[0]
hwnd = win32gui.WindowFromPoint((msg.pt.x, msg.pt.y))
if hwnd in vlcHwnds:
win32gui.PostMessage(widget.winId(), wParam, wParam, (msg.pt.y << 16) + msg.pt.x)
return windll.user32.CallNextHookEx(None, nCode, WPARAM(wParam), LPARAM(lParam))
def togglePlaying():
print("toggle")
player.get_state() == vlc.State.Ended and player.set_media(player.get_media())
player.get_state() == vlc.State.Playing and player.pause()
player.get_state() != vlc.State.Playing and player.play()
def onVideoOut(event):
hwnd1 = win32gui.GetWindow(player.get_hwnd(), win32con.GW_CHILD)
hwnd2 = win32gui.GetWindow(hwnd1, win32con.GW_CHILD)
vlcHwnds.append(hwnd1)
vlcHwnds.append(hwnd2)
print("vlcHwnds", vlcHwnds)
app = QtWidgets.QApplication()
widget = QtWidgets.QWidget()
widget.mouseReleaseEvent = lambda *args: togglePlaying()
window = QtWidgets.QMainWindow()
window.setCentralWidget(widget)
window.setWindowFlags(QtCore.Qt.WindowType.WindowCloseButtonHint)
window.resize(854, 480)
window.show()
vlcHwnds = []
HookStruct = genStruct(
"Hook", pt=genStruct("Point", x=LONG, y=LONG), mouseData=DWORD, flags=DWORD, time=DWORD, dwExtraInfo=PULONG)
msgDict = {v: k for k, v in win32con.__dict__.items() if k.startswith("WM_")}
windll.user32.SetWindowsHookExW(win32con.WH_MOUSE_LL, hookProc, None, 0)
filename = r"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
player = vlc.MediaPlayer(filename)
player.set_hwnd(widget.winId())
player.event_manager().event_attach(vlc.EventType.MediaPlayerVout, onVideoOut)
player.play()
app.exec_()
解决方案三:进程内鼠标钩
# Created by BaiJiFeiLong@gmail.com at 2022/2/10 23:31
from ctypes import WINFUNCTYPE, c_int, Structure, cast, POINTER, windll
from ctypes.wintypes import LPARAM, WPARAM, DWORD, PULONG, LONG, HINSTANCE
import vlc
import win32api
import win32con
import win32gui
from PySide2 import QtWidgets, QtCore
def genStruct(name="Structure", **kwargs):
return type(name, (Structure,), dict(
_fields_=list(kwargs.items()),
__str__=lambda self: "%s(%s)" % (name, ",".join("%s=%s" % (k, getattr(self, k)) for k in kwargs))
))
@WINFUNCTYPE(LPARAM, c_int, WPARAM, LPARAM)
def hookProc(nCode, wParam, lParam):
msg = cast(lParam, POINTER(HookStruct))[0]
win32gui.PostMessage(widget.winId(), wParam, wParam, (msg.pt.y << 16) + msg.pt.x)
return windll.user32.CallNextHookEx(None, nCode, WPARAM(wParam), LPARAM(lParam))
def togglePlaying():
player.get_state() == vlc.State.Ended and player.set_media(player.get_media())
player.get_state() == vlc.State.Playing and player.pause()
player.get_state() != vlc.State.Playing and player.play()
def onVideoOut(event):
hwnd1 = win32gui.GetWindow(player.get_hwnd(), win32con.GW_CHILD)
processId = win32api.GetModuleHandle()
threadId = windll.user32.GetWindowThreadProcessId(hwnd1, None)
windll.user32.SetWindowsHookExW(win32con.WH_MOUSE, hookProc, HINSTANCE(processId), threadId)
app = QtWidgets.QApplication()
window = QtWidgets.QMainWindow()
widget = QtWidgets.QWidget()
widget.mouseReleaseEvent = lambda *args: togglePlaying()
window.setCentralWidget(widget)
window.setWindowFlags(QtCore.Qt.WindowType.WindowCloseButtonHint)
window.resize(854, 480)
window.show()
HookStruct = genStruct(
"Hook", pt=genStruct("Point", x=LONG, y=LONG), mouseData=DWORD, flags=DWORD, time=DWORD, dwExtraInfo=PULONG)
msgDict = {v: k for k, v in win32con.__dict__.items() if k.startswith("WM_")}
filename = r"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
player = vlc.MediaPlayer(filename)
player.set_hwnd(widget.winId())
player.event_manager().event_attach(vlc.EventType.MediaPlayerVout, onVideoOut)
player.play()
app.exec_()