【问题标题】:libvlc+qwidget handle mouse event on Win64libvlc+qwidget 在 Win64 上处理鼠标事件
【发布时间】:2015-03-31 09:57:21
【问题描述】:

我正在使用 Qt 并使用 libVlc 2.1.5 版进行实时视频流。我想处理 vlc 帧上的鼠标按下事件。但是当我单击 vlc 时,它无法引发鼠标事件。 我试过了

libvlc_video_set_mouse_input(libvlcMediaPlayer,false);

但是它将鼠标隐藏在 vlc 上。 如果有人知道,请帮助我。

谢谢。

【问题讨论】:

  • 在'libvlc_video_set_mouse_input(libvlcMediaPlayer,false);'之前它在控制台和“libvlc_video_set_mouse_input(libvlcMediaPlayer,false);”上显示鼠标信息它没有在控制台上显示任何鼠标信息。
  • 我在 Vlc Web 插件中使用鼠标钩子来解决相同的任务:git.videolan.org/?p=npapi-vlc.git;a=blob;f=common/… - 但它有点复杂。
  • 另一种可能的解决方案是将 QtQuick 与我的 libvlc 包装库一起使用:github.com/RSATom/QmlVlc 您可以查看 WebChimera 插件的鼠标事件处理演示:webchimera.org/demos/mouse_events - 它使用 QmlVlc 库。您可以在gitter.im/RSATom/WebChimera 提出任何相关问题
  • RSATom ,感谢您的回复,但我无法理解您的意思。我尝试了您所说的任何内容但无法理解。我是否需要在我们的课程中添加额外的插件。我正在创建带有 LIBVLC 的基于桌面的应用程序。
  • 好的,让我问你一个问题:你准备好在你的应用程序中使用 QML/QtQuick 了吗?

标签: mouseevent qwidget libvlc win64


【解决方案1】:

您还需要使用 libvlc_video_set_key_input 函数:

libvlc_video_set_mouse_input(media_player, 0);
libvlc_video_set_key_input(media_player, 0);

【讨论】:

    【解决方案2】:

    我在 Ubuntu 16 下使用了 libvlc 2.2.2,并设法通过以下方式在 vlc 视频区域上获取鼠标事件(仅提供与问题相关的代码)。在我的 VideoPlayer 类中,我有成员:

    libvlc_media_player_t* vlcPlayer;
    VideoWidget* widget;
    

    ,其中 VideoWidget 是我的自定义小部件类。在cpp中我设置libvlc_video_set_mouse_input(vlcPlayer, false);,创建widget实例,将它传递给我的用户界面,当调用“播放”视频时,我还将小部件传递给vlc libvlc_media_player_set_xwindow(vlcPlayer, widget->winId());

    我的自定义 VideoWidget 类如下:

    // header
    class VideoWidget : public QFrame
    {
    public:
      VideoWidget(QWidget* parent = Q_NULLPTR);
    
    protected:
      void mousePressEvent(QMouseEvent* event) override;
    };
    
    // cpp
    VideoWidget::VideoWidget(QWidget* parent)
      : QFrame(parent)
    {
    }
    
    void VideoWidget::mousePressEvent(QMouseEvent* event)
    {
      qDebug() << "mouse press";
      QFrame::mousePressEvent(event);
    }
    

    所以想法是通过传递给 vlc 的 QWidget 来捕获鼠标事件。

    【讨论】:

      【解决方案3】:

      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_()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-03
        • 2018-08-15
        • 1970-01-01
        • 1970-01-01
        • 2015-02-06
        • 1970-01-01
        相关资源
        最近更新 更多