-
-
Save cosven/b313de2acce1b7e15afda263779c0afc to your computer and use it in GitHub Desktop.
# BSD 3-Clause License | |
# | |
# Copyright (c) 2020, Cosven | |
# All rights reserved. | |
# | |
# Redistribution and use in source and binary forms, with or without | |
# modification, are permitted provided that the following conditions are met: | |
# | |
# 1. Redistributions of source code must retain the above copyright notice, this | |
# list of conditions and the following disclaimer. | |
# | |
# 2. Redistributions in binary form must reproduce the above copyright notice, | |
# this list of conditions and the following disclaimer in the documentation | |
# and/or other materials provided with the distribution. | |
# | |
# 3. Neither the name of the copyright holder nor the names of its | |
# contributors may be used to endorse or promote products derived from | |
# this software without specific prior written permission. | |
# | |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
""" | |
Mainly learned from these two example. | |
- https://github.com/ozmartian/vidcutter/blob/793127c521b18f0bab19b67bc42e8da16a667afd/vidcutter/libs/mpvwidget.py | |
- https://github.com/mpv-player/mpv-examples/blob/master/libmpv/qt_opengl/mpvwidget.cpp | |
""" | |
from PyQt5.QtCore import Qt, QMetaObject, pyqtSlot | |
from PyQt5.QtWidgets import QOpenGLWidget, QApplication | |
from PyQt5.QtOpenGL import QGLContext | |
# HELP: currently, we need import GL module,otherwise it will raise seg fault on Linux(Ubuntu 18.04) | |
from OpenGL import GL # noqa | |
from mpv import MPV, _mpv_get_sub_api, _mpv_opengl_cb_set_update_callback, \ | |
_mpv_opengl_cb_init_gl, OpenGlCbGetProcAddrFn, _mpv_opengl_cb_draw, \ | |
_mpv_opengl_cb_report_flip, MpvSubApi, OpenGlCbUpdateFn, _mpv_opengl_cb_uninit_gl | |
def get_proc_addr(_, name): | |
glctx = QGLContext.currentContext() | |
if glctx is None: | |
return 0 | |
addr = int(glctx.getProcAddress(name.decode('utf-8'))) | |
return addr | |
class MpvWidget(QOpenGLWidget): | |
def __init__(self, parent=None): | |
super().__init__(parent=parent) | |
self.mpv = MPV(vo='opengl-cb', ytdl=True) | |
self.mpv_gl = _mpv_get_sub_api(self.mpv.handle, MpvSubApi.MPV_SUB_API_OPENGL_CB) | |
self.on_update_c = OpenGlCbUpdateFn(self.on_update) | |
self.on_update_fake_c = OpenGlCbUpdateFn(self.on_update_fake) | |
self.get_proc_addr_c = OpenGlCbGetProcAddrFn(get_proc_addr) | |
_mpv_opengl_cb_set_update_callback(self.mpv_gl, self.on_update_c, None) | |
self.frameSwapped.connect(self.swapped, Qt.DirectConnection) | |
def initializeGL(self): | |
_mpv_opengl_cb_init_gl(self.mpv_gl, None, self.get_proc_addr_c, None) | |
def paintGL(self): | |
# compatible with HiDPI display | |
ratio = self.windowHandle().devicePixelRatio() | |
w = int(self.width() * ratio) | |
h = int(self.height() * ratio) | |
_mpv_opengl_cb_draw(self.mpv_gl, self.defaultFramebufferObject(), w, -h) | |
@pyqtSlot() | |
def maybe_update(self): | |
if self.window().isMinimized(): | |
self.makeCurrent() | |
self.paintGL() | |
self.context().swapBuffers(self.context().surface()) | |
self.swapped() | |
self.doneCurrent() | |
else: | |
self.update() | |
def on_update(self, ctx=None): | |
# maybe_update method should run on the thread that creates the OpenGLContext, | |
# which in general is the main thread. QMetaObject.invokeMethod can | |
# do this trick. | |
QMetaObject.invokeMethod(self, 'maybe_update') | |
def on_update_fake(self, ctx=None): | |
pass | |
def swapped(self): | |
_mpv_opengl_cb_report_flip(self.mpv_gl, 0) | |
def closeEvent(self, _): | |
self.makeCurrent() | |
if self.mpv_gl: | |
_mpv_opengl_cb_set_update_callback(self.mpv_gl, self.on_update_fake_c, None) | |
_mpv_opengl_cb_uninit_gl(self.mpv_gl) | |
self.mpv.terminate() | |
if __name__ == '__main__': | |
import locale | |
app = QApplication([]) | |
locale.setlocale(locale.LC_NUMERIC, 'C') | |
widget = MpvWidget() | |
widget.show() | |
url = 'data/test.webm' | |
widget.mpv.play(url) | |
app.exec() |
Thanks. :)
Hmpf, just close to 2 years later:
/home/matze/git/python-mpv/tests/OpenGltest.py:68: DeprecationWarning: Backend C api has been deprecated: mpv_get_sub_api self.mpv_gl = _mpv_get_sub_api(self.mpv.handle, MpvSubApi.MPV_SUB_API_OPENGL_CB) /home/matze/git/python-mpv/tests/OpenGltest.py:72: DeprecationWarning: Backend C api has been deprecated: mpv_opengl_cb_set_update_callback _mpv_opengl_cb_set_update_callback(self.mpv_gl, self.on_update_c, None) /home/matze/git/python-mpv/tests/OpenGltest.py:76: DeprecationWarning: Backend C api has been deprecated: mpv_opengl_cb_init_gl _mpv_opengl_cb_init_gl(self.mpv_gl, None, self.get_proc_addr_c, None) /home/matze/git/python-mpv/tests/OpenGltest.py:83: DeprecationWarning: Backend C api has been deprecated: mpv_opengl_cb_draw _mpv_opengl_cb_draw(self.mpv_gl, self.defaultFramebufferObject(), w, -h) /home/matze/git/python-mpv/tests/OpenGltest.py:106: DeprecationWarning: Backend C api has been deprecated: mpv_opengl_cb_report_flip _mpv_opengl_cb_report_flip(self.mpv_gl, 0) /home/matze/git/python-mpv/tests/OpenGltest.py:112: DeprecationWarning: Backend C api has been deprecated: mpv_opengl_cb_uninit_gl _mpv_opengl_cb_uninit_gl(self.mpv_gl)
Anyone a tip? python3-opengl has been installed on Arch linux..
@kanehekili You can take a look at the implement in FeelUOwn project. It use the new render context API.
https://github.com/feeluown/FeelUOwn/blob/master/feeluown/gui/widgets/mpv.py
Done