mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-03-06 04:21:40 +01:00
player refactoring
This commit is contained in:
@@ -1,32 +1,37 @@
|
||||
from app.commons import run_task
|
||||
from app.tools import vlc
|
||||
from app.tools.vlc import EventType
|
||||
import sys
|
||||
from app.commons import run_task, log
|
||||
|
||||
|
||||
class Player:
|
||||
_VLC_INSTANCE = None
|
||||
__VLC_INSTANCE = None
|
||||
|
||||
def __init__(self, rewind_callback=None, position_callback=None):
|
||||
self._is_playing = False
|
||||
self._player = self.get_vlc_instance()
|
||||
ev_mgr = self._player.event_manager()
|
||||
def __init__(self, rewind_callback, position_callback):
|
||||
try:
|
||||
from app.tools import vlc
|
||||
from app.tools.vlc import EventType
|
||||
except OSError as e:
|
||||
log("{}: Load library error: {}".format(__class__.__name__, e))
|
||||
else:
|
||||
self._is_playing = False
|
||||
args = "--quiet {}".format("" if sys.platform == "darwin" else "--no-xlib")
|
||||
self._player = vlc.Instance(args).media_player_new()
|
||||
ev_mgr = self._player.event_manager()
|
||||
|
||||
if rewind_callback:
|
||||
# TODO look other EventType options
|
||||
ev_mgr.event_attach(EventType.MediaPlayerBuffering,
|
||||
lambda e, p: rewind_callback(p.get_media().get_duration()),
|
||||
self._player)
|
||||
if position_callback:
|
||||
ev_mgr.event_attach(EventType.MediaPlayerTimeChanged,
|
||||
lambda e, p: position_callback(p.get_time()),
|
||||
self._player)
|
||||
if rewind_callback:
|
||||
# TODO look other EventType options
|
||||
ev_mgr.event_attach(EventType.MediaPlayerBuffering,
|
||||
lambda et, p: rewind_callback(p.get_media().get_duration()),
|
||||
self._player)
|
||||
if position_callback:
|
||||
ev_mgr.event_attach(EventType.MediaPlayerTimeChanged,
|
||||
lambda et, p: position_callback(p.get_time()),
|
||||
self._player)
|
||||
|
||||
@staticmethod
|
||||
def get_vlc_instance():
|
||||
if Player._VLC_INSTANCE:
|
||||
return Player._VLC_INSTANCE
|
||||
_VLC_INSTANCE = vlc.Instance("--quiet --no-xlib").media_player_new()
|
||||
return _VLC_INSTANCE
|
||||
@classmethod
|
||||
def get_instance(cls, rewind_callback=None, position_callback=None):
|
||||
if not cls.__VLC_INSTANCE:
|
||||
cls.__VLC_INSTANCE = Player(rewind_callback, position_callback)
|
||||
return cls.__VLC_INSTANCE
|
||||
|
||||
@run_task
|
||||
def play(self, mrl=None):
|
||||
@@ -57,6 +62,26 @@ class Player:
|
||||
def set_xwindow(self, xid):
|
||||
self._player.set_xwindow(xid)
|
||||
|
||||
def set_nso(self, widget):
|
||||
""" Used on MacOS to set NSObject.
|
||||
|
||||
Based on gtkvlc.py[get_window_pointer] example from here:
|
||||
https://github.com/oaubert/python-vlc/tree/master/examples
|
||||
"""
|
||||
try:
|
||||
import ctypes
|
||||
g_dll = ctypes.CDLL("libgdk-3.0.dylib")
|
||||
except OSError as e:
|
||||
log("{}: Load library error: {}".format(__class__.__name__, e))
|
||||
else:
|
||||
get_nsview = g_dll.gdk_quartz_window_get_nsview
|
||||
get_nsview.restype, get_nsview.argtypes = ctypes.c_void_p, [ctypes.c_void_p]
|
||||
ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
|
||||
ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object]
|
||||
# Get the C void* pointer to the window
|
||||
pointer = ctypes.pythonapi.PyCapsule_GetPointer(widget.get_window().__gpointer__, None)
|
||||
self._player.set_nsobject(get_nsview(pointer))
|
||||
|
||||
def set_mrl(self, mrl):
|
||||
self._player.set_mrl(mrl)
|
||||
|
||||
|
||||
@@ -1554,8 +1554,8 @@ class Application(Gtk.Application):
|
||||
def play(self, url):
|
||||
if not self._player:
|
||||
try:
|
||||
self._player = Player(rewind_callback=self.on_player_duration_changed,
|
||||
position_callback=self.on_player_time_changed)
|
||||
self._player = Player.get_instance(rewind_callback=self.on_player_duration_changed,
|
||||
position_callback=self.on_player_time_changed)
|
||||
except (NameError, AttributeError):
|
||||
self.show_error_dialog("No VLC is found. Check that it is installed!")
|
||||
return
|
||||
@@ -1592,8 +1592,7 @@ class Application(Gtk.Application):
|
||||
|
||||
def on_player_close(self, item=None):
|
||||
if self._player:
|
||||
self._player.release()
|
||||
self._player = None
|
||||
self._player.stop()
|
||||
GLib.idle_add(self._player_box.set_visible, False, priority=GLib.PRIORITY_LOW)
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
@@ -1615,8 +1614,12 @@ class Application(Gtk.Application):
|
||||
return "{}{:02d}:{:02d}".format(str(h) + ":" if h else "", m, s)
|
||||
|
||||
def on_drawing_area_realize(self, widget):
|
||||
self._drawing_area_xid = widget.get_window().get_xid()
|
||||
self._player.set_xwindow(self._drawing_area_xid)
|
||||
if sys.platform == "darwin":
|
||||
self._player.set_nso(widget)
|
||||
else:
|
||||
self._drawing_area_xid = widget.get_window().get_xid()
|
||||
print(self._drawing_area_xid)
|
||||
self._player.set_xwindow(self._drawing_area_xid)
|
||||
|
||||
def on_player_drawing_area_draw(self, widget, cr):
|
||||
""" Used for black background drawing in the player drawing area.
|
||||
|
||||
Reference in New Issue
Block a user