Exemple #1
0
    def __init__(self):
        self._video = None
        mpv_options = OrderedDict()
        mpv_location = settings.mpv_ext_path
        # Use bundled path for MPV if not specified by user, on Mac OS, and frozen
        if (mpv_location is None and platform.system() == "Darwin"
                and getattr(sys, "frozen", False)):
            mpv_location = get_resource("mpv")
        self.timeline_trigger = None
        self.action_trigger = None
        self.external_subtitles = {}
        self.external_subtitles_rev = {}
        self.should_send_timeline = False
        self.start_time = None
        self.url = None
        self.evt_queue = Queue()
        self._lock = RLock()
        self._tl_lock = RLock()
        self._finished_lock = Lock()
        self.last_update = Timer()
        self._jf_settings = None
        self.get_webview = lambda: None
        self.pause_ignore = None  # Used to ignore pause events that come from us.
        self.do_not_handle_pause = False
        self.last_seek = None
        self.warned_about_transcode = False
        self.fullscreen_disable = False
        self.update_check = UpdateChecker(self)

        if is_using_ext_mpv:
            mpv_options.update({
                "start_mpv": settings.mpv_ext_start,
                "ipc_socket": settings.mpv_ext_ipc,
                "mpv_location": mpv_location,
                "player-operation-mode": "cplayer",
            })
        if settings.menu_mouse:
            if is_using_ext_mpv:
                mpv_options["script"] = get_resource("mouse.lua")
            else:
                mpv_options["scripts"] = get_resource("mouse.lua")
        if not (settings.mpv_ext and settings.mpv_ext_no_ovr):
            mpv_options["include"] = conffile.get(APP_NAME, "mpv.conf", True)
            mpv_options["input_conf"] = conffile.get(APP_NAME, "input.conf",
                                                     True)
        self._player = mpv.MPV(input_default_bindings=True,
                               input_vo_keyboard=True,
                               input_media_keys=settings.media_keys,
                               log_handler=mpv_log_handler,
                               loglevel=settings.mpv_log_level,
                               **mpv_options)
        self.menu = OSDMenu(self, self._player)
        self.syncplay = SyncPlayManager(self)

        if hasattr(self._player, "osc"):
            self._player.osc = settings.enable_osc
        else:
            log.warning(
                "This mpv version doesn't support on-screen controller.")

        if settings.screenshot_dir is not None:
            if hasattr(self._player, "screenshot_directory"):
                self._player.screenshot_directory = settings.screenshot_dir
            else:
                log.warning(
                    "This mpv version doesn't support setting the screenshot directory."
                )

        # Wrapper for on_key_press that ignores None.
        def keypress(key):
            def wrapper(func):
                if key is not None:
                    self._player.on_key_press(key)(func)
                return func

            return wrapper

        @self._player.on_key_press("CLOSE_WIN")
        @self._player.on_key_press("STOP")
        @keypress(settings.kb_stop)
        def handle_stop():
            self.stop()

        @keypress(settings.kb_prev)
        def handle_prev():
            self.put_task(self.play_prev)

        @keypress(settings.kb_next)
        def handle_next():
            self.put_task(self.play_next)

        @self._player.on_key_press("PREV")
        @self._player.on_key_press("XF86_PREV")
        def handle_media_prev():
            if settings.media_key_seek:
                seektime, _x = self.get_seek_times()
                self.seek(seektime)
            else:
                self.put_task(self.play_prev)

        @self._player.on_key_press("NEXT")
        @self._player.on_key_press("XF86_NEXT")
        def handle_media_next():
            if settings.media_key_seek:
                _x, seektime = self.get_seek_times()
                self.seek(seektime)
            else:
                self.put_task(self.play_next)

        @keypress(settings.kb_watched)
        def handle_watched():
            self.put_task(self.watched_skip)

        @keypress(settings.kb_unwatched)
        def handle_unwatched():
            self.put_task(self.unwatched_quit)

        @keypress(settings.kb_menu)
        def menu_open():
            if not self.menu.is_menu_shown:
                self.menu.show_menu()
            else:
                self.menu.hide_menu()

        @keypress(settings.kb_menu_esc)
        def menu_back():
            if self.menu.is_menu_shown:
                self.menu.menu_action("back")
            else:
                self._player.command("set", "fullscreen", "no")
                self.fullscreen_disable = True

        @keypress(settings.kb_menu_ok)
        def menu_ok():
            self.menu.menu_action("ok")

        @keypress(settings.kb_menu_left)
        def menu_left():
            if self.menu.is_menu_shown:
                self.menu.menu_action("left")
            else:
                self.kb_seek("left")

        @keypress(settings.kb_menu_right)
        def menu_right():
            if self.menu.is_menu_shown:
                self.menu.menu_action("right")
            else:
                self.kb_seek("right")

        @keypress(settings.kb_menu_up)
        def menu_up():
            if self.menu.is_menu_shown:
                self.menu.menu_action("up")
            else:
                self.kb_seek("up")

        @keypress(settings.kb_menu_down)
        def menu_down():
            if self.menu.is_menu_shown:
                self.menu.menu_action("down")
            else:
                self.kb_seek("down")

        @keypress(settings.kb_pause)
        def handle_pause():
            if self.menu.is_menu_shown:
                self.menu.menu_action("ok")
            else:
                self.toggle_pause()

        @keypress(settings.kb_fullscreen)
        def handle_fullscreen():
            self.toggle_fullscreen()

        # This gives you an interactive python debugger prompt.
        @keypress(settings.kb_debug)
        def handle_debug():
            import pdb

            pdb.set_trace()

        # Kill shader packs (useful for breakage)
        @keypress(settings.kb_kill_shader)
        def kill_shaders():
            if settings.shader_pack_remember:
                settings.shader_pack_profile = None
                settings.save()
            if self.menu.profile_manager is not None:
                self.menu.profile_manager.unload_profile()

        # Fires between episodes.
        @self._player.property_observer("eof-reached")
        def handle_end(_name, reached_end: bool):
            self.pause_ignore = True
            if self._video and reached_end:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)

        # Fires at the end.
        @self._player.property_observer("playback-abort")
        def handle_end_idle(_name, value: bool):
            self.pause_ignore = True
            if self._video and value:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)

        @self._player.property_observer("seeking")
        def handle_seeking(_name, value: bool):
            if self.do_not_handle_pause:
                return

            if self.syncplay.is_enabled():
                play_time = self._player.playback_time
                if (play_time is not None and self.last_seek is not None
                        and abs(self.last_seek - play_time) > 10):
                    self.syncplay.seek_request(play_time)
                else:
                    log.debug("SyncPlay Buffering: {0}".format(value))
                    if value:
                        self.syncplay.on_buffer()
                    else:
                        self.syncplay.on_buffer_done()

        @self._player.property_observer("pause")
        def pause_handler(_name, value: bool):
            if self.do_not_handle_pause:
                return

            if not self._player.playback_abort:
                self.timeline_handle()

            if value != self.pause_ignore:
                if self.syncplay.is_enabled():
                    if value:
                        self.syncplay.pause_request()
                    else:
                        # Don't allow unpausing locally through MPV.
                        self.syncplay.play_request()
                        self.set_paused(True, True)

        @self._player.event_callback("client-message")
        def handle_client_message(event):
            try:
                if "event_id" in event:
                    args = event["event"]["args"]
                else:
                    args = event["args"]
                if len(args) == 0:
                    return
                if args[0] == "shim-menu-select":
                    # Apparently this can happen...
                    if args[1] == "inf":
                        return
                    self.menu.mouse_select(int(args[1]))
                elif args[0] == "shim-menu-click":
                    self.menu.menu_action("ok")
            except Exception:
                log.warning("Error when processing client-message.",
                            exc_info=True)
    def __init__(self):
        mpv_config = conffile.get(APP_NAME, "mpv.conf", True)
        input_config = conffile.get(APP_NAME, "input.conf", True)
        self._video = None
        extra_options = {}
        self.timeline_trigger = None
        self.action_trigger = None
        self.external_subtitles = {}
        self.external_subtitles_rev = {}
        self.should_send_timeline = False
        self.start_time = None
        self.url = None
        self.evt_queue = Queue()
        self._lock = RLock()
        self._tl_lock = RLock()
        self.last_update = Timer()
        self._jf_settings = None
        self.get_webview = lambda: None

        if is_using_ext_mpv:
            extra_options = {
                "start_mpv": settings.mpv_ext_start,
                "ipc_socket": settings.mpv_ext_ipc,
                "mpv_location": settings.mpv_ext_path,
                "player-operation-mode": "cplayer"
            }
        self._player = mpv.MPV(input_default_bindings=True,
                               input_vo_keyboard=True,
                               input_media_keys=True,
                               include=mpv_config,
                               input_conf=input_config,
                               log_handler=mpv_log_handler,
                               loglevel=settings.mpv_log_level,
                               **extra_options)
        self.menu = OSDMenu(self)

        if hasattr(self._player, 'osc'):
            self._player.osc = settings.enable_osc
        else:
            log.warning(
                "This mpv version doesn't support on-screen controller.")

        @self._player.on_key_press('CLOSE_WIN')
        @self._player.on_key_press('STOP')
        @self._player.on_key_press('q')
        def handle_stop():
            self.stop()

        @self._player.on_key_press('<')
        def handle_prev():
            self.put_task(self.play_prev)

        @self._player.on_key_press('>')
        def handle_next():
            self.put_task(self.play_next)

        @self._player.on_key_press('PREV')
        @self._player.on_key_press('XF86_PREV')
        def handle_media_prev():
            if settings.media_key_seek:
                seektime, _ = self.get_seek_times()
                self._player.command("seek", seektime)
            else:
                self.put_task(self.play_prev)

        @self._player.on_key_press('NEXT')
        @self._player.on_key_press('XF86_NEXT')
        def handle_media_next():
            if settings.media_key_seek:
                _, seektime = self.get_seek_times()
                self._player.command("seek", seektime)
            else:
                self.put_task(self.play_next)

        @self._player.on_key_press('w')
        def handle_watched():
            self.put_task(self.watched_skip)

        @self._player.on_key_press('u')
        def handle_unwatched():
            self.put_task(self.unwatched_quit)

        @self._player.on_key_press('c')
        def menu_open():
            if not self.menu.is_menu_shown:
                self.menu.show_menu()
            else:
                self.menu.hide_menu()

        @self._player.on_key_press('esc')
        def menu_back():
            self.menu.menu_action('back')

        @self._player.on_key_press('enter')
        def menu_ok():
            self.menu.menu_action('ok')

        @self._player.on_key_press('left')
        def menu_left():
            if self.menu.is_menu_shown:
                self.menu.menu_action('left')
            else:
                seektime = -5
                if settings.use_web_seek:
                    seektime, _ = self.get_seek_times()
                self._player.command("seek", seektime)

        @self._player.on_key_press('right')
        def menu_right():
            if self.menu.is_menu_shown:
                self.menu.menu_action('right')
            else:
                seektime = 5
                if settings.use_web_seek:
                    _, seektime = self.get_seek_times()
                self._player.command("seek", seektime)

        @self._player.on_key_press('up')
        def menu_up():
            if self.menu.is_menu_shown:
                self.menu.menu_action('up')
            else:
                self._player.command("seek", 60)

        @self._player.on_key_press('down')
        def menu_down():
            if self.menu.is_menu_shown:
                self.menu.menu_action('down')
            else:
                self._player.command("seek", -60)

        @self._player.on_key_press('space')
        def handle_pause():
            if self.menu.is_menu_shown:
                self.menu.menu_action('ok')
            else:
                self.toggle_pause()

        # This gives you an interactive python debugger prompt.
        @self._player.on_key_press('~')
        def handle_debug():
            import pdb
            pdb.set_trace()

        # Fires between episodes.
        @self._player.property_observer('eof-reached')
        def handle_end(_name, reached_end):
            if self._video and reached_end:
                self.put_task(self.finished_callback)

        # Fires at the end.
        @self._player.event_callback('idle')
        def handle_end_idle(event):
            if self._video:
                self.put_task(self.finished_callback)
