From: James Bunton Date: Sun, 17 Feb 2013 00:47:06 +0000 (+1100) Subject: Run mplayer in a background thread so it doesn't block UI X-Git-Url: https://code.delx.au/bluplayer/commitdiff_plain/5c5a98bfd5f83a422d61cfe0f71e34d0bdb8836d?ds=sidebyside Run mplayer in a background thread so it doesn't block UI --- diff --git a/bluplayer.py b/bluplayer.py index 15f6c97..4b6f2b8 100755 --- a/bluplayer.py +++ b/bluplayer.py @@ -67,17 +67,6 @@ class Title(object): def __str__(self): return "Title%s: %s %s" % (self.id, self.duration, self.video_url) - def play(self): - cmd = [ - MPLAYER_PATH, - "-fs", - "-lavdopts", "threads=%s" % subprocess.check_output("nproc").strip(), - "-volume", "100", - self.video_url, - ] - logging.info("Running mplayer: %s", self.video_url) - subprocess.check_call(cmd) - class MakeMkvCon(object): def __init__(self, params): @@ -124,6 +113,27 @@ class MakeMkvCon(object): self.buf += data +class MPlayer(QObject): + play_finished = pyqtSignal() + fatal_error = pyqtSignal(str) + + def play(self, video_url): + logging.info("Running mplayer: %s", video_url) + try: + cmd = [ + MPLAYER_PATH, + "-fs", + "-lavdopts", "threads=%s" % subprocess.check_output("nproc").strip(), + "-volume", "100", + video_url, + ] + subprocess.check_call(cmd) + except Exception, e: + self.fatal_error.emit(format_exception("MPlayer failed to play the video", e)) + finally: + self.play_finished.emit() + + class MakeMkv(QObject): title_loaded = pyqtSignal(Title) title_load_complete = pyqtSignal() @@ -203,13 +213,17 @@ class MakeMkv(QObject): class PlayerWindow(QWidget): + video_selected = pyqtSignal(str) + def __init__(self): QWidget.__init__(self) + self.title_map = {} + self.is_playing = False self.list_widget = QListWidget(self) self.list_widget.itemActivated.connect(self.handle_activated) - self.list_widget.setFocus() + self.list_widget.setEnabled(False) self.log = QTextEdit(self) self.log.setReadOnly(True) @@ -239,6 +253,8 @@ class PlayerWindow(QWidget): longest_title = title longest_item = item self.list_widget.setCurrentItem(longest_item) + self.list_widget.setEnabled(True) + self.list_widget.setFocus() def add_log_entry(self, text): self.log.append(text) @@ -248,12 +264,18 @@ class PlayerWindow(QWidget): qApp.quit() def handle_activated(self, item): + if self.is_playing: + return name = str(item.text()) title = self.title_map[name] - try: - title.play() - except Exception, e: - popup_error_exit("MPlayer failed to play the video", e) + self.is_playing = True + self.list_widget.setEnabled(False) + self.video_selected.emit(title.video_url) + + def set_play_finished(self): + self.is_playing = False + self.list_widget.setEnabled(True) + self.list_widget.setFocus() def keyPressEvent(self, e): if e.key() in (Qt.Key_Escape, Qt.Key_Backspace): @@ -269,6 +291,7 @@ def killall_makemkvcon(): def main(): logging.basicConfig(format="%(levelname)s: %(message)s") logging.getLogger().setLevel(logging.DEBUG) + logging.info("Configuring application") app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(True) @@ -282,24 +305,35 @@ def main(): player_window.show() makemkv = MakeMkv() - worker_thread = QThread() - makemkv.moveToThread(worker_thread) + makemkv_thread = QThread() + makemkv.moveToThread(makemkv_thread) - worker_thread.started.connect(makemkv.run) + mplayer = MPlayer() + mplayer_thread = QThread() + mplayer.moveToThread(mplayer_thread) + + makemkv_thread.started.connect(makemkv.run) makemkv.title_loaded.connect(player_window.add_title) makemkv.title_load_complete.connect(player_window.select_longest_title) makemkv.status.connect(player_window.add_log_entry) makemkv.fatal_error.connect(player_window.popup_fatal_error) - logging.info("Starting worker thread") - worker_thread.start() + player_window.video_selected.connect(mplayer.play) + mplayer.play_finished.connect(player_window.set_play_finished) + + logging.info("Starting application") + makemkv_thread.start() + mplayer_thread.start() result = app.exec_() logging.info("Shutting down") - worker_thread.quit() + makemkv_thread.quit() + mplayer_thread.quit() killall_makemkvcon() - logging.info("Waiting for worker thread") - worker_thread.wait(2000) + logging.info("Waiting for makemkv thread") + makemkv_thread.wait(2000) + logging.info("Waiting for mplayer thread") + mplayer_thread.wait(2000) logging.info("Exiting...") sys.exit(result)