""" Opengl related Code adapted from https://gist.github.com/cosven/b313de2acce1b7e15afda263779c0afc """ import os import re import time import sys import platform import locale import itertools import urllib.parse import hashlib from functools import partial from collections import namedtuple from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt, QMetaObject, pyqtSlot, pyqtSignal from PyQt5.QtWidgets import QOpenGLWidget, QApplication from PyQt5.QtOpenGL import QGLContext from OpenGL import GL from mpv_bak 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 try: import mpv except Exception as err: print(err) print("only opengl-cb api is available") from player import PlayerWidget, KeyBoardShortcuts def get_proc_addr(_, name): glctx = QGLContext.currentContext() if glctx is None: return 0 addr = int(glctx.getProcAddress(name.decode('utf-8'))) return addr if sys.platform == 'win32': from PyQt5.QtOpenGL import QGLContext elif sys.platform == 'darwin': from OpenGL.GLUT import glutGetProcAddress else: from OpenGL.platform import PLATFORM from ctypes import c_char_p, c_void_p def getProcAddress(proc: bytes) -> int: if sys.platform == 'win32': _ctx = QGLContext.currentContext() if _ctx is None: return 0 _gpa = (_ctx.getProcAddress, proc.decode()) elif sys.platform == 'darwin': _gpa = (glutGetProcAddress, proc) else: _getProcAddress = PLATFORM.getExtensionProcedure _getProcAddress.argtypes = [c_char_p] _getProcAddress.restype = c_void_p _gpa = (_getProcAddress, proc) return _gpa[0](_gpa[1]).__int__() class QProcessExtra(QtCore.QProcess): def __init__(self, parent=None, ui=None, logr=None, tmp=None): super(QProcessExtra, self).__init__(parent) self.ui = ui def filter_command(self, cmd): file_path = re.search('"(?P<file>(.?)*)"', cmd).group('file') command = re.sub('"(.?)*"', "", cmd) arr = command.split() arr.insert(1, file_path) try: self.ui.tab_5.mpv.command(*arr) except Exception as err: print(err) return file_path def write(self, cmd): if self.ui.player_val == "libmpv" and self.ui.tab_5.mpv.get_property("idle-active") is False: print(cmd) cmd = str(cmd, "utf-8").strip() cmd_arr = cmd.split() print(cmd_arr) show_duration = None if cmd_arr[0] == "show-text": cmd_tail = cmd.split(" ", 1)[-1] if cmd_tail.startswith('"'): cmd = cmd.replace('"', "") elif cmd_tail.startswith("'"): cmd = cmd.replace("'", '') if "filename" in cmd_tail: filename = self.ui.tab_5.mpv.get_property('filename') cmd_tail = "filename: {}".format(filename) elif "chapter" in cmd_tail: try: chapter = self.ui.tab_5.mpv.get_property('chapter') total = self.ui.tab_5.mpv.get_property('chapters') meta = self.ui.tab_5.mpv.get_property('chapter-metadata') if meta: title = meta.get("TITLE") else: title = None if title: cmd_tail = "{} / {}".format(title, total) else: cmd_tail = "Chapter: {} / {}".format(chapter, total) except Exception as err: cmd_tail = "Chapters not available" elif "${aid}" in cmd_tail: aid = self.ui.tab_5.mpv.get_property('aid') cmd_tail = self.ui.tab_5.get_track_property(aid, "audio") if cmd_tail is None: cmd_tail = "Audio: Disabled" elif "${info}" in cmd_tail: cmd_tail = "Info" elif "${sid}" in cmd_tail: sid = self.ui.tab_5.mpv.get_property('sid') cmd_tail = self.ui.tab_5.get_track_property(sid, "sub") if cmd_tail is None: cmd_tail = "Subtitle: Disabled" elif "${sub-delay}" in cmd_tail: sub_delay = self.ui.tab_5.mpv.get_property('sub-delay') if sub_delay: sub_delay = "{} ms".format(int(sub_delay * 1000)) cmd_tail = "Sub delay: {}".format(sub_delay) elif "${audio-delay}" in cmd_tail: audio_delay = self.ui.tab_5.mpv.get_property('audio-delay') if audio_delay: audio_delay = "{} ms".format(int(audio_delay * 1000)) cmd_tail = "A-V delay: {}".format(audio_delay) elif 'osd-sym-cc' in cmd: print(cmd) if "pause" in cmd or "2000" in cmd: try: time_pos = self.ui.tab_5.mpv.get_property('time-pos') except Exception as err: time_pos = 0 display_string = self.ui.tab_5.display_play_pause_string(time_pos) if self.ui.tab_5.mpv_api == "opengl-render": cmd_tail = self.ui.tab_5.mpv.get_property('osd-sym-cc') + " " + display_string else: cmd_tail = self.ui.tab_5.mpv.osd_sym_cc + b" " + bytes(display_string, "utf-8") else: cmd_list = cmd.split() cmd_list = cmd_list[1:] if self.ui.tab_5.mpv_api == "opengl-render": cmd_tail = self.ui.tab_5.mpv.get_property('osd-sym-cc') + ' ' + ''.join(cmd_list) else: cmd_tail = self.ui.tab_5.mpv.get_property('osd-sym-cc') + b'' + bytes(''.join(cmd_list), "utf-8") if cmd_tail: self.ui.tab_5.mpv.command("show-text", cmd_tail) elif cmd_arr[0] == "sub-add": sub_file = self.filter_command(cmd) self.ui.tab_5.mpv.command("show-text", "Adding-subtitle: {}".format(sub_file), 2000) elif cmd_arr[0] == "loadfile": file_path = self.filter_command(cmd) self.ui.tab_5.mpv.command("show-text", "loading: {}".format(file_path), 2000) else: try: if cmd_arr[0] in ["stop", "quit"]: self.ui.quit_now = True if "set pause" in cmd or "cycle pause" in cmd: try: time_pos = self.ui.tab_5.mpv.get_property('time-pos') except Exception as err: time_pos = 0 self.ui.tab_5.mpv.command(*cmd_arr) display_string = self.ui.tab_5.display_play_pause_string(time_pos) if self.ui.tab_5.mpv_api == "opengl-render": cmd_tail = self.ui.tab_5.mpv.get_property('osd-sym-cc') + " " + display_string else: cmd_tail = self.ui.tab_5.mpv.osd_sym_cc + b" " + bytes(display_string, "utf-8") self.ui.tab_5.mpv.command("show-text", cmd_tail, 2000) elif cmd_arr[0] == "set": cmd_name = cmd_arr[1] cmd_val = cmd_arr[-1].replace('"', '') self.ui.tab_5.mpv.set_property(cmd_name, cmd_val) else: self.ui.tab_5.mpv.command(*cmd_arr) except Exception as e: print(e) self.ui.tab_5.mpv.command("show-text", "not found: {}, {}".format(cmd, e), 5000) elif self.ui.player_val == "libmpv" and self.ui.tab_5.mpv.get_property("idle-active") is True: print("nothing is playing") else: super(QProcessExtra, self).write(cmd) class KeyT(QtCore.QThread): mpv_cmd = pyqtSignal(list) def __init__(self, ui, event, cmd): self.ui = ui QtCore.QThread.__init__(self) self.event = event self.cmd = cmd def __del__(self): self.wait() def run(self): if self.event is not None and self.cmd: try: self.ui.tab_5.mpv.command(*self.cmd) except Exception as err: print(err) class PlayerStatusObserver(QtCore.QThread): def __init__(self, ui): self.ui = ui QtCore.QThread.__init__(self) self.show_status = False self.remove_external_files = False def __del__(self): self.wait() def core_observer_status(self): idle_active = self.ui.tab_5.mpv.get_property('idle-active') core_idle = self.ui.tab_5.mpv.get_property('core-idle') if idle_active in [False, 'no'] and core_idle in [True, 'yes']: self.ui.mpvplayer_val.write(b'show-text osd-sym-cc pause-string') def run(self): while True: if self.show_status: self.core_observer_status() if self.remove_external_files: try: self.ui.tab_5.mpv.command("sub-remove") self.ui.logger.info('removing external subtitles') except Exception as err: self.ui.logger.debug('no external subtitle loaded') try: self.ui.tab_5.mpv.command("audio-remove") self.ui.logger.info('removing external audio') except Exception as err: self.ui.logger.debug('no external audio loaded') self.remove_external_files = False time.sleep(1) class ExecCommand(QtCore.QThread): def __init__(self, ui, func_list): self.ui = ui QtCore.QThread.__init__(self) self.func_list = func_list.copy() def __del__(self): self.wait() def run(self): if self.func_list: try: sub_gather_func, try_sub_func = self.func_list sub_arr, sub_lang = sub_gather_func() try_sub_func(sub_arr.copy(), sub_lang.copy()) except Exception as err: print(err) class InitAgainThread(QtCore.QThread): mpv_cmd = pyqtSignal(list) def __init__(self, uiw, me): global ui self.ui = uiw ui = uiw QtCore.QThread.__init__(self) self.me = me self.mpv_cmd.connect(mpv_cmd_direct) def __del__(self): self.wait() def run(self): if self.me.mpv_api == "opengl-cb": _mpv_opengl_cb_uninit_gl(self.me.mpv_gl) else: if self.me.mpv_gl: self.me.mpv_gl.close() path = self.me.mpv.get_property("path") aud = None self.me.quit_watch_later('quit-watch-later', True) if path and not os.path.exists(path): aud = self.me.get_external_audio_file() func = partial(self.me.initializeGL) self.mpv_cmd.emit([func, self.me.mpv_api, self.me, path, aud]) @pyqtSlot(list) def mpv_cmd_direct(cmd): global ui func, api, me, path, aud = cmd site = ui.get_parameters_value(st='site')['site'] if api == "opengl-cb": func() try: pls_pos = me.mpv.get_property("playlist-pos") if (path and os.path.exists(path) and site.lower() in ["video", "music", "none", "myserver"]): me.mpv.set_property("playlist-pos", pls_pos) else: if aud: me.audio = aud me.mpv.command("loadfile", path) me.mpv.set_property('loop-playlist', 'no') me.mpv.set_property('loop-file', 'no') except Exception as err: print(err) def mpv_log(level, component, msg): print('[{}] {}: {}'.format(level, component, msg)) class MpvOpenglWidget(QOpenGLWidget): def __init__(self, parent=None, ui=None, logr=None, tmp=None, mpv_api=None, app=None): global gui, MainWindow, screen_width, screen_height, logger super().__init__(parent) gui = ui self.ui = ui MainWindow = parent logger = logr self.app = app if mpv_api in ["opengl-cb", "opengl-render"]: self.mpv_api = mpv_api else: self.mpv_api = "opengl-cb" logger.debug("using {}".format(self.mpv_api)) self.args_dict = {'vo':'libmpv', 'ytdl':True, 'loop_playlist':'inf', 'idle':True, 'audio-display': 'attachment', 'osd_duration': 4000, 'osd_font_size': 25, 'cache': 'auto', 'cache-secs': 120} if platform.system().lower() == "darwin": self.args_dict.update({"ao":"coreaudio"}) elif os.name == "posix": if hasattr(self.ui, "desktop_session") and self.ui.desktop_session == "lxde-pi": self.args_dict.update({"ao":"alsa"}) else: self.args_dict.update({"ao":"pulse"}) elif os.name == "nt": self.args_dict.update({"ao":"wasapi"}) self.default_args = self.args_dict.copy() if gui.mpvplayer_string_list and gui.use_custom_config_file: self.create_args_dict() elif not gui.use_custom_config_file: self.parse_mpv_config_file() locale.setlocale(locale.LC_NUMERIC, 'C') self.track_list = None self.playlist_backup = False self.mpv_gl = None if self.mpv_api == "opengl-render": self.init_opengl_render() else: self.init_opengl_cb() self.frameSwapped.connect(self.swapped, Qt.DirectConnection) self.arrow_timer = QtCore.QTimer() self.arrow_timer.timeout.connect(self.arrow_hide) self.arrow_timer.setSingleShot(True) self.pause_timer = QtCore.QTimer() self.pause_timer.timeout.connect(self.pause_unpause) self.pause_timer.setSingleShot(True) self.fs_timer = QtCore.QTimer() self.fs_timer.timeout.connect(self.toggle_fullscreen_mode) self.fs_timer.setSingleShot(True) self.mx_timer = QtCore.QTimer() self.mx_timer.timeout.connect(MainWindow.showMaximized) self.mx_timer.setSingleShot(True) self.fs_timer_now = QtCore.QTimer() self.fs_timer_now.timeout.connect(self.only_fs_tab) self.fs_timer_now.setSingleShot(True) self.player_val = "libmpv" screen_width = gui.screen_size[0] screen_height = gui.screen_size[1] self.custom_keys = {} self.event_dict = {'ctrl':False, 'alt':False, 'shift':False} self.key_map = KeyBoardShortcuts(gui, self) self.mpv_default = self.key_map.get_default_keys() self.mpv_custom, self.input_conf_list = self.key_map.get_custom_keys(gui.mpv_input_conf) self.custom_keys, _ = self.key_map.get_custom_keys(gui.custom_key_file) self.function_map = self.key_map.function_map() self.non_alphanumeric_keys = self.key_map.non_alphanumeric_keys() self.alphanumeric_keys = self.key_map.alphanumeric_keys() if self.custom_keys: self.mpv_default = self.custom_keys.copy() self.shift_keys = [ '?', '>', '<', '"', ':', '}', '{', '|', '+', '_', 'sharp', ')', '(', '*', '&', '^', '%', '$', '#', '#', '@', '!', '~' ] self.aboutToResize.connect(self.resized) self.aboutToCompose.connect(self.compose) self.audio = None self.subtitle = None self.ratio = None self.dim = None self.chapter_list = None self.prefetch_url = None self.window_title_set = False self.mpv_queue_tuple = None self.mpv_default_modified = {} for key, value in self.mpv_default.items(): if "seek" in value: self.mpv_default_modified.update({key:value.split()}) self.modifiers = set([QtCore.Qt.ShiftModifier, QtCore.Qt.ControlModifier, QtCore.Qt.AltModifier]) self.total_keys = {**self.alphanumeric_keys, **self.non_alphanumeric_keys} self.seek_now = False self.aspect_map = {'0':'Original', '1':'16:9', '2':'4:3', '3':'2.35:1', '4':'Disabled'} self.player_volume = None self.initial_volume_set = False self.mpv_reinit = False self.key_thread = KeyT(self.ui, None, None) self.init_again_thread = InitAgainThread(self.ui, self) self.key_thread.start() self.player_observer_thread = PlayerStatusObserver(self.ui) self.player_observer_thread.start() self.sub_id = -1 self.audio_id = -1 self.dpr = 1.0 self.fake_mousemove_event = ("libmpv", False) self.playing_queue = False self.exec_thread = ExecCommand(self.ui, []) self.started = False self.file_size = 0 self.first_play = True self.stop_msg = None self.pointer_moved = False def init_opengl_cb(self): try: self.mpv = MPV(log_handler=mpv_log, **self.args_dict) except Exception as err: logger.error("\nSome wrong config option. Restoring default\n") self.mpv = MPV(**self.default_args) self.mpv.observe_property("time-pos", self.time_observer) self.mpv.observe_property("eof-reached", self.eof_observer) self.mpv.observe_property("idle-active", self.idle_observer) self.mpv.observe_property("duration", self.time_duration) self.mpv.observe_property("sub", self.sub_changed) self.mpv.observe_property("audio", self.audio_changed) self.mpv.observe_property("seeking", self.player_seeking) self.mpv.observe_property("ao-volume", self.volume_observer) self.mpv.observe_property("quit-watch-later", self.quit_watch_later) self.mpv.observe_property("playback-abort", self.playback_abort_observer) self.mpv.observe_property("playlist-pos", self.playlist_position_observer) self.mpv.observe_property("core-idle", self.core_observer) self.init_mpv_opengl_cb() def init_mpv_opengl_cb(self): 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) def init_opengl_render(self): self.mpv = mpv.Context() self.mpv.initialize() self.mpv.set_log_level('no') for key, value in self.args_dict.items(): key = key.replace('_', '-') if isinstance(value, bool): value = 'yes' if value else 'no' try: self.mpv.set_option(key, value) except Exception as err: logger.error("Error in setting property: {} => {}, Correct config options.".format(key, value)) if key == "msg-level": try: if "=" in value: self.mpv.set_log_level(value.rsplit('=', 1)[-1]) else: self.mpv.set_log_level(value) except Exception as err: logger.error("Error setting log-level") self.mpv.observe_property('time-pos') self.mpv.observe_property('duration') self.mpv.observe_property('eof-reached') self.mpv.observe_property('idle-active') self.mpv.observe_property('sub') self.mpv.observe_property('audio') self.mpv.observe_property('seeking') self.mpv.observe_property('ao-volume') self.mpv.observe_property('quit-watch-later') self.mpv.observe_property('playback-abort') self.mpv.observe_property('playlist-pos') self.mpv.observe_property('core-idle') self.observer_map = { 'time-pos': self.time_observer, 'eof-reached': self.eof_observer, 'idle-active': self.idle_observer, 'duration': self.time_duration, 'sub': self.sub_changed, 'audio': self.audio_changed, 'seeking': self.player_seeking, 'ao-volume': self.volume_observer, 'quit-watch-later': self.quit_watch_later, 'playback-abort': self.playback_abort_observer, 'playlist-pos': self.playlist_position_observer, 'core-idle': self.core_observer } self.mpv.set_wakeup_callback(self.eventHandler) def eventHandler(self): while self.mpv: try: event = self.mpv.wait_event(.01) if event.id in {mpv.Events.none, mpv.Events.shutdown}: break elif event.id == mpv.Events.log_message: event_log = event.data log_msg = "[{}] {}-{}".format(event_log.level, event_log.prefix, event_log.text.strip()) print(log_msg) elif event.id == mpv.Events.property_change: event_prop = event.data observer_function = self.observer_map.get(event_prop.name) if observer_function: observer_function(event_prop.name, event_prop.data) except mpv.MPVError as err: logger.error(err) def initializeGL(self): if self.mpv_api == "opengl-render": try: self.mpv_gl = mpv.OpenGLRenderContext(self.mpv, getProcAddress) self.mpv_gl.set_update_callback(self.maybe_update) except Exception as err: logger.error(err) else: _mpv_opengl_cb_init_gl(self.mpv_gl, None, self.get_proc_addr_c, None) def paintGL(self): w = int(self.width()* self.dpr) h = int(self.height()* self.dpr) if self.mpv_api == "opengl-render": func = partial(self.mpv_gl.render, opengl_fbo={"w": w, "h": h, "fbo": self.defaultFramebufferObject()}, flip_y=True) else: func = partial(_mpv_opengl_cb_draw, self.mpv_gl, self.defaultFramebufferObject(), w, -h) func() @pyqtSlot() def maybe_update(self): if (self.isMinimized() or self.isHidden()) and self.mpv_api == "opengl-cb": self.makeCurrent() self.paintGL() self.context().swapBuffers(self.context().surface()) self.swapped() self.doneCurrent() else: self.update() def on_update(self, ctx=None): QMetaObject.invokeMethod(self, 'maybe_update') def on_update_fake(self, ctx=None): pass def swapped(self): if self.mpv_api == "opengl-render": if self.mpv_gl: self.mpv_gl.report_swap() else: _mpv_opengl_cb_report_flip(self.mpv_gl, 0) def closeEvent(self, _): if self.mpv_api == "opengl-render": if self.mpv_gl: self.mpv_gl.close() else: 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() def init_mpv_again(self): if self.mpv_api in ["opengl-cb", "opengl-render"] and platform.system().lower() in ["linux", "windows"]: if not self.init_again_thread.isRunning(): self.init_again_thread = InitAgainThread(self.ui, self) self.init_again_thread.start() else: pass def only_fs_tab(self): self.setMinimumWidth(MainWindow.width()) self.setMinimumHeight(MainWindow.height()) def parse_mpv_config_file(self, file_path=None): self.setup_args_from_gui() if file_path is None or not os.path.exists(file_path): file_path = os.path.join(os.path.expanduser("~"), ".config/mpv/config") if os.path.exists(file_path): txt = open(file_path).read() if txt: txt_list = txt.split('\n') else: txt_list = [] for line in txt_list: line = line.strip() if line and not line.startswith('#'): line = re.sub('#[^\n]*', '', line) if '=' in line: key, value = line.split('=', 1) else: key = line value = "yes" value = self.sanitize_values(value) key = key.replace("-", "_") logger.info((key, value)) self.args_dict.update({key:value}) self.args_dict.update({"vo":"libmpv"}) def sanitize_values(self, value): if isinstance(value, str) and value.startswith('"'): value = value[1:] if value.endswith('"'): value = value[:-1] if isinstance(value, str) and value.startswith("'"): value = value[1:] if value.endswith("'"): value = value[:-1] return value def setup_args_from_gui(self): self.args_dict.update({'screenshot-directory': gui.screenshot_directory}) if gui.gsbc_dict: for key, value in gui.gsbc_dict.items(): self.args_dict.update({key:value}) if gui.subtitle_dict and gui.apply_subtitle_settings: for key, value in gui.subtitle_dict.items(): self.args_dict.update({key:value}) elif gui.subtitle_dict and not gui.apply_subtitle_settings: scale = gui.subtitle_dict.get('sub-scale') if scale: self.args_dict.update({'sub-scale': scale}) if gui.gapless_playback or gui.gapless_network_stream: self.args_dict.update({'gapless-audio':True}) self.args_dict.update({'prefetch-playlist': True}) if isinstance(gui.cache_pause_seconds, int) and gui.cache_pause_seconds > 0: self.args_dict.update({'cache-pause': True}) self.args_dict.update({'cache-pause-wait': gui.cache_pause_seconds}) def create_args_dict(self): self.setup_args_from_gui() for param in gui.mpvplayer_string_list: if "=" in param: k, v = param.split("=", 1) else: k = param v = True if k.startswith('--'): k = k[2:] k = k.replace("-", "_") v = self.sanitize_values(v) self.args_dict.update({k:v}) self.args_dict.update({"vo":"libmpv"}) def set_mpvplayer(self, player=None, mpvplayer=None): if mpvplayer: self.mpvplayer = mpvplayer else: self.mpvplayer = self.ui.mpvplayer_val if player: self.player_val = player else: self.player_val = self.ui.player_val def pause_unpause(self, status=None): if status == "pause": self.mpv.command("set", "pause", "yes") else: self.mpv.command("set", "pause", "no") def compose(self): pass def resized(self): self.setFocus() if self.ui.device_pixel_ratio == 0: self.dpr = self.devicePixelRatio() else: self.dpr = self.ui.device_pixel_ratio logger.debug('Device Pixel Ratio: {}'.format(self.dpr)) def arrow_hide(self): if gui.player_val in ['mpv', 'mplayer', 'libmpv']: if self.hasFocus(): self.setCursor(QtGui.QCursor(QtCore.Qt.BlankCursor)) logger.debug('player has focus') #QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.BlankCursor); else: logger.debug('player not focussed') if (self.ui.fullscreen_video and self.hasFocus() and self.ui.tab_6.isHidden() and self.ui.list2.isHidden() and self.ui.tab_2.isHidden()): self.ui.frame1.hide() def get_track_property(self, id_val, id_type): txt = None if self.track_list: for i in self.mpv.get_property("track-list"): idval = i.get("id") idtype = i.get("type") if idval == id_val and idtype == id_type: lang = i.get("lang") if idtype and len(idtype) > 2: idtype = idtype[:1] if idtype: idtype = idtype.title() if lang is None: lang = "auto" txt = "{}:{} ({})".format(idtype, idval, lang) break return txt def get_external_audio_file(self): aud = None for i in self.mpv.get_property("track-list"): idval = i.get("id") idtype = i.get("type") if idtype == "audio": if i.get("external") and i.get("selected"): aud = i.get("external-filename") break return aud def player_seeking(self, _name, value): logger.info("{} {}".format(_name, value)) if value is True: self.seek_now = True else: self.seek_now = False def playback_abort_observer(self, name, value): site = self.ui.get_parameters_value(st='site')['site'] logger.debug('\n..{} {}..\n'.format(name, value)) if self.ui.epn_clicked and value is True and self.ui.playlist_continue: if self.ui.cur_row < self.ui.list2.count(): self.ui.list2.setCurrentRow(self.ui.cur_row) item = self.ui.list2.item(self.ui.cur_row) if self.first_play and site == "Music": self.mpv.command("stop") self.ui.player_stop.clicked_emit() self.first_play = False if item: self.ui.list2.itemDoubleClicked['QListWidgetItem*'].emit(item) logger.debug("trying again..............") def volume_observer(self, _name, value): logger.info("{} {}".format(_name, value)) if value and isinstance(value, float): self.player_volume = value self.ui.player_volume = str(int(value)) def quit_watch_later(self, _name, value): logger.info("{} {}".format(_name, value)) if value is True: self.rem_properties(self.ui.final_playing_url, rem_quit=1, seek_time=self.ui.progress_counter) def sub_changed(self, _name, value): logger.debug('{} {} {}'.format(_name, value, "--sub--")) self.sub_id = value if value is False: gui.subtitle_track.setText("Sub: None") else: txt = self.get_track_property(value, "sub") if txt: gui.subtitle_track.setText(txt) def audio_changed(self, _name, value): self.audio_id = value logger.debug("{} {} {}".format(_name, value, "--audio--")) if value is False: gui.audio_track.setText("A: None") else: txt = self.get_track_property(value, "audio") if txt: gui.audio_track.setText(txt) def display_play_pause_string(self, value): display_string = "None" if value is not None: fn = lambda val: time.strftime('%H:%M:%S', time.gmtime(int(val))) gui.progress_counter = value try: cache = self.mpv.get_property('demuxer-cache-duration') except Exception as err: cache = 0 if gui.mplayerLength > 0: percent = int((value/gui.mplayerLength)*100) else: percent = 0 if not cache: cache = 0 if gui.mplayerLength > 0: display_string = '{}% {} / {} Cache: {}s'.format(percent, fn(value), fn(gui.mplayerLength), int(cache)) return display_string def playlist_position_observer(self, _name, value): logger.debug("{}-{}".format(_name, value)) if platform.system().lower() == "darwin": self.ui.gui_signals.cursor_method((self, "show")) if isinstance(value, int) and value >= 0: cur_row = value if (self.mpv.get_property('playlist-count') > 1 and cur_row < gui.list2.count() and gui.list2.count() > 1): gui.cur_row = cur_row gui.list2.setCurrentRow(gui.cur_row) self.set_window_title_and_epn(row=cur_row) if gui.view_mode == "thumbnail_light" and gui.cur_row < gui.list_poster.count(): gui.list_poster.setCurrentRow(gui.cur_row) if platform.system().lower() == "darwin": self.ui.gui_signals.cursor_method((self, "hide")) def time_observer(self, _name, value): if value is not None: if abs(value - gui.progress_counter) >= 0.5: display_string = self.display_play_pause_string(value) value_int = int(value) if self.file_size: file_size = round((self.file_size)/(1024*1024), 2) display_string = "{} Size: {} M".format(display_string, file_size) if not gui.frame1.isHidden() and not self.seek_now: gui.slider.valueChanged.emit(value_int) gui.gui_signals.display_string((display_string)) if not gui.new_tray_widget.isHidden(): gui.new_tray_widget.update_signal.emit(display_string, int(value)) if value_int % 30 == 0: self.send_fake_event("mouse_release") if self.audio and int(value) in range(0, 3): if self.mpv.get_property("loop-file") is False: self.mpv.command("audio-add", self.audio, "select") logger.debug("{} {}".format("adding..audio..", self.audio)) self.audio = None if self.subtitle and int(value) in range(0, 3): if self.mpv.get_property("loop-file") is False: if "::" in self.subtitle: for sub in self.subtitle.split("::"): self.mpv.command("sub-add", sub) else: self.mpv.command("sub-add", self.subtitle, "select") logger.debug("\n{} {}\n".format("adding..subtitle..", self.subtitle)) self.subtitle = None if gui.gapless_network_stream and not gui.queue_url_list: if gui.progress_counter > int(gui.mplayerLength/2): if (gui.cur_row + 1) < gui.list2.count(): item_index = gui.cur_row + 1 else: item_index = 0 if gui.tmp_pls_file_dict.get(item_index) is False and gui.list2.count() > 1: gui.start_gapless_stream_process(item_index) if self.prefetch_url and isinstance(self.prefetch_url, tuple) and gui.gapless_network_stream: finalUrl, row, type_val = self.prefetch_url gui.epnfound_now_start_prefetch(finalUrl, row, type_val) self.prefetch_url = None def send_fake_event(self, val): self.fake_mousemove_event = ("libmpv", True) pos = self.cursor().pos() if not self.pointer_moved: new_point = QtCore.QPoint(pos.x() + 1, pos.y()) self.pointer_moved = True else: new_point = QtCore.QPoint(pos.x() - 1, pos.y()) self.pointer_moved = False self.cursor().setPos(new_point) if val == "mouse_release": event = QtGui.QMouseEvent( QtCore.QEvent.MouseButtonRelease, new_point, QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, ) elif val == "mouse_move": event = QtGui.QMouseEvent( QtCore.QEvent.MouseMove, new_point, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier, ) self.ui.gui_signals.mouse_move_method((self, event)) def rem_properties(self, final_url, rem_quit, seek_time): self.ui.history_dict_obj_libmpv.update( { final_url:[ seek_time, time.time(), self.sub_id, self.audio_id, rem_quit, self.player_volume, self.ui.mpvplayer_aspect_cycle ] } ) logger.info("remember-- {}".format(self.ui.history_dict_obj_libmpv.get(self.ui.final_playing_url))) def core_observer(self, _name, value): logger.debug("{} {}".format("core..observer.. value", value)) if value is True and self.mpv.get_property("idle-active") is False: cache = self.mpv.get_property('demuxer-cache-idle') time_pos = self.mpv.get_property('time-pos') if time_pos and time_pos > 3: self.ui.mpvplayer_val.write(b'show-text osd-sym-cc pause-string') self.player_observer_thread.show_status = True else: self.player_observer_thread.show_status = False else: self.player_observer_thread.show_status = False if self.mpv.get_property("idle-active") is False: time_pos = self.mpv.get_property('time-pos') if time_pos and time_pos > 3: self.ui.mpvplayer_val.write(b'show-text osd-sym-cc pause-string') def eof_observer(self, _name, value): logger.debug("{} {}".format("eof.. value", value, _name)) if value is True or value is None: if value is True: self.rem_properties(self.ui.final_playing_url, 0, 0) if self.ui.queue_url_list: self.check_queued_item() elif not gui.queue_url_list and self.playlist_backup: if gui.cur_row < gui.list2.count(): gui.list2.setCurrentRow(gui.cur_row) item = gui.list2.item(gui.cur_row) if item: gui.list2.itemDoubleClicked['QListWidgetItem*'].emit(item) self.playlist_backup = False if (value in [None, True] and (self.ui.quit_really == "yes" or not self.ui.playlist_continue)): self.stop_msg = "openglwidget" self.mpv.command("stop") self.ui.player_stop.clicked_emit() def check_queued_item(self): if self.ui.queue_url_list: item = self.ui.queue_url_list[0] self.ui.queue_url_list = self.ui.queue_url_list[1:] self.ui.gui_signals.delete_queue_item(0) if '\t' in item: item_list = item.split('\t') title = item_list[0] url = item_list[1] else: title = item.rsplit('/')[-1] if not title: title = item url = item if title and title.startswith("#"): title = title[1:] self.mpv.command("playlist-clear") url = url.replace('"', "") self.mpv.command("loadfile", url) self.ui.final_playing_url = url self.set_window_title_and_epn(title=title) self.playlist_backup = True def gather_external_sub(self, row=None): new_path = self.ui.final_playing_url.replace('"', '') sub_arr = [] slang_list = self.mpv.get_property("slang") if not slang_list: slang_list = ["mr", "en", "fr", "es", "jp"] if os.path.exists(new_path): sub_name_bytes = bytes(new_path, 'utf-8') h = hashlib.sha256(sub_name_bytes) sub_name = h.hexdigest() sub_path_vtt = os.path.join(self.ui.yt_sub_folder, sub_name+'.vtt') sub_path_srt = os.path.join(self.ui.yt_sub_folder, sub_name+'.srt') sub_path_ass = os.path.join(self.ui.yt_sub_folder, sub_name+'.ass') if os.path.exists(sub_path_vtt): sub_arr.append({"path":sub_path_vtt, "type":"vtt", lang: "default"}) if os.path.exists(sub_path_srt): sub_arr.append({"path":sub_path_srt, "type":"srt", lang: "default"}) if os.path.exists(sub_path_ass): sub_arr.append({"path":sub_path_ass, "type":"ass", lang: "default"}) if self.ui.cur_row < len(self.ui.epn_arr_list): if row and row < len(self.ui.epn_arr_list): ourl = self.ui.epn_arr_list[row] else: ourl = self.ui.epn_arr_list[self.ui.cur_row] if '\t' in ourl: param = None ourl = ourl.split('\t')[1] ourl = ourl.replace('"', "") if ourl.startswith("http"): u = urllib.parse.urlparse(ourl) if 'youtube.com' in u.netloc and 'watch' in u.path: for q in u.query.split('&'): if q.startswith('v='): param = q.rsplit('=')[-1] break if param: ext_fn = lambda x: [x+".vtt", x+".srt", x+".ass"] ext_list = list(itertools.chain.from_iterable(list(map(ext_fn, slang_list)))) for ext in ext_list: lang, file_type = ext.split(".") sub_arr.append( {"path": os.path.join(self.ui.yt_sub_folder, param+"."+ext), "type": file_type, "lang": lang} ) return sub_arr, slang_list def try_external_sub(self, sub_arr, slang_list): for sub in sub_arr.copy(): path = sub.get("path") sub_type = sub.get("type") lang = sub.get("lang") if os.path.exists(path): logger.debug(path) if lang in slang_list or lang == "default": opt = "select" else: opt = "auto" self.mpv.command("sub-add", path, opt, "External-Subtitle", lang) def idle_observer(self, _name, value): site = self.ui.get_parameters_value(st='site')['site'] logger.debug("...{}={}, quit-now={} site={}".format(value, _name, gui.quit_now, site)) if (value is True and self.started and gui.list2.count() > 1 and gui.quit_now is False and site.lower() not in ["video", "music", "none", "myserver"]): if site.lower() == "playlists": self.ui.stale_playlist = True if self.mpv.get_property("playlist-count") == 1 and self.ui.playlist_continue: logger.debug("only single playlist..") self.mpv.set_property('loop-playlist', 'no') self.mpv.set_property('loop-file', 'no') self.mpv.command('stop') gui.cur_row = (gui.cur_row + 1) % gui.list2.count() gui.list2.setCurrentRow(gui.cur_row) item = gui.list2.item(gui.cur_row) if item: gui.list2.itemDoubleClicked['QListWidgetItem*'].emit(item) self.set_window_title_and_epn(row=gui.cur_row) def set_window_title_and_epn(self, title=None, row=None): if title is None: if isinstance(row, int) and row < self.ui.list2.count(): item = gui.list2.item(row) else: item = gui.list2.item(gui.cur_row) if item: epn = item.text() else: epn = "Unknown" if epn.startswith(gui.check_symbol): epn = epn[1:] else: epn = title MainWindow.windowTitleChanged.emit(epn) gui.epn_name_in_list = epn self.mpv.command("show-text", epn, 2000) def time_duration(self, _name, value): if value is not None: if self.mpv_reinit: self.mpv.start = "none" self.mpv_reinit = False self.ui.quit_really = False self.ui.epn_clicked = False self.started = True z = 'duration is {:.2f}s'.format(value) #gui.progressEpn.setFormat((z)) gui.mplayerLength = int(value) try: self.file_size = self.mpv.get_property('file-size') except Exception as err: self.file_size = 0 try: self.mpv.set_property("ao-volume", str(gui.player_volume)) except Exception as err: logger.error(err) gui.progress_counter = 0 gui.slider.setRange(0, int(gui.mplayerLength)) gui.final_playing_url = self.mpv.get_property('path') self.track_list = self.mpv.get_property('track-list') self.chapter_list = self.mpv.get_property('chapter-list') if not self.initial_volume_set: logger.debug("setting..........volume.......{}".format(gui.player_volume)) try: self.mpv.set_property('ao-volume', int(gui.player_volume)) self.initial_volume_set = True except Exception as err: logger.error(err) if self.ui.pc_to_pc_casting == "slave": saved_url = self.ui.final_playing_url.rsplit("/&master_token=")[0] else: saved_url = self.ui.final_playing_url if saved_url in self.ui.history_dict_obj_libmpv: seek_time, cur_time, sub_id, audio_id, rem_quit, vol, asp = self.ui.history_dict_obj_libmpv.get(saved_url) if asp == -1 or asp == "-1" or asp is None: asp = "0" aspect_val = self.ui.mpvplayer_aspect_float.get(str(asp)) logger.info("restoring.. -> {}".format(self.ui.history_dict_obj_libmpv.get(self.ui.final_playing_url))) if aspect_val and gui.restore_aspect: self.mpv.set_property('video-aspect', aspect_val) elif not gui.restore_aspect: self.mpv.command("show-text", "Bad Aspect Property: {}".format(aspect_val)) try: self.mpv.set_property('sid', sub_id) except: pass try: self.mpv.set_property('aid', audio_id) except: pass if gui.restore_volume and vol: try: self.mpv.set_property('ao-volume', str(vol)) except Exception as err: logger.error(err) param_dict = gui.get_parameters_value(o='opt', s="site") site = param_dict["site"] opt = param_dict["opt"] if rem_quit or (site.lower() == "video" and opt.lower() == "history"): self.mpv.command("seek", seek_time, "absolute") if not self.exec_thread.isRunning() and not self.playlist_backup: func_gather_sub = partial(self.gather_external_sub, self.ui.cur_row) func_try_sub = self.try_external_sub self.exec_thread = ExecCommand(self.ui, [func_gather_sub, func_try_sub]) self.exec_thread.start() if self.ui.pc_to_pc_casting == 'slave' and 'master_abs_path=' in self.ui.final_playing_url: self.ui.add_external_subtitle.clicked_emit() def keyPressEvent(self, event): if event.isAutoRepeat(): if not self.key_thread.isRunning(): cmd = self.get_mpv_cmd(event) if cmd: self.key_thread = KeyT(self.ui, event, cmd.copy()) self.key_thread.start() else: self.keyPressEventO(event) else: self.keyPressEventO(event) def get_mpv_cmd(self, event): key = self.total_keys.get(event.key()) if key and event.modifiers() not in self.modifiers: cmd = self.mpv_default_modified.get(key) else: cmd = None return cmd def keyPressEventO(self, event): key = self.total_keys.get(event.key()) if key and event.modifiers() not in self.modifiers: cmd = self.mpv_default_modified.get(key) else: cmd = None if cmd: logger.debug(cmd) try: self.mpv.command(*cmd) except Exception as err: logger.error(err) else: PlayerWidget.keyPressEvent(self, event) def keyReleaseEvent(self, event): PlayerWidget.keyReleaseEvent(self, event) def mouseDoubleClickEvent(self, event): self.toggle_fullscreen_mode() for i in self.event_dict: self.event_dict[i] = False def mouseMoveEvent(self, event): self.setFocus() PlayerWidget.mouseMoveEvent(self, event) def mouseEnterEvent(self, event): self.setFocus() self.ui.gui_signals.cursor_method((self, "hide")) def leaveEvent(self, event): self.ui.gui_signals.cursor_method((self, "show")) def change_aspect_ratio(self, key=None): if key is None: self.ui.mpvplayer_aspect_cycle = (self.ui.mpvplayer_aspect_cycle + 1) % 5 else: self.ui.mpvplayer_aspect_cycle = int(key) aspect_val = self.ui.mpvplayer_aspect_float.get(str(self.ui.mpvplayer_aspect_cycle)) self.mpv.set_property('video-aspect', aspect_val) aspect_prop = self.aspect_map.get(str(self.ui.mpvplayer_aspect_cycle)) self.mpv.command("show-text", "Video-Aspect: {}".format(aspect_prop)) def start_player_loop(self): PlayerWidget.start_player_loop(self) def show_hide_status_frame(self): PlayerWidget.show_hide_status_frame(self) def toggle_play_pause(self): PlayerWidget.toggle_play_pause(self) def load_subtitle_from_file(self): PlayerWidget.load_subtitle_from_file(self) def load_subtitle_from_network(self): PlayerWidget.load_subtitle_from_network(self) def add_external_audio(self): fname = QtWidgets.QFileDialog.getOpenFileNames( MainWindow, 'Select One or More Files', self.ui.last_dir) sub_dict = {} if fname and fname[0]: for aud in fname[0]: self.ui.last_dir, file_choose = os.path.split(fname[0][0]) logger.debug('{}, {}'.format(aud, file_choose)) self.mpv.command("audio-add", aud, "select") def load_external_sub(self, mode=None, subtitle=None, title=None): if mode is None: fname = QtWidgets.QFileDialog.getOpenFileNames( MainWindow, 'Select Subtitle file', self.ui.last_dir) if fname: logger.info(fname) if fname[0]: self.ui.last_dir, file_choose = os.path.split(fname[0][0]) title_sub = fname[0][0] if self.player_val == "mplayer": txt = '\n sub_load "{}" \n'.format(title_sub) txt_b = bytes(txt, 'utf-8') logger.info("{0} - {1}".format(txt_b, txt)) gui.mpvplayer_val.write(txt_b) else: txt = '\n sub-add "{}" select \n'.format(title_sub) txt_b = bytes(txt, 'utf-8') logger.info("{0} - {1}".format(txt_b, txt)) gui.mpvplayer_val.write(txt_b) self.ui.acquire_subtitle_lock = False elif mode == 'network': site = self.ui.get_parameters_value(st='site')['site'] if site.lower() == 'myserver': title_sub = self.ui.final_playing_url + '.original.subtitle' if self.player_val == "mplayer": txt = '\n sub_load "{}" \n'.format(title_sub) txt_b = bytes(txt, 'utf-8') logger.info("{0} - {1}".format(txt_b, txt)) gui.mpvplayer_val.write(txt_b) else: txt = '\n sub-add "{}" select \n'.format(title_sub) txt_b = bytes(txt, 'utf-8') logger.info("{0} - {1}".format(txt_b, txt)) gui.mpvplayer_val.write(txt_b) else: logger.warning('Not Allowed') elif mode == 'drop': title_sub = subtitle logger.debug(title_sub) if self.player_val == "mplayer": txt = '\n sub_load "{}" \n'.format(title_sub) txt_b = bytes(txt, 'utf-8') logger.info("{0} - {1}".format(txt_b, txt)) gui.mpvplayer_val.write(txt_b) else: txt = '\n sub-add "{}" select \n'.format(title_sub) txt_b = bytes(txt, 'utf-8') logger.info("{0} - {1}".format(txt_b, txt)) gui.mpvplayer_val.write(txt_b) elif mode in ['load', 'auto']: ext_find = subtitle.split('.') if len(ext_find) >= 2: lang = ext_find[-2] ext = ext_find[-1] else: lang = ext_find[-1] ext = ext_find[-1] if self.ui.player_val == "mplayer": cmd = 'sub_load "{}"'.format(subtitle) else: cmd = 'sub-add "{}" auto {} {}'.format(subtitle, lang, lang) if self.ui.list2.currentItem(): row = self.ui.list2.currentRow() else: row = 0 if mode == 'auto': self.ui.mpv_execute_command(cmd, row, 1000) else: self.ui.mpv_execute_command(cmd, row) def add_parameter(self, cmd): if ' ' in cmd: cmd_list = cmd.split(' ') cmd_name = cmd_list[1] if cmd_name in ['volume', 'ao-volume']: self.change_volume(cmd) elif cmd_name in ['brightness', 'contrast', 'saturation', 'hue', 'gamma']: cmd_val = cmd_list[-1] try: cmd_val_int = int(cmd_val) slider = eval('self.ui.frame_extra_toolbar.{}_slider'.format(cmd_name)) slider.setValue(slider.value() + cmd_val_int) except Exception as err: logger.error(err) else: cmd = '\n {} \n'.format(cmd) command_string = bytes(cmd, 'utf-8') logger.debug(command_string) self.ui.mpvplayer_val.write(command_string) def change_volume(self, command): vol = None volume = False msg = None new_command = None if ' ' in command: vol_int = command.split(' ')[-1] if vol_int.startswith('-') or vol_int.startswith('+'): vol = vol_int[1:] else: vol = vol_int if vol.isnumeric(): volume = True slider = self.ui.frame_extra_toolbar.slider_volume if command.startswith('add volume') and volume: value = slider.value() + int(vol_int) if self.ui.volume_type == 'ao-volume': msg = '\n print-text volume-print=${volume} \n' if value <= 100: slider.setValue(value) else: new_command = '\n add volume {} \n'.format(vol_int) msg = '\n print-text volume-print=${volume} \n' elif command.startswith('add ao-volume') and volume: slider.setValue(slider.value() + int(vol_int)) if self.ui.volume_type == 'volume': msg = '\n print-text ao-volume-print=${ao-volume} \n' if msg: if new_command: self.ui.mpvplayer_val.write(bytes(new_command, 'utf-8')) msg = bytes(msg, 'utf-8') self.ui.mpvplayer_val.write(msg) def toggle_fullscreen_mode(self): wd = self.width() ht = self.height() val = self.mpv.get_property('fullscreen') if (val is False or val is None) or (val and not self.ui.fullscreen_video): self.mpv.set_property('fullscreen', 'yes') self.player_fs(mode='fs') else: self.mpv.set_property('fullscreen', 'no') self.player_fs(mode='nofs') def get_next(self): pls_count = self.mpv.get_property('playlist-count') pls_pos = self.mpv.get_property('playlist-pos') print(pls_count, pls_pos) if pls_count is not None and pls_pos is not None and pls_count == pls_pos + 1: self.mpv.set_property('playlist-pos', 0) else: self.mpv.command("playlist-next") def get_previous(self): pls_count = self.mpv.get_property('playlist-count') pls_pos = self.mpv.get_property('playlist-pos') print(pls_count, pls_pos) if pls_count is not None and pls_pos is not None and pls_pos == 0: self.mpv.set_property('playlist-pos', pls_count - 1) else: self.mpv.command("playlist-prev") def quit_player(self, msg=None): if msg == "rem_quit": self.rem_properties(self.ui.final_playing_url, 1, self.ui.progress_counter) else: self.rem_properties(self.ui.final_playing_url, 0, self.ui.progress_counter) self.initial_volume_set = False self.player_observer_thread.remove_external_files = True self.audio = None self.subtitle = None self.ui.quit_now = True self.mpv.command("stop") self.stop_msg = "openglwidget" self.ui.player_stop.clicked_emit() self.ui.tab_5.setMinimumWidth(0) self.ui.tab_5.setMinimumHeight(0) self.setParent(MainWindow) self.ui.gridLayout.addWidget(self, 0, 1, 1, 1) self.ui.superGridLayout.addWidget(self.ui.frame1, 1, 1, 1, 1) self.setMouseTracking(True) self.showNormal() self.setFocus() def remember_and_quit(self): self.quit_player(msg="rem_quit") def cycle_player_subtitle(self): self.ui.mpvplayer_val.write(b'\n cycle sub \n') self.ui.mpvplayer_val.write(b'\n print-text "SUB_KEY_ID=${sid}" \n') self.ui.mpvplayer_val.write(b'\n show-text "${sid}" \n') def cycle_player_audio(self): self.ui.mpvplayer_val.write(b'\n cycle audio \n') self.ui.mpvplayer_val.write(b'\n print-text "AUDIO_KEY_ID=${aid}" \n') self.ui.mpvplayer_val.write(b'\n show-text "${aid}" \n') def stop_after_current_file(self): self.ui.quit_really = "yes" msg = '"Stop After current file"' msg_byt = bytes('\nshow-text {0}\n'.format(msg), 'utf-8') gui.mpvplayer_val.write(msg_byt) def player_fs(self, mode=None): if platform.system().lower() == "darwin": self.mpv.command("set", "pause", "yes") if not self.ui.idw or self.ui.idw == self.ui.get_winid(): if self.player_val == "libmpv": if mode == 'fs': if not self.ui.tab_6.isHidden(): self.ui.fullscreen_mode = 1 elif not self.ui.float_window.isHidden(): self.ui.fullscreen_mode = 2 else: self.ui.fullscreen_mode = 0 self.ui.superGridLayout.setSpacing(0) self.ui.superGridLayout.setContentsMargins(0, 0, 0, 0) self.ui.gridLayout.setSpacing(0) self.ui.gridLayout.setContentsMargins(0, 0, 0, 0) self.ui.text.hide() self.ui.label.hide() self.ui.frame1.hide() self.ui.tab_6.hide() self.ui.goto_epn.hide() if self.ui.wget.processId() > 0 or self.ui.video_local_stream or self.ui.is_torrent_active: self.ui.progress.hide() if not self.ui.torrent_frame.isHidden(): self.ui.torrent_frame.hide() self.ui.list2.hide() self.ui.frame_extra_toolbar.hide() self.ui.frame_extra_toolbar.playlist_hide = False self.ui.list6.hide() self.ui.list1.hide() self.ui.frame.hide() self.ui.dockWidget_3.hide() if self.ui.orientation_dock == 'right': self.ui.superGridLayout.addWidget(self.ui.dockWidget_3, 0, 1, 1, 1) self.show() self.setFocus() if not self.ui.tab_2.isHidden(): self.ui.tab_2.hide() if self.player_val in self.ui.playback_engine: self.ui.gui_signals.cursor_method((MainWindow, "hide")) if platform.system().lower() == "darwin" and self.ui.osx_native_fullscreen: MainWindow.hide() self.setParent(None) self.ui.tab_5_layout.insertWidget(1, self.ui.frame1) else: MainWindow.showFullScreen() self.ui.fullscreen_video = True self.showFullScreen() self.setFocus() self.setMouseTracking(True) if platform.system().lower() == "darwin": self.setMinimumWidth(MainWindow.width()) if self.ui.widgets_on_video: self.ui.gridLayoutVideo.addWidget(self.ui.frame1, 2, 1, 1, 1) elif mode == "nofs": #self.hide() if self.ui.widgets_on_video: self.ui.superGridLayout.addWidget(self.ui.frame1, 1, 1, 1, 1) if platform.system().lower() == "darwin": self.mpv.command("set", "pause", "yes") self.ui.gridLayout.setSpacing(5) self.ui.superGridLayout.setSpacing(5) self.ui.gridLayout.setContentsMargins(5, 5, 5, 5) self.ui.superGridLayout.setContentsMargins(5, 5, 5, 5) self.ui.list2.show() self.ui.btn20.show() if self.ui.wget.processId() > 0 or self.ui.video_local_stream or self.ui.is_torrent_active: self.ui.progress.show() self.ui.frame1.show() if self.player_val in self.ui.playback_engine: self.ui.gui_signals.cursor_method((MainWindow, "show")) if not self.ui.force_fs: #MainWindow.showNormal() MainWindow.show() if platform.system().lower() in ["darwin", "linux"]: MainWindow.showMaximized() param_dict = self.ui.get_parameters_value(tl='total_till') total_till = param_dict['total_till'] if total_till != 0 or self.ui.fullscreen_mode == 1: self.ui.tab_6.show() self.ui.list2.hide() self.ui.frame_extra_toolbar.hide() self.ui.frame_extra_toolbar.playlist_hide = False self.ui.goto_epn.hide() if self.ui.btn1.currentText().lower() == 'youtube': self.ui.list2.hide() self.ui.frame_extra_toolbar.hide() self.ui.frame_extra_toolbar.playlist_hide = False self.ui.goto_epn.hide() self.ui.tab_2.show() if self.ui.orientation_dock == 'right': self.ui.superGridLayout.addWidget(self.ui.dockWidget_3, 0, 5, 2, 1) self.ui.fullscreen_video = False if platform.system().lower() == "darwin" and self.ui.osx_native_fullscreen: self.setParent(MainWindow) self.ui.gridLayout.addWidget(self, 0, 1, 1, 1) self.ui.superGridLayout.addWidget(self.ui.frame1, 1, 1, 1, 1) self.setMouseTracking(True) self.showNormal() self.setFocus() #MainWindow.show() #MainWindow.showMaximized() self.setMinimumWidth(0) self.setMinimumHeight(0) if not self.mx_timer.isActive() and platform.system().lower() != "darwin": self.mx_timer.start(1000) else: if self.ui.detach_fullscreen: self.ui.detach_fullscreen = False self.ui.float_window.showNormal() self.ui.tray_widget.right_menu._detach_video() self.ui.tab_5.setFocus() else: if not self.ui.float_window.isHidden(): if not self.ui.float_window.isFullScreen(): self.ui.float_window.showFullScreen() else: self.ui.float_window.showNormal() else: self.ui.tab_6_size_indicator.append(self.ui.tab_6.width()) param_dict = self.ui.get_parameters_value(icn='iconv_r_indicator', i='iconv_r') iconv_r_indicator = param_dict['iconv_r_indicator'] iconv_r = param_dict['iconv_r'] cur_label_num = self.ui.cur_row if not MainWindow.isHidden(): if self.ui.video_mode_index in [5,6,7]: pass else: if iconv_r_indicator: iconv_r = iconv_r_indicator[0] self.ui.set_parameters_value(iconv=iconv_r) widget = eval("self.ui.label_epn_"+str(cur_label_num)) col = (cur_label_num%iconv_r) row = 2*int(cur_label_num/iconv_r) new_pos = (row, col) print(new_pos) if not MainWindow.isFullScreen(): cur_label = cur_label_num index = self.ui.gridLayout2.indexOf(widget) logger.debug(index) if index >= 0: self.ui.current_thumbnail_position = self.ui.gridLayout2.getItemPosition(index) self.ui.tab_6.hide() self.ui.gridLayout.addWidget(widget, 0, 1, 1, 1) widget.setMaximumSize(QtCore.QSize(screen_width, screen_height)) self.ui.gridLayout.setContentsMargins(0, 0, 0, 0) self.ui.superGridLayout.setContentsMargins(0, 0, 0, 0) self.ui.gridLayout1.setContentsMargins(0, 0, 0, 0) self.ui.gridLayout2.setContentsMargins(0, 0, 0, 0) self.ui.gridLayout.setSpacing(0) self.ui.gridLayout1.setSpacing(0) self.ui.gridLayout2.setSpacing(0) self.ui.superGridLayout.setSpacing(0) if self.ui.orientation_dock == 'right': self.ui.superGridLayout.addWidget(self.ui.dockWidget_3, 0, 1, 1, 1) MainWindow.showFullScreen() self.ui.fullscreen_video = True else: w = float((self.ui.tab_6.width()-60)/iconv_r) h = int(w/self.ui.image_aspect_allowed) width=str(int(w)) height=str(int(h)) r = self.ui.current_thumbnail_position[0] c = self.ui.current_thumbnail_position[1] cur_label = cur_label_num self.ui.gridLayout2.addWidget(widget, r, c, 1, 1, QtCore.Qt.AlignCenter) QtWidgets.QApplication.processEvents() MainWindow.showNormal() MainWindow.showMaximized() yy = widget.y() self.ui.scrollArea1.verticalScrollBar().setValue(yy) QtWidgets.QApplication.processEvents() self.ui.frame1.show() self.ui.gridLayout.setContentsMargins(5, 5, 5, 5) self.ui.superGridLayout.setContentsMargins(5, 5, 5, 5) self.ui.gridLayout1.setContentsMargins(5, 5, 5, 5) self.ui.gridLayout2.setContentsMargins(5, 5, 5, 5) self.ui.gridLayout.setSpacing(5) self.ui.gridLayout1.setSpacing(5) self.ui.gridLayout2.setSpacing(5) self.ui.superGridLayout.setSpacing(5) self.ui.tab_6.show() if self.ui.orientation_dock == 'right': self.ui.superGridLayout.addWidget(self.ui.dockWidget_3, 0, 5, 2, 1) QtWidgets.QApplication.processEvents() widget.setFocus() QtCore.QTimer.singleShot(1000, self.ui.update_thumbnail_position) self.ui.fullscreen_video = False else: if not self.ui.float_window.isHidden(): if not self.ui.float_window.isFullScreen(): widget = eval("self.ui.label_epn_"+str(cur_label_num)) index = self.ui.gridLayout2.indexOf(widget) print(index, '--index--') self.ui.current_thumbnail_position = self.ui.gridLayout2.getItemPosition(index) self.ui.float_window.showFullScreen() else: self.ui.float_window.showNormal() if not self.pause_timer.isActive() and platform.system().lower() == "darwin": self.pause_timer.start(1000)