Exemple #3
0
    def test_python_stream(self):
        handler = mock.Mock()

        disp = Xvfb()
        disp.start()
        m = mpv.MPV()
        m.register_event_callback(handler)

        @m.python_stream('foo')
        def foo_gen():
            with open(TESTVID, 'rb') as f:
                yield f.read()

        @m.python_stream('bar')
        def bar_gen():
            yield b''

        m.play('python://foo')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.EOF,
                'error': mpv.ErrorCode.SUCCESS
            }
        })
        handler.reset_mock()

        m.play('python://bar')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.UNKNOWN_FORMAT
            }
        })
        handler.reset_mock()

        m.play('python://baz')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.LOADING_FAILED
            }
        })
        handler.reset_mock()

        m.play('foo://foo')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.LOADING_FAILED
            }
        })
        handler.reset_mock()

        foo_gen.unregister()

        m.play('python://foo')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.LOADING_FAILED
            }
        })
        handler.reset_mock()

        m.play('python://bar')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.UNKNOWN_FORMAT
            }
        })
        handler.reset_mock()

        m.terminate()
        disp.stop()
 def test_flags(self):
     with self.assertRaises(AttributeError):
         mpv.MPV('this-option-does-not-exist')
     m = mpv.MPV('no-video', 'cursor-autohide-fs-only', 'fs')
     self.assertTrue(m.fullscreen)
     self.assertEqual(m.cursor_autohide, '1000')
Exemple #5
0
from flask import Flask, render_template

import mpv
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins='*')

player: mpv.MPV = mpv.MPV(ytdl=True)


def on_volume_change(_, value: float):
    socketio.emit('volumeChanged', {'value': value})


player.observe_property("volume", on_volume_change)


@socketio.on('volume', namespace='/command')
def volume_change(data):
    global player
    try:
        player._set_property('volume', data['value'])
        emit('log', {
            'message': f'Volume changed to {data["value"]}',
            'type': 'info'
        })
    except KeyError:
        emit('log', {'message': 'No volume value provided', 'type': 'error'})

Exemple #6
0
	def setup_video_player(self, player_id):
		mpv_player = mpv.MPV(border=False, ontop=False, osc="yes", loop_file="yes", aid="no")
		if player_id == 1:
			self.main_player_1 = mpv_player
		elif player_id == 2:
			self.main_player_2 = mpv_player
Exemple #7
0
import tkinter as tk
import os
import mpv

p = mpv.MPV()
p.volume = 50
p.loop = 'inf'
names = []
sampleFolder = 'sourceSamples'

blocksize = 1024 * 10

textSource = open('transcript.txt', 'r')

for fn in os.listdir(sampleFolder):
    if '.wav' in fn:
        base = os.path.join(sampleFolder, fn.replace('.wav', ''))
        if os.path.exists(base + '.png'):
            names.append(base)
            print(base)

names = sorted(names,
               reverse=True,
               key=lambda x: int(x.replace(sampleFolder + '\\Zaud', '')))

root = tk.Tk()

currentFile = None
txt = tk.Text(root, height=50, width=80)

Exemple #8
0
    def __init__(self, parent):

        QW.QWidget.__init__(self, parent)

        self._canvas_type = ClientGUICommon.CANVAS_PREVIEW

        self._stop_for_slideshow = False

        # 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.
        locale.setlocale(locale.LC_NUMERIC, 'C')

        self.setAttribute(QC.Qt.WA_DontCreateNativeAncestors)
        self.setAttribute(QC.Qt.WA_NativeWindow)

        # loglevels: fatal, error, debug
        self._player = mpv.MPV(wid=str(int(self.winId())),
                               log_handler=print,
                               loglevel='fatal')

        # hydev notes on OSC:
        # OSC is by default off, default input bindings are by default off
        # difficult to get this to intercept mouse/key events naturally, so you have to pipe them to the window with 'command', but this is not excellent
        # general recommendation when using libmpv is to just implement your own stuff anyway, so let's do that for prototype

        #self._player[ 'input-default-bindings' ] = True

        self.UpdateConf()

        #self._player.osc = True #Set to enable the mpv UI. Requires that mpv captures mouse/key events, otherwise it won't work.

        self._player.loop = True

        # this makes black screen for audio (rather than transparent)
        self._player.force_window = True

        # this actually propagates up to the OS-level sound mixer lmao, otherwise defaults to ugly hydrus filename
        self._player.title = 'hydrus mpv player'

        # this is telling ffmpeg to do audio normalization. play with it more and put it in default mpv.conf
        # it doesn't seem to apply at all for some files--maybe a vp9 issue or something?
        #self._player.af = 'lavfi=[dynaudnorm=p=0.9]'

        self.setMouseTracking(True)  #Needed to get mouse move events
        #self.setFocusPolicy(QC.Qt.StrongFocus)#Needed to get key events
        self._player.input_cursor = False  #Disable mpv mouse move/click event capture
        self._player.input_vo_keyboard = False  #Disable mpv key event capture, might also need to set input_x11_keyboard

        self._media = None

        self._times_to_play_gif = 0

        self._current_seek_to_start_count = 0

        player = self._player

        def qt_seek_event():

            if not QP.isValid(self):

                return

            if self._media is not None and self._player.time_pos <= 1.0:

                self._current_seek_to_start_count += 1

                if self._stop_for_slideshow:

                    self.Pause()

                if self._times_to_play_gif != 0 and self._current_seek_to_start_count >= self._times_to_play_gif:

                    self.Pause()

        @player.event_callback(mpv.MpvEventID.SEEK)
        def seek_event(event):

            QP.CallAfter(qt_seek_event)

        self.destroyed.connect(self._player.terminate)

        HG.client_controller.sub(self, 'UpdateAudioMute', 'new_audio_mute')
        HG.client_controller.sub(self, 'UpdateAudioVolume', 'new_audio_volume')
        HG.client_controller.sub(self, 'UpdateConf', 'notify_new_options')

        self._my_shortcut_handler = ClientGUIShortcuts.ShortcutsHandler(
            self, [], catch_mouse=True)
Exemple #9
0
    def __init__(self):
        mpv_config = conffile.get(APP_NAME, "mpv.conf", True)
        self._player = mpv.MPV(input_default_bindings=True,
                               input_vo_keyboard=True,
                               include=mpv_config)
        self.timeline_trigger = None
        self.action_trigger = None
        self.external_subtitles = {}
        self.external_subtitles_rev = {}
        self.menu = OSDMenu(self)

        if hasattr(self._player, 'osc'):
            self._player.osc = True
        else:
            log.warning(
                "This mpv version doesn't support on-screen controller.")

        self.url = None
        self.evt_queue = Queue()

        @self._player.on_key_press('q')
        def handle_stop():
            self.stop()
            self.timeline_handle()

        @self._player.on_key_press('<')
        def handle_prev():
            self.put_task(self.play_prev)

        @self._player.on_key_press('>')
        def handle_next():
            self.put_task(self.play_next)

        @self._player.on_key_press('w')
        def handle_watched():
            self.put_task(self.watched_skip)

        @self._player.on_key_press('u')
        def handle_unwatched():
            self.put_task(self.unwatched_quit)

        @self._player.on_key_press('c')
        def menu_open():
            if not self.menu.is_menu_shown:
                self.menu.show_menu()
            else:
                self.menu.hide_menu()

        @self._player.on_key_press('esc')
        def menu_back():
            self.menu.menu_action('back')

        @self._player.on_key_press('enter')
        def menu_ok():
            self.menu.menu_action('ok')

        @self._player.on_key_press('left')
        def menu_left():
            if self.menu.is_menu_shown:
                self.menu.menu_action('left')
            else:
                self._player.command("seek", -5)

        @self._player.on_key_press('right')
        def menu_right():
            if self.menu.is_menu_shown:
                self.menu.menu_action('right')
            else:
                self._player.command("seek", 5)

        @self._player.on_key_press('up')
        def menu_up():
            if self.menu.is_menu_shown:
                self.menu.menu_action('up')
            else:
                self._player.command("seek", 60)

        @self._player.on_key_press('down')
        def menu_down():
            if self.menu.is_menu_shown:
                self.menu.menu_action('down')
            else:
                self._player.command("seek", -60)

        @self._player.on_key_press('space')
        def handle_pause():
            if self.menu.is_menu_shown:
                self.menu.menu_action('ok')
            else:
                self.toggle_pause()

        # This gives you an interactive python debugger prompt.
        @self._player.on_key_press('~')
        def handle_debug():
            import pdb
            pdb.set_trace()

        @self._player.event_callback('idle')
        def handle_end(event):
            if self._video:
                self.put_task(self.finished_callback)

        self._video = None
        self._lock = RLock()
        self.last_update = Timer()

        self.__part = 1
Exemple #10
0
    def __init__(self):
        mpv_config = conffile.get(APP_NAME,"mpv.conf", True)
        input_config = conffile.get(APP_NAME,"input.conf", True)
        extra_options = {}
        self._video = None
        self._lock = RLock()
        self._finished_lock = Lock()
        self.last_update = Timer()
        self.__part = 1
        self.timeline_trigger = None
        self.action_trigger = None
        self.external_subtitles = {}
        self.external_subtitles_rev = {}
        self.url = None
        self.evt_queue = Queue()
        self.is_in_intro = False
        self.intro_has_triggered = False

        if is_using_ext_mpv:
            extra_options = {
                "start_mpv": settings.mpv_ext_start,
                "ipc_socket": settings.mpv_ext_ipc,
                "mpv_location": settings.mpv_ext_path,
                "player-operation-mode": "cplayer"
            }
        # todo figure out how to put these in a file
        extra_options = {
            'script-opts': 'osc-layout=slimbox,osc-deadzonesize=.9,osc-valign=1.05',
        }
        self._player = mpv.MPV(input_default_bindings=True, input_vo_keyboard=True,
                               input_media_keys=True, include=mpv_config, input_conf=input_config,
                               log_handler=mpv_log_handler, loglevel=settings.mpv_log_level,
                               **extra_options)
        self.menu = OSDMenu(self)
        self.auto_insert = False

        def on_new_sub(name, text):
            if not self.auto_insert:
                return
            if not text or not text.strip():
                return
            pyperclip.copy(text.replace('\n', ' '))

        self._player.observe_property('sub-text', on_new_sub)

        if hasattr(self._player, 'osc'):
            self._player.osc = settings.enable_osc
        else:
            log.warning("This mpv version doesn't support on-screen controller.")

        # Wrapper for on_key_press that ignores None.
        def keypress(key):
            def wrapper(func):
                if key is not None:
                    self._player.on_key_press(key)(func)
                return func
            return wrapper

        @self._player.on_key_press('CLOSE_WIN')
        @self._player.on_key_press('STOP')
        @keypress(settings.kb_stop)
        def handle_stop():
            self.stop()
            self.timeline_handle()

        @keypress(settings.kb_prev)
        def handle_prev():
            self.put_task(self.play_prev)

        @keypress(settings.kb_next)
        def handle_next():
            self.put_task(self.play_next)

        @self._player.on_key_press('PREV')
        @self._player.on_key_press('XF86_PREV')
        def handle_media_prev():
            if settings.media_key_seek:
                self._player.command("seek", -15)
            else:
                self.put_task(self.play_prev)

        @self._player.on_key_press('NEXT')
        @self._player.on_key_press('XF86_NEXT')
        def handle_media_next():
            if settings.media_key_seek:
                if self.is_in_intro:
                    self.skip_intro()
                else:
                    self._player.command("seek", 30)
            else:
                self.put_task(self.play_next)

        @keypress(settings.kb_watched)
        def handle_watched():
            self.put_task(self.watched_skip)

        @keypress(settings.kb_unwatched)
        def handle_unwatched():
            self.put_task(self.unwatched_quit)

        @keypress(settings.kb_menu)
        def menu_open():
            if not self.menu.is_menu_shown:
                self.menu.show_menu()
            else:
                self.menu.hide_menu()

        @keypress(settings.kb_menu_esc)
        def menu_back():
            if self.menu.is_menu_shown:
                self.menu.menu_action('back')
            else:
                self._player.command('set', 'fullscreen', 'no')

        @keypress(settings.kb_menu_ok)
        def menu_ok():
            self.menu.menu_action('ok')

        @keypress(settings.kb_menu_left)
        def menu_left():
            if self.menu.is_menu_shown:
                self.menu.menu_action('left')
            else:
                self._player.command("seek", settings.seek_left)

        @keypress(settings.kb_menu_right)
        def menu_right():
            if self.menu.is_menu_shown:
                self.menu.menu_action('right')
            else:
                if self.is_in_intro:
                    self.skip_intro()
                else:
                    self._player.command("seek", settings.seek_right)

        @keypress(settings.kb_menu_up)
        def menu_up():
            if self.menu.is_menu_shown:
                self.menu.menu_action('up')
            else:
                if self.is_in_intro:
                    self.skip_intro()
                else:
                    self._player.command("seek", settings.seek_up)

        @keypress(settings.kb_menu_down)
        def menu_down():
            if self.menu.is_menu_shown:
                self.menu.menu_action('down')
            else:
                self._player.command("seek", settings.seek_down)

        @keypress(settings.kb_pause)
        def handle_pause():
            if self.menu.is_menu_shown:
                self.menu.menu_action('ok')
            else:
                self.toggle_pause()

        # This gives you an interactive python debugger prompt.
        @keypress(settings.kb_debug)
        def handle_debug():
            import pdb
            pdb.set_trace()

        @self._player.on_key_press('ctrl+c')
        def copy_current_sub():
            try:
                sub = self._player.sub_text
                pyperclip.copy(sub)
            except AttributeError:
                pass  # no subtitle available.

        def copy_screenshot(subtitles=True):
            includes = 'subtitles' if subtitles else 'video'
            from io import BytesIO
            import win32clipboard
            image = self._player.screenshot_raw(includes=includes)
            output = BytesIO()
            image.convert("RGB").save(output, "BMP")
            data = output.getvalue()[14:]
            output.close()
            win32clipboard.OpenClipboard()
            win32clipboard.EmptyClipboard()
            win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
            win32clipboard.CloseClipboard()

        @self._player.on_key_press('ctrl+s')
        def copy_current_image():
            copy_screenshot(subtitles=True)

        @self._player.on_key_press('ctrl+shift+s')
        def copy_current_image():
            copy_screenshot(subtitles=False)

        @self._player.on_key_press('ctrl+v')
        def output_audio():
            import subprocess
            import string
            import unicodedata
            sub_delay = round(self._player.sub_delay, 4)  # round b/c of weird mpv precision
            sub_start = self._player.sub_start + sub_delay
            if sub_start:
                print("Outputting current subtitle...")
                valid_fn_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
                fn_dirty = "%s - %s" % (self._player.media_title, str(int(sub_start * 1000)))
                fn = unicodedata.normalize('NFKD', fn_dirty).encode('ASCII', 'ignore')
                fn = ''.join(chr(c) for c in fn if chr(c) in valid_fn_chars)
                aid = [x for x in self._player.track_list
                       if x.get("type") == "audio" and x.get("selected")][0].get("id")
                subprocess.Popen([
                    'mpv',
                    self.url,
                    '-o',
                    '%s.mp3' % fn,
                    '--no-video',
                    '--start=%s' % sub_start,
                    '--end=%s' % (self._player.sub_end + sub_delay),
                    '--aid=%s' % aid,
                ])
                self._player.screenshot_to_file("%s.png" % fn, includes='video')
                with open('%s.txt' % fn, 'w+', encoding='utf-8') as f:
                    f.write(self._player.sub_text)

        @self._player.on_key_press('ctrl+a')
        def toggle_auto_insert():
            self.auto_insert = not self.auto_insert
            self._player.show_text('Auto insert %s' % ("on" if self.auto_insert else "off"))

        # Fires between episodes.
        @self._player.property_observer('eof-reached')
        def handle_end(_name, reached_end):
            if self._video and reached_end:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)

        # Fires at the end.
        @self._player.event_callback('idle')
        def handle_end_idle(event):
            if self._video:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)
Exemple #11
0
 def setUp(self):
     self.disp = Xvfb()
     self.disp.start()
     self.m = mpv.MPV(vo='x11')
Exemple #12
0
def startVideo():
    gd.player = mpv.MPV()
    gd.player.pause = True
    gd.player.window_scale = 0.5
    gd.video = True
def view_files():

    player = mpv.MPV(
        autofit_larger=
        '100%x95%',  # resize video if it's larger than W%xH% of the screen
        reset_on_next_file=
        'pause',  # reset pause status on next media in playlist
        loop_file='inf',  # loop file in case of videos
        input_default_bindings=True,
        input_vo_keyboard=True)

    @player.on_key_press(DELETEKEY)
    def delete_file():
        to_delete.append(current_video)
        try:
            player.playlist_next()
        except SystemError:
            print('Playlist finished!')
            player.quit()

    @player.on_key_press(NEXTFILEKEY)
    def next_file():
        try:
            player.playlist_next()
        except SystemError:
            print("Playlist finished")
            # playlist finished
            player.quit()

    @player.on_key_press(ACCEPTKEY)
    def accept():
        print(ACCEPTKEY)
        delete_files(to_delete)

    @player.on_key_press(FULLSCREENTOGGLE)
    def fullscreen_toggle():
        print('fullscreen')
        player.fullscreen = not player.fullscreen

    player.fullscreen = True
    mediafiles = [
        os.path.join(DIRNAME, file) for file in os.listdir(DIRNAME)
        if os.path.isfile(os.path.join(DIRNAME, file))
    ]
    player.playlist_append(
        mediafiles[-1]
    )  # hack: last media is skipped, add it twice to make up for ite
    for video in mediafiles:
        player.playlist_append(video)

    player.playlist_pos = 0
    playlist_len = len(player.playlist)
    while True:
        current_video = player.playlist[player.playlist_pos]['filename']
        print("position: " + str(player.playlist_pos) + "/" +
              str(playlist_len - 1))
        if player.playlist_pos >= playlist_len - 1:
            print("reached end of playlist")
            break
        else:
            player.wait_for_playback()
Exemple #14
0
 def setUp(self):
     self.disp = Xvfb()
     self.disp.start()
     self.m = mpv.MPV(vo=testvo, loglevel='debug', log_handler=timed_print())
Exemple #15
0
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
from urllib.parse import urlencode
from urllib.request import Request, urlopen
import codecs
from subprocess import call
from subprocess import Popen
import mpv

main = codecs.open("main.html", 'r', 'utf-8').read()

hostName = "0.0.0.0"
hostPort = 8888

player = mpv.MPV(ytdl=True)

def ytLink(number):
    yt = ['https://www.youtube.com/watch?v=xxG2UWhvXJI', 'https://youtu.be/LO2RPDZkY88', 'https://youtu.be/jbt6UWc1ZKo', 'https://youtu.be/WC5FdFlUcl0']
    intNum = int(number[1])
    return(yt[intNum])


class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes(main, "utf-8"))
    def do_POST(self):
        choice = ytLink(self.path)
        print(choice)
Exemple #16
0
    def __init__(self):
        mpv_config = conffile.get(APP_NAME,"mpv.conf", True)
        input_config = conffile.get(APP_NAME,"input.conf", True)
        extra_options = {}
        self._media_item = None
        self._lock = RLock()
        self._finished_lock = Lock()
        self.last_update = Timer()
        self.__part = 1
        self.timeline_trigger = None
        self.action_trigger = None
        self.external_subtitles = {}
        self.external_subtitles_rev = {}
        self.url = None
        self.evt_queue = Queue()
        self.is_in_intro = False
        self.intro_has_triggered = False

        if is_using_ext_mpv:
            extra_options = {
                "start_mpv": settings.mpv_ext_start,
                "ipc_socket": settings.mpv_ext_ipc,
                "mpv_location": settings.mpv_ext_path,
                "player-operation-mode": "cplayer"
            }
        self._player = mpv.MPV(input_default_bindings=True, input_vo_keyboard=True,
                               input_media_keys=True, include=mpv_config, input_conf=input_config,
                               log_handler=mpv_log_handler, loglevel=settings.mpv_log_level,
                               **extra_options)
        self.menu = OSDMenu(self)
        if hasattr(self._player, 'osc'):
            self._player.osc = settings.enable_osc
        else:
            log.warning("This mpv version doesn't support on-screen controller.")

        # Wrapper for on_key_press that ignores None.
        def keypress(key):
            def wrapper(func):
                if key is not None:
                    self._player.on_key_press(key)(func)
                return func
            return wrapper

        @self._player.on_key_press('CLOSE_WIN')
        @self._player.on_key_press('STOP')
        @keypress(settings.kb_stop)
        def handle_stop():
            self.stop()
            self.timeline_handle()

        @keypress(settings.kb_prev)
        def handle_prev():
            self.put_task(self.play_prev)

        @keypress(settings.kb_next)
        def handle_next():
            self.put_task(self.play_next)

        @self._player.on_key_press('PREV')
        @self._player.on_key_press('XF86_PREV')
        def handle_media_prev():
            if settings.media_key_seek:
                self._player.command("seek", -15)
            else:
                self.put_task(self.play_prev)

        @self._player.on_key_press('NEXT')
        @self._player.on_key_press('XF86_NEXT')
        def handle_media_next():
            if settings.media_key_seek:
                if self.is_in_intro:
                    self.skip_intro()
                else:
                    self._player.command("seek", 30)
            else:
                self.put_task(self.play_next)

        @keypress(settings.kb_watched)
        def handle_watched():
            self.put_task(self.watched_skip)

        @keypress(settings.kb_unwatched)
        def handle_unwatched():
            self.put_task(self.unwatched_quit)

        @keypress(settings.kb_menu)
        def menu_open():
            if not self.menu.is_menu_shown:
                self.menu.show_menu()
            else:
                self.menu.hide_menu()

        @keypress(settings.kb_menu_esc)
        def menu_back():
            if self.menu.is_menu_shown:
                self.menu.menu_action('back')
            else:
                self._player.command('set', 'fullscreen', 'no')

        @keypress(settings.kb_menu_ok)
        def menu_ok():
            self.menu.menu_action('ok')

        @keypress(settings.kb_menu_left)
        def menu_left():
            if self.menu.is_menu_shown:
                self.menu.menu_action('left')
            else:
                self._player.command("seek", settings.seek_left)

        @keypress(settings.kb_menu_right)
        def menu_right():
            if self.menu.is_menu_shown:
                self.menu.menu_action('right')
            else:
                if self.is_in_intro:
                    self.skip_intro()
                else:
                    self._player.command("seek", settings.seek_right)

        @keypress(settings.kb_menu_up)
        def menu_up():
            if self.menu.is_menu_shown:
                self.menu.menu_action('up')
            else:
                if self.is_in_intro:
                    self.skip_intro()
                else:
                    self._player.command("seek", settings.seek_up)

        @keypress(settings.kb_menu_down)
        def menu_down():
            if self.menu.is_menu_shown:
                self.menu.menu_action('down')
            else:
                self._player.command("seek", settings.seek_down)

        @keypress(settings.kb_pause)
        def handle_pause():
            if self.menu.is_menu_shown:
                self.menu.menu_action('ok')
            else:
                self.toggle_pause()

        # This gives you an interactive python debugger prompt.
        @keypress(settings.kb_debug)
        def handle_debug():
            import pdb
            pdb.set_trace()

        # Fires between episodes.
        @self._player.property_observer('eof-reached')
        def handle_end(_name, reached_end):
            if self._media_item and reached_end:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)

        # Fires at the end.
        @self._player.event_callback('idle')
        def handle_end_idle(event):
            if self._media_item:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)
Exemple #17
0
	def load_stream_player(self, player):
		mpv_player = mpv.MPV(vf="crop=600:1080:500:0", geometry="+960+0", speed="1.1", no_correct_pts="yes", demuxer_thread="no", osc="yes", border=False, fps="60", ontop=False, profile="low-latency", cache="no", untimed="yes", rtsp_transport="tcp", aid="no", input_vo_keyboard=True, brightness="0")
		if player == 1:
			self.main_player_1 = mpv_player
		elif player == 2:
			self.main_player_2 = mpv_player
Exemple #18
0
#import mpv
#player = mpv.MPV(ytdl=True)
#player.play('https://youtu.be/DOmdB7D-pUU')

#!/usr/bin/env python3
import mpv


def my_log(loglevel, component, message):
    print('[{}] {}: {}'.format(loglevel, component, message))


player = mpv.MPV(log_handler=my_log,
                 ytdl=True,
                 input_default_bindings=True,
                 input_vo_keyboard=True)


# Property access, these can be changed at runtime
@player.property_observer('time-pos')
def time_observer(_name, value):
    # Here, _value is either None if nothing is playing or a float containing
    # fractional seconds since the beginning of the file.
    print('Now playing at {:.2f}s'.format(value))


player.fullscreen = True
player.loop_playlist = 'inf'
# Option access, in general these require the core to reinitialize
player['vo'] = 'gpu'
Exemple #19
0
# os.environ['PATH']=dllspath+os.pathsep+os.environ['PATH']
# os.add_dll_directory("C:\Program Files (x86)\mpv-1.dll")
import re
import subprocess
import time
import urllib.parse
import urllib.request
from tkinter import *

import mpv
import requests
import vlc  # pip install python-vlc
from bs4 import BeautifulSoup

root = Tk()
mPlayer = mpv.MPV(ytdl=True, video=False)
root.title("Test MPV Program")
# vlc_instance=vlc.Instance()
# player = vlc_instance.media_player_new()
playing = BooleanVar()
res_pause = StringVar()
res_pause.set("__")

query_url = StringVar()
query_url.set("")
query_title = StringVar()
query_title.set("")
query_thumbnail = ""
display_var = StringVar()
display_var.set("Enter a song name")
Exemple #20
0
# All of the tidalapi classes are inherited from Model which has a .name
# Add a __str__ function so when things are converted to strings, they
# return their .name. Applied to Tracks/Albums/Artists/Playlists/etc
def patch__str__(self):
    return self.name


setattr(tidalapi.models.Model, '__str__', patch__str__)

#
#   CREATE OBJECTS
#

# Get the mpv player up and running
player = mpv.MPV()
# ! Check for errors

# Establish the Tidal session using the Kodi tidalapi library
session = tidalapi.Session()

# Create list to keep track of playlist. Can't use mpv since the URLs given back from
# Tidal have expiration dates. Usually, you can get 6 or so tracks in before the URLs
# start to go bad, but this object just fetches a URL as needed
internal_playlist = DoubleLinkedList()

#
#   LOGIN TO TIDAL
#
#   Use the tidalapi to login, give the user 3 attempts before aborting
#
Exemple #21
0
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(300, 300))
        panel = wx.Panel(self)
        box = wx.BoxSizer(wx.VERTICAL)
        lbl = wx.StaticText(panel, 10, style=wx.ALIGN_CENTER)
        # label.SetLabel("Duration")
        font = wx.Font(8, wx.ROMAN, wx.ITALIC, wx.NORMAL)
        lbl.SetFont(font)
        lbl.SetLabel("me")
        box.Add(lbl, 20, wx.ALIGN_CENTER)

        self.url1 = "http://funasia.streamguys1.com/live3"
        self.mpvAudio = mpv.MPV()
        # self.mpvAudio.play(self.url1)
        self.playing = False
        self.CreateStatusBar()  # status bar
        self.elapsed = ""
        self.recFile = None
        self.recording = False
        self.probe = None
        btn = wx.Button()

        @self.mpvAudio.property_observer('time-pos')
        def time_observer(name, val):
            try:
                wholeSecs = round(val)
            except:
                wholeSecs = 0
            sep = ":"
            hr = 0
            min1 = 0
            sec = 0
            elapsedTemp = ""

            if wholeSecs < 3600:
                min1 = wholeSecs // 60
                sec = wholeSecs % 60
                elapsedTemp = str(min1) + sep + str(sec).zfill(2)
                #print("Debug ",elapsed)
            elif wholeSecs >= 3600:
                hr = wholeSecs // 3600
                lo = wholeSecs % 3600
                if lo < 60:
                    min1 = lo // 60
                    sec = lo % 60
                else:
                    sec = lo
                elapsedTemp = str(hr) + sep + str(min1).zfill(2) + sep + str(
                    sec).zfill(2)

            if elapsedTemp != self.elapsed:
                self.elapsed = elapsedTemp
                print("Now Playing at: ", self.elapsed)

        filemenu = wx.Menu()

        menuAbout = filemenu.Append(wx.ID_ABOUT, "&About",
                                    "Info about this app")
        filemenu.AppendSeparator()
        menuOpen = filemenu.Append(wx.ID_OPEN, "&Open", "Open File")
        menuExit = filemenu.Append(wx.ID_EXIT, "&Exit", "Terminate")
        # menuStop = filemenu.Append(wx.ID_STOP, "&Stop" ,"Stop")
        menuPlay = filemenu.Append(wx.ID_ANY, "&Play", "Play")
        menuRec = filemenu.Append(wx.ID_ANY, "&Rec", "Record")

        # menubar
        mb = wx.MenuBar()
        mb.Append(filemenu, "&File")
        self.SetMenuBar(mb)  # add to frame

        #events

        self.Bind(wx.EVT_MENU, self.onAbout, menuAbout)
        self.Bind(wx.EVT_MENU, self.onOpen, menuOpen)
        self.Bind(wx.EVT_MENU, self.onExit, menuExit)
        # self.Bind(wx.EVT_MENU,self.onStop,menuStop)
        self.Bind(wx.EVT_MENU, self.onPlay, menuPlay)
        self.Bind(wx.EVT_MENU, self.onRecord, menuRec)
        # self.Bind(wx.EVT_MENU, self.recStop,menuRstop)

        self.Show(True)
Exemple #22
0
#!/usr/bin/python3

import mpv
player = mpv.MPV(ytdl=False)
player['vid'] = 'no'

@player.property_observer('time-pos')
def time_observer(_name, value):
  # Here, _value is either None if nothing is playing or a float containing
  # fractional seconds since the beginning of the file.
  # print('Now playing at {:.2f}s'.format(value))
  print('Now playing at ', str(value))

player.play('track.mp3')
player.wait_for_playback()    
Exemple #23
0
 def setUp(self):
     self.m = mpv.MPV()
Exemple #24
0
    def __init__(self, val, screenwidth, screenheight, parent=None):
        super().__init__(parent)
        self.setWindowTitle("qtube")

        app_exit_shortcuts = ["Ctrl+Q", "Ctrl+W"]
        for sc in app_exit_shortcuts:
            exitshortcut = QShortcut(QKeySequence(sc), self)
            exitshortcut.activated.connect(self.exit_seq)

        backshortcut = QShortcut(QKeySequence('Alt+Left'), self)
        backshortcut.activated.connect(self.on_back_clicked)

        self.setStyleSheet("background-color: " + BACKGROUND_COLOR + ";")

        self.mygroupbox = QGroupBox('')
        self.mygroupbox.setStyleSheet("color: " + FOREGROUND_COLOR +
                                      "; font-family: " + FONT +
                                      "; font-style: italic")
        self.myform = QFormLayout()
        labellist = []
        combolist = []

        self.mygroupbox.setLayout(self.myform)
        self.scroll = QScrollArea()
        self.scroll.setWidget(self.mygroupbox)
        self.scroll.setWidgetResizable(True)
        self.scroll.setStyleSheet("color: " + FOREGROUND_COLOR + ";")

        self.history = {
            'urls': [],
            'title_boxes': [],
            'data': [],
            'page_numbers': []
        }
        self.downloaded_videos = {'paths': [], 'short_titles': []}
        self.search = ''

        self.spinner = QtWaitingSpinner(self, False)
        self.spinner.setRoundness(70.0)
        self.spinner.setMinimumTrailOpacity(15.0)
        self.spinner.setTrailFadePercentage(70.0)
        self.spinner.setNumberOfLines(10)
        self.spinner.setLineLength(10)
        self.spinner.setLineWidth(4)
        self.spinner.setInnerRadius(4)
        self.spinner.setRevolutionsPerSecond(1.5)
        self.spinner.setColor(QColor(FOREGROUND_COLOR))

        # multi-threading
        QThread.currentThread().setObjectName(
            'main')  # threads can be named, useful for log output
        self.__workers_done = []
        self.__threads = []

        self.line = QLineEdit(self)
        self.line.returnPressed.connect(self.clickMethod)
        self.line.setStyleSheet("color: " + FOREGROUND_COLOR +
                                "; background-color: " + BACKGROUND_COLOR +
                                "; border: 1px solid " + FOREGROUND_COLOR +
                                "; font-family: " + FONT + ";")

        active_buttons = []
        self.inactive_buttons = []

        self.search_button = QPushButton()
        self.search_button.setText('Search')
        self.search_button.clicked.connect(self.clickMethod)
        active_buttons.append(self.search_button)

        self.home_button = QPushButton()
        self.home_button.setText('Home')
        self.home_button.clicked.connect(self.on_home_clicked)
        self.inactive_buttons.append(self.home_button)

        self.play_playlist_button = QPushButton()
        self.play_playlist_button.setText('Play All')
        self.play_playlist_button.clicked.connect(
            self.on_play_playlist_clicked)
        active_buttons.append(self.play_playlist_button)

        self.back_button = QPushButton()
        self.back_button.setText('Back')
        self.back_button.clicked.connect(self.on_back_clicked)
        self.inactive_buttons.append(self.back_button)

        for b in active_buttons:
            b.setStyleSheet("color: " + FOREGROUND_COLOR +
                            "; background-color: " + BACKGROUND_COLOR +
                            "; border: 1px solid " + FOREGROUND_COLOR +
                            "; font-family: " + FONT + ";")
            b.setCursor(Qt.PointingHandCursor)

        for b in self.inactive_buttons:
            b.setStyleSheet("color: " + INACTIVE_COLOR +
                            "; background-color: " + BACKGROUND_COLOR +
                            "; border: 1px solid " + INACTIVE_COLOR +
                            "; font-family: " + FONT + ";")

        self.download_label = QLabel()
        self.download_label.setText('0 downloads')
        self.download_label.setMaximumSize(QSize(110, 20))
        self.download_label.setStyleSheet("color: " + INACTIVE_COLOR +
                                          "; background-color: " +
                                          BACKGROUND_COLOR +
                                          "; font-family: " + FONT + ";")

        self.download_selector = QComboBox()
        self.download_selector.setStyleSheet("color: " + INACTIVE_COLOR +
                                             "; background-color: " +
                                             BACKGROUND_COLOR +
                                             "; font-family: " + FONT + ";")
        self.download_selector.currentIndexChanged.connect(
            self.select_download)

        self.download_to_play = ''

        self.play_downloaded_button = QPushButton()
        self.play_downloaded_button.setText('Play')
        self.play_downloaded_button.clicked.connect(self.on_play_downloaded)
        self.play_downloaded_button.setMaximumSize(QSize(50, 20))
        self.play_downloaded_button.setStyleSheet("color: " + INACTIVE_COLOR +
                                                  "; background-color: " +
                                                  BACKGROUND_COLOR +
                                                  "; border: 1px solid " +
                                                  INACTIVE_COLOR +
                                                  "; font-family: " + FONT +
                                                  ";")

        self.container = VideoContainer(PLAYER_SIZE)
        self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
        self.container.setAttribute(Qt.WA_NativeWindow)
        #self.container.sig_height.connect(self.resizeWindow)

        self.player = mpv.MPV(
            wid=str(int(self.container.winId())),
            ytdl=True,
            input_default_bindings=True,
            input_vo_keyboard=True,
            keep_open=True,
            reset_on_next_file='pause',
            osd_bar=True,
        )

        script_dir = str(Path.home()) + '/.config/mpv/scripts/'
        [
            self.player.command('load-script', script_dir + script)
            for script in os.listdir(script_dir)
        ]

        player_exit_shortcuts = ['q', 'ctrl+q', 'ctrl+w']
        for sc in player_exit_shortcuts:
            self.player.register_key_binding(sc, self.exit_seq)

        self.player.register_key_binding('f', self.fullscreen)
        self.player.register_key_binding('esc', self.fullscreen_off)
        self.isFullScreen = False

        self.player.register_key_binding('WHEEL_LEFT', 'seek 1')
        self.player.register_key_binding('WHEEL_RIGHT', 'seek -1')

        searchbarlayout = QHBoxLayout()
        searchbarlayout.addWidget(self.line)
        searchbarlayout.addWidget(self.search_button)
        searchbarlayout.addWidget(self.spinner)
        searchbar = QWidget()
        searchbar.setLayout(searchbarlayout)

        buttonrowlayout = QHBoxLayout()
        buttonrowlayout.addWidget(self.back_button)
        buttonrowlayout.addWidget(self.home_button)
        buttonrowlayout.addWidget(self.play_playlist_button)
        buttonrow = QWidget()
        buttonrow.setLayout(buttonrowlayout)

        downloadrowlayout = QHBoxLayout()
        downloadrowlayout.addWidget(self.download_label)
        downloadrowlayout.addWidget(self.download_selector)
        downloadrowlayout.addWidget(self.play_downloaded_button)
        downloadrow = QWidget()
        downloadrow.setLayout(downloadrowlayout)

        sublayout = QVBoxLayout()
        sublayout.addWidget(searchbar)
        sublayout.addWidget(buttonrow)
        sublayout.addWidget(self.scroll)
        sublayout.addWidget(downloadrow)
        self.left = QWidget()
        self.left.setLayout(sublayout)
        self.left.setFixedWidth(LIST_WIDTH)

        biglayout = QHBoxLayout(self)
        biglayout.addWidget(self.left)
        biglayout.addWidget(self.container)
        biglayout.setContentsMargins(0, 0, 0, 0)

        self.move(int((screenwidth - PLAYER_SIZE.width() - LIST_WIDTH) / 2),
                  int((screenheight - PLAYER_SIZE.height()) / 2))

        # load home page data
        self.spinner.start()

        idx = 'Home'
        worker = Worker(idx, HOME_URL, search=False)
        thread = QThread()
        thread.setObjectName('thread_' + idx)
        worker.moveToThread(thread)

        worker.sig_data.connect(self.on_click_data_received)

        self.sig_abort_workers.connect(worker.abort)

        thread.started.connect(worker.grabData)
        thread.start()
        self.__threads.append((thread, worker))
Exemple #25
0
 def start_playing(self):
     if not self.player:
         self.player = mpv.MPV(video=False)
     thread = threading.Thread(target=self.continous_player, args={})
     thread.daemon = True
     thread.start()
Exemple #26
0
    def start_server(cls, visibility=False, ao="alsa:device=[plughw:1,0]"):
        if os.path.isfile(PLAYLIST_FILE):
            f = open(PLAYLIST_FILE, "r")
            try:
                cls.playlist = json.loads(f.read())
            except:
                pass
            finally:
                f.close()
        else:
            cls.playlist = []
        
        cls.currently_playing = None
        cls.user_selected_flag = False
        cls.shutdown_flag = False
        cls.lock = threading.Lock()
        cls.play_lock = threading.Lock()
        cls.mpv = mpv.MPV(None, no_video="", ao=ao)
        cls.volume = 100.0
        cls.play_queue = queue.Queue(maxsize=50)

        # threaded debug
        if DEBUG:
            cls._thread_debug = threading.Thread(target=cls._debug)
            cls._thread_debug.start()

        # threaded broadcast of position
        cls._thread_broadcast_pos = threading.Thread(target=cls._broadcast_position)
        cls._thread_broadcast_pos.start()

        # threaded play
        cls._thread_play = threading.Thread(target=cls._play)
        cls._thread_play.start()

        # start mpv listeners
        cls.mpv.register_event_callback(mpv.MpvEventID.END_FILE, cls._mpv_eof)

        # set mpv to paused initially
        cls.mpv.pause = True

        cherrypy_config = {
            "/rq": {
                "tools.websocket.on": True,
                "tools.websocket.handler_cls": JukeboxWebWorker,
                "tools.secureheaders.on": True,
            }
        }
        cherrypy.config.update({
            "log.access_file": "access_log",
            "log.error_file": "error_log"
        })

        cherrypy.config.update({"server.socket_port": WS_PORT})
        if visibility:
            cherrypy.config.update({"server.socket_host": "0.0.0.0"})

        # set the priority according to your needs if you are hooking something
        # else on the 'before_finalize' hook point.
        cherrypy.tools.secureheaders = cherrypy.Tool('before_finalize', secureheaders, priority=60)

        cls._wsp = WebSocketPlugin(cherrypy.engine)
        cls._wsp.subscribe()
        cherrypy.tools.websocket = WebSocketTool()

        cherrypy.engine.subscribe("stop", cls.stop_server)

        cherrypy.quickstart(JukeboxWebService(), "/", config=cherrypy_config)
Exemple #27
0
    def __init__(self):
        mpv_config = conffile.get(APP_NAME, "mpv.conf", True)
        input_config = conffile.get(APP_NAME, "input.conf", True)
        self._video = None
        extra_options = {}
        self.timeline_trigger = None
        self.action_trigger = None
        self.external_subtitles = {}
        self.external_subtitles_rev = {}
        self.should_send_timeline = False
        self.start_time = None
        self.url = None
        self.evt_queue = Queue()
        self._lock = RLock()
        self._tl_lock = RLock()
        self._finished_lock = Lock()
        self.last_update = Timer()
        self._jf_settings = None
        self.get_webview = lambda: None
        self.pause_ignore = None  # Used to ignore pause events that come from us.
        self.last_seek = None
        self.update_check = UpdateChecker(self)

        if is_using_ext_mpv:
            extra_options = {
                "start_mpv": settings.mpv_ext_start,
                "ipc_socket": settings.mpv_ext_ipc,
                "mpv_location": settings.mpv_ext_path,
                "player-operation-mode": "cplayer"
            }
        self._player = mpv.MPV(input_default_bindings=True,
                               input_vo_keyboard=True,
                               input_media_keys=True,
                               include=mpv_config,
                               input_conf=input_config,
                               log_handler=mpv_log_handler,
                               loglevel=settings.mpv_log_level,
                               **extra_options)
        self.menu = OSDMenu(self)
        self.syncplay = SyncPlayManager(self)

        self._player['demuxer-max-bytes'] = '800000000'

        if hasattr(self._player, 'osc'):
            self._player.osc = settings.enable_osc
        else:
            log.warning(
                "This mpv version doesn't support on-screen controller.")

        # Wrapper for on_key_press that ignores None.
        def keypress(key):
            def wrapper(func):
                if key is not None:
                    self._player.on_key_press(key)(func)
                return func

            return wrapper

        @self._player.on_key_press('CLOSE_WIN')
        @self._player.on_key_press('STOP')
        @keypress(settings.kb_stop)
        def handle_stop():
            self.stop()

        @keypress(settings.kb_prev)
        def handle_prev():
            self.put_task(self.play_prev)

        @keypress(settings.kb_next)
        def handle_next():
            self.put_task(self.play_next)

        @self._player.on_key_press('PREV')
        @self._player.on_key_press('XF86_PREV')
        def handle_media_prev():
            if settings.media_key_seek:
                seektime, _x = self.get_seek_times()
                self.seek(seektime)
            else:
                self.put_task(self.play_prev)

        @self._player.on_key_press('NEXT')
        @self._player.on_key_press('XF86_NEXT')
        def handle_media_next():
            if settings.media_key_seek:
                _x, seektime = self.get_seek_times()
                self.seek(seektime)
            else:
                self.put_task(self.play_next)

        @keypress(settings.kb_watched)
        def handle_watched():
            self.put_task(self.watched_skip)

        @keypress(settings.kb_unwatched)
        def handle_unwatched():
            self.put_task(self.unwatched_quit)

        @keypress(settings.kb_menu)
        def menu_open():
            if not self.menu.is_menu_shown:
                self.menu.show_menu()
            else:
                self.menu.hide_menu()

        @keypress(settings.kb_menu_esc)
        def menu_back():
            if self.menu.is_menu_shown:
                self.menu.menu_action('back')
            else:
                self._player.command('set', 'fullscreen', 'no')

        @keypress(settings.kb_menu_ok)
        def menu_ok():
            self.menu.menu_action('ok')

        @keypress(settings.kb_menu_left)
        def menu_left():
            if self.menu.is_menu_shown:
                self.menu.menu_action('left')
            else:
                seektime = settings.seek_left
                if settings.use_web_seek:
                    seektime, _x = self.get_seek_times()
                self.seek(seektime)

        @keypress(settings.kb_menu_right)
        def menu_right():
            if self.menu.is_menu_shown:
                self.menu.menu_action('right')
            else:
                seektime = settings.seek_right
                if settings.use_web_seek:
                    _x, seektime = self.get_seek_times()
                self.seek(seektime)

        @keypress(settings.kb_menu_up)
        def menu_up():
            if self.menu.is_menu_shown:
                self.menu.menu_action('up')
            else:
                self.seek(settings.seek_up)

        @keypress(settings.kb_menu_down)
        def menu_down():
            if self.menu.is_menu_shown:
                self.menu.menu_action('down')
            else:
                self.seek(settings.seek_down)

        @keypress(settings.kb_pause)
        def handle_pause():
            if self.menu.is_menu_shown:
                self.menu.menu_action('ok')
            else:
                self.toggle_pause()

        # This gives you an interactive python debugger prompt.
        @keypress(settings.kb_debug)
        def handle_debug():
            import pdb
            pdb.set_trace()

        # Fires between episodes.
        @self._player.property_observer('eof-reached')
        def handle_end(_name, reached_end):
            if self._video and reached_end:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)

        # Fires at the end.
        @self._player.property_observer('playback-abort')
        def handle_end_idle(name, value):
            if self._video and value:
                has_lock = self._finished_lock.acquire(False)
                self.put_task(self.finished_callback, has_lock)

        @self._player.property_observer("seeking")
        def handle_seeking(name, value):
            if self.syncplay.is_enabled():
                play_time = self._player.playback_time
                if (play_time is not None and self.last_seek is not None
                        and abs(self.last_seek - play_time) > 10):
                    log.info("Reverting sync for syncplay.")
                    self._player.command("revert-seek")
                    self.syncplay.seek_request(play_time)
                else:
                    log.debug("SyncPlay Buffering: {0}".format(value))
                    if value:
                        self.syncplay.on_buffer()
                    else:
                        self.syncplay.on_buffer_done()

        @self._player.property_observer("pause")
        def pause_handler(_name, value):
            if not self._player.playback_abort:
                self.timeline_handle()

            if value != self.pause_ignore:
                if self.syncplay.is_enabled():
                    if value:
                        self.syncplay.pause_request()
                    else:
                        # Don't allow unpausing locally through MPV.
                        self.syncplay.play_request()
                        self.set_paused(True, True)
Exemple #28
0
 def __init__( self, parent ):
     
     CAC.ApplicationCommandProcessorMixin.__init__( self )
     QW.QWidget.__init__( self, parent )
     
     self._canvas_type = CC.CANVAS_PREVIEW
     
     self._stop_for_slideshow = False
     
     # 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.
     locale.setlocale( locale.LC_NUMERIC, 'C' )
     
     self.setAttribute( QC.Qt.WA_DontCreateNativeAncestors )
     self.setAttribute( QC.Qt.WA_NativeWindow )
     
     loglevel = 'debug' if HG.mpv_report_mode else 'fatal'
     
     # loglevels: fatal, error, debug
     self._player = mpv.MPV( wid = str( int( self.winId() ) ), log_handler = log_handler, loglevel = loglevel )
     
     # hydev notes on OSC:
     # OSC is by default off, default input bindings are by default off
     # difficult to get this to intercept mouse/key events naturally, so you have to pipe them to the window with 'command', but this is not excellent
     # general recommendation when using libmpv is to just implement your own stuff anyway, so let's do that for prototype
     
     #self._player[ 'input-default-bindings' ] = True
     
     self.UpdateConf()
     
     self._player.loop = True
     
     # this makes black screen for audio (rather than transparent)
     self._player.force_window = True
     
     # this actually propagates up to the OS-level sound mixer lmao, otherwise defaults to ugly hydrus filename
     self._player.title = 'hydrus mpv player'
     
     # pass up un-button-pressed mouse moves to parent, which wants to do cursor show/hide
     self.setMouseTracking( True )
     #self.setFocusPolicy(QC.Qt.StrongFocus)#Needed to get key events
     self._player.input_cursor = False#Disable mpv mouse move/click event capture
     self._player.input_vo_keyboard = False#Disable mpv key event capture, might also need to set input_x11_keyboard
     
     self._media = None
     
     self._file_is_loaded = False
     self._disallow_seek_on_this_file = False
     
     self._times_to_play_gif = 0
     
     self._current_seek_to_start_count = 0
     
     self._InitialiseMPVCallbacks()
     
     self.destroyed.connect( self._player.terminate )
     
     HG.client_controller.sub( self, 'UpdateAudioMute', 'new_audio_mute' )
     HG.client_controller.sub( self, 'UpdateAudioVolume', 'new_audio_volume' )
     HG.client_controller.sub( self, 'UpdateConf', 'notify_new_options' )
     HG.client_controller.sub( self, 'SetLogLevel', 'set_mpv_log_level' )
     
     self._my_shortcut_handler = ClientGUIShortcuts.ShortcutsHandler( self, [], catch_mouse = True )
Exemple #29
0
    def test_custom_stream(self):
        handler = mock.Mock()
        fail_mock = mock.Mock(side_effect=ValueError)
        stream_mock = mock.Mock()
        stream_mock.seek = mock.Mock(return_value=0)
        stream_mock.read = mock.Mock(return_value=b'')

        disp = Xvfb()
        disp.start()
        m = mpv.MPV(video=False)
        m.register_event_callback(handler)

        m.register_stream_protocol('pythonfail', fail_mock)

        @m.register_stream_protocol('pythonsuccess')
        def open_fn(uri):
            self.assertEqual(uri, 'pythonsuccess://foo')
            return stream_mock

        m.play('pythondoesnotexist://foo')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.LOADING_FAILED
            }
        })
        handler.reset_mock()

        m.play('pythonfail://foo')
        m.wait_for_playback()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.LOADING_FAILED
            }
        })
        handler.reset_mock()

        m.play('pythonsuccess://foo')
        m.wait_for_playback()
        stream_mock.seek.assert_any_call(0)
        stream_mock.read.assert_called()
        handler.assert_any_call({
            'reply_userdata': 0,
            'error': 0,
            'event_id': mpv.MpvEventID.END_FILE,
            'event': {
                'reason': mpv.MpvEventEndFile.ERROR,
                'error': mpv.ErrorCode.UNKNOWN_FORMAT
            }
        })

        m.terminate()
        disp.stop()
Exemple #30
0
def main():
    global player
    parser = argparse.ArgumentParser(description='simple queue player for mpv')
    parser.add_argument('files', metavar="URL/PATH", default=None, nargs='*')
    parser.add_argument(
        '-p',
        '--property',
        metavar=("KEY", "VALUE"),
        nargs=2,
        default=[],
        action='append',
        help=
        "set mpv property KEY to VALUE. See all available properties with 'mpv --list-properties'"
    )
    parser.add_argument('-v',
                        '--video',
                        action='store_true',
                        help="Enable video. Shorthand for '-p video auto'")

    args = parser.parse_args()

    props = default_properties

    # assemble dict from properties from command line
    custom_props = {p[0]: p[1] for p in args.property}

    # override/add properties from arguments
    props.update(custom_props)

    if args.video:
        props['video'] = "auto"

    player = mpv.MPV(**props)

    @player.on_key_press('a')
    def ask_url():
        """Ask for filename/URL to append to the playlist"""
        def cb(url):
            if url != "":
                player.playlist_append(url)

        prompt("Enter URL or file name", cb)

    @player.on_key_press('c')
    def ask_command():
        """Open playlist editing command prompt.
        Available commands listed in HELP_COMMANDS"""

        prompt("Enter command (or 'h' for help)", handle_command)

    @player.property_observer('playlist')
    def playlist_observer(_name, value):
        """Make sure playlist_pos is set, display playlist.
        Gets called if items in playlist or position in playlist changes."""

        if len(player.playlist) > 0:
            if player.playlist_pos is None:
                # when adding a title to an empty playlist, mpv doesn't automatically start playback,
                # this does the job.
                player.playlist_pos = 0

        print_playlist()

    greet()

    if len(args.files) > 0:
        for f in args.files:
            player.playlist_append(f)
    else:
        ask_url()

    # slightly ugly; but makes sure this thread terminates when mpv terminates
    # there probably is a better way to do this.
    player._event_thread.join()