0

I use the library https://github.com/jaseg/python-mpv to control the mpv player, but when using it together with pyside6, keybindings do not work (player doesn't accept input totally). What am I doing wrong? or is it impossible to use them when embedding in pyside6? (If I run the player with the same arguments without embedding, everything works fine)

import os
os.add_dll_directory(os.getcwd())
import mpv
from PySide6.QtWidgets import *
from PySide6.QtCore import *
mpvfolderpath = f"mpv.net/portable_config/"
import sys
class Test(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.container = QWidget(self)
        self.setCentralWidget(self.container)
        self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
        self.container.setAttribute(Qt.WA_NativeWindow)
        player = mpv.MPV(wid=str(int(self.container.winId())),
                         vo="gpu",  # You may not need this
                         log_handler=print,
                         loglevel='debug',
                         input_default_bindings=True,
                         input_vo_keyboard=True)

        @player.on_key_press('f')
        def my_f_binding():
            print("f работает!")
        player.play('test.mp4')

app = QApplication(sys.argv)

# This is necessary since PyQT stomps over the locale settings needed by libmpv.
# This needs to happen after importing PyQT before creating the first mpv.MPV instance.
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
win = Test()
win.show()
sys.exit(app.exec_())
MRX
  • 5
  • 4
  • To what keybindings are you referring to? Those received by mpv, or the one you're trying to capture with `my_f_binding`? Because that function will probably be garbage collected right after `__init__` returns, so it will never be called. – musicamante Feb 23 '22 at 15:40
  • mpv keybindings and python keybindings (both), but mpv keybindings preferably – MRX Feb 23 '22 at 15:46
  • 1
    Please explain yourself better. *What* of those keybindings don't work? Also, does it change anything if you click on the player window *before* pressing any key? – musicamante Feb 23 '22 at 15:50
  • No, it will not change, the player does not accept input at all if it is located on pyside6, in theory, if you move the mouse in the territory of the player window, the interface should appear, but it does not even appear, although the corresponding flag is specified, the player does not accept input totally. – MRX Feb 23 '22 at 16:40
  • With your code (in PyQt, but I don't think it would change anything with PySide) I get a *separate* mpv window, but I can get proper embedding with `vo='x11'`, but keyboard events are only received when the mouse is hovering the window. Note that according to the documentation, the OSC must be explicitly enabled: `osc=True`. – musicamante Feb 23 '22 at 17:23

1 Answers1

0

If the keyboard is not handled (which, in my tests, only happened when the mouse is not hovering the video), the key events are propagated to the Qt window. This means that we can handle those events in the keyPressEvent() override and then create a proper mpv command, which is already mapped to the keypress() function. Obviously, a reference to the player must exist, so you need to make it an instance attribute.

For standard literal keys, it's usually enough to use the event's text(), but for other keys such as arrows you need to map the event with mpv's key names. Using a dictionary is certainly simpler:

MpvKeys = {
    Qt.Key.Key_Backspace:   'BS', 
    Qt.Key.Key_PageUp:      'PGUP', 
    Qt.Key.Key_PageDown:    'PGDWN', 
    Qt.Key.Key_Home:        'HOME', 
    Qt.Key.Key_End:         'END', 
    Qt.Key.Key_Left:        'LEFT', 
    Qt.Key.Key_Up:          'UP', 
    Qt.Key.Key_Right:       'RIGHT', 
    Qt.Key.Key_Down:        'DOWN', 
    # ...
}

class Test(QMainWindow):
    def __init__(self, parent=None):
        # ...
        self.player = mpv.MPV(...)

    def keyPressEvent(self, event):
        # look up for the key in our mapping, otherwise use the event's text
        key = MpvKeys.get(event.key(), event.text())
        self.player.keypress(key)

Note: in my tests I had to use the vo='x11' flag to have a properly embedded window, and osc=True is also required to use the native OSD.

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • It really works, but mouse events are still not processed, I tried using vo=x11 but got the error "[vo] Video output x11 not found!" (in mpv log), so I use vo=gpu, but it doesn't work. In any case, thanks for the answer, this solved part of the problem, it remains to find out how to make vo=x11 run without problems. – MRX Feb 23 '22 at 18:35
  • @MRX you can do the same with mouse events: just override `mousePressEvent()`, `mouseMoveEvent()`, `mouseReleaseEvent()` and `mouseDoubleClickEvent()` and call [`self.player.mouse(...)`](https://mpv.io/manual/master/#command-interface-[%3Cmode%3E]]). Note that you might want to enable mouse tracking: `self.setMouseTracking(True)`. – musicamante Feb 23 '22 at 18:37
  • This only works when I pinch and move the mouse over the window, otherwise the mouse is simply not tracked, but if mpv not in window mouse normal tracking – MRX Feb 23 '22 at 19:23
  • Even with `mouseTracking` enabled? – musicamante Feb 23 '22 at 19:26
  • yes, self.setMouseTracking(True), and i created issue on mpv github and was answered, windows don't support vo=x11 mode – MRX Feb 23 '22 at 20:18
  • Ok, I just assumed that you were on Linux, which is the native OS of mpv. By the way, for future reference, adding platform details is usually better, especially when using complex systems that use embedded windows and multimedia aspects (also, please try to use proper casing and grammar: "windows don't support" is **very** different than "Windows doesn't support"; it took me a while to understand what you meant). Unfortunately, I cannot help you on that, as I don't have a Windows system on which I can try the code. – musicamante Feb 24 '22 at 00:00
  • I fixed this problem, i dont tracking mouse in container when i put mpv, my bad. – MRX Feb 24 '22 at 14:54