Skip to content

Instantly share code, notes, and snippets.

@jaseg
Last active December 2, 2024 19:01
Show Gist options
  • Save jaseg/657e8ecca3267c0d82ec85d40f423caa to your computer and use it in GitHub Desktop.
Save jaseg/657e8ecca3267c0d82ec85d40f423caa to your computer and use it in GitHub Desktop.
Basic test of python-mpv mpv render context mapping used with GTK
#!/usr/bin/env python3
import ctypes
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
gi.require_version('GL', '1.0')
from OpenGL import GL, GLX
from mpv import MPV, MpvRenderContext, OpenGlCbGetProcAddrFn
def get_process_address(_, name):
address = GLX.glXGetProcAddress(name.decode("utf-8"))
return ctypes.cast(address, ctypes.c_void_p).value
class MainClass(Gtk.Window):
def __init__(self, media):
super(MainClass, self).__init__()
self.media = media
self.set_default_size(600, 400)
self.connect("destroy", self.on_destroy)
frame = Gtk.Frame()
self.area = OpenGlArea()
self.area.connect("realize", self.play)
frame.add(self.area)
self.add(frame)
self.show_all()
def on_destroy(self, widget, data=None):
Gtk.main_quit()
def play(self, arg1):
self.area.play(self.media)
class OpenGlArea(Gtk.GLArea):
def __init__(self, **properties):
super().__init__(**properties)
self._proc_addr_wrapper = OpenGlCbGetProcAddrFn(get_process_address)
self.ctx = None
self.mpv = MPV() # log_handler=print, loglevel='debug')
self.connect("realize", self.on_realize)
self.connect("render", self.on_render)
self.connect("unrealize", self.on_unrealize)
def on_realize(self, area):
print('\033[91mon_realize called\033[0m')
self.make_current()
self.ctx = MpvRenderContext(self.mpv, 'opengl',
opengl_init_params={'get_proc_address': self._proc_addr_wrapper})
self.ctx.update_cb = self.wrapped_c_render_func
def on_unrealize(self, arg):
print('\033[91munrealize called\033[0m')
self.ctx.free()
self.mpv.terminate()
def wrapped_c_render_func(self):
print('\033[91mwrapped_c_render_func called\033[0m')
GLib.idle_add(self.call_frame_ready, None, GLib.PRIORITY_HIGH)
def call_frame_ready(self, *args):
print('\033[91mcall_frame_ready called\033[0m')
if self.ctx.update():
self.queue_render()
def on_render(self, arg1, arg2):
print('\033[91mon_render called\033[0m')
if self.ctx:
factor = self.get_scale_factor()
rect = self.get_allocated_size()[0]
width = rect.width * factor
height = rect.height * factor
fbo = GL.glGetIntegerv(GL.GL_DRAW_FRAMEBUFFER_BINDING)
self.ctx.render(flip_y=True, opengl_fbo={'w': width, 'h': height, 'fbo': fbo})
return True
return False
def play(self, media):
self.mpv.play(media)
if __name__ == '__main__':
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
application = MainClass(media='test.webm')
Gtk.main()
@JPThiel
Copy link

JPThiel commented Sep 8, 2022

On Ubuntu 22.04.1:
I have the import error :
from mpv import MPV, MpvRenderContext,OpenGlCbGetProcAddrFn
ImportError: cannot import name 'OpenGlCbGetProcAddrFn' from 'mpv' (/home/jp/.local/lib/python3.10/site-packages/mpv.py)

On Ubuntu 20.04, it was OK !!!!

Thanks for your response

@trin94
Copy link

trin94 commented Sep 9, 2022

Please use the MpvGlGetProcAddressFn function instead. The usage is the same. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment