From 185aff6be3a02f4494b06564b185b7d8b392a2d5 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Tue, 19 Feb 2019 13:13:17 +0100 Subject: [PATCH] Fixed support for subtitles in torrent files and better synchronization between mpv and torrent --- platypush/plugins/media/mpv.py | 36 +++++++++++++++------------ platypush/plugins/media/webtorrent.py | 27 +++++++++++++++++++- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/platypush/plugins/media/mpv.py b/platypush/plugins/media/mpv.py index 929bdb36..cef4d911 100644 --- a/platypush/plugins/media/mpv.py +++ b/platypush/plugins/media/mpv.py @@ -43,19 +43,13 @@ class MediaMpvPlugin(MediaPlugin): self._player = None self._is_playing_torrent = False - self._mpv_stopped_event = threading.Event() + self._playback_rebounce_event = threading.Event() + self._on_stop_callbacks = [] def _init_mpv(self, args=None): import mpv - if self._player: - try: - self.quit() - except Exception as e: - self.logger.debug('Failed to quit mpv before play: {}'. - format(str(e))) - mpv_args = self.args.copy() if args: mpv_args.update(args) @@ -67,10 +61,10 @@ class MediaMpvPlugin(MediaPlugin): self._player.register_event_callback(self._event_callback()) def _event_callback(self): - playback_rebounce_event = threading.Event() - def callback(event): from mpv import MpvEventID as Event + from mpv import MpvEventEndFile as EndFile + self.logger.info('Received mpv event: {}'.format(event)) evt = event.get('event_id') @@ -79,23 +73,29 @@ class MediaMpvPlugin(MediaPlugin): bus = get_bus() if evt == Event.FILE_LOADED or evt == Event.START_FILE: - playback_rebounce_event.set() - self._mpv_stopped_event.clear() + self._playback_rebounce_event.set() bus.post(NewPlayingMediaEvent(resource=self._get_current_resource())) bus.post(MediaPlayEvent(resource=self._get_current_resource())) + elif evt == Event.PLAYBACK_RESTART: + self._playback_rebounce_event.set() + pass elif evt == Event.PAUSE: bus.post(MediaPauseEvent(resource=self._get_current_resource())) elif evt == Event.UNPAUSE: bus.post(MediaPlayEvent(resource=self._get_current_resource())) - elif evt == Event.SHUTDOWN: - playback_rebounced = playback_rebounce_event.wait(timeout=2) + elif evt == Event.SHUTDOWN or ( + evt == Event.END_FILE and event.get('event', {}).get('reason') + in [EndFile.EOF_OR_INIT_FAILURE, EndFile.ABORTED, EndFile.QUIT]): + playback_rebounced = self._playback_rebounce_event.wait(timeout=0.5) if playback_rebounced: - playback_rebounce_event.clear() + self._playback_rebounce_event.clear() return self._player = None - self._mpv_stopped_event.set() bus.post(MediaStopEvent()) + + for callback in self._on_stop_callbacks: + callback() return callback def _get_youtube_link(self, resource): @@ -143,6 +143,7 @@ class MediaMpvPlugin(MediaPlugin): args['sub_file'] = self.get_subtitles_file(subtitles) resource = self._get_resource(resource) + if resource.startswith('file://'): resource = resource[7:] elif resource.startswith('magnet:?'): @@ -397,6 +398,9 @@ class MediaMpvPlugin(MediaPlugin): PlayerState.PLAY.value), } + def on_stop(self, callback): + self._on_stop_callbacks.append(callback) + def _get_current_resource(self): if not self._player or not self._player.stream_path: return diff --git a/platypush/plugins/media/webtorrent.py b/platypush/plugins/media/webtorrent.py index bd322af3..0da505e7 100644 --- a/platypush/plugins/media/webtorrent.py +++ b/platypush/plugins/media/webtorrent.py @@ -236,6 +236,10 @@ class MediaWebtorrentPlugin(MediaPlugin): media_file, player.__class__.__name__, webtorrent_url)) + subfile = self.get_subtitles(media) + if subfile: + player_args['subtitles'] = subfile + player.play(media, **player_args) self.logger.info('Waiting for player to terminate') @@ -260,7 +264,10 @@ class MediaWebtorrentPlugin(MediaPlugin): if media_cls == 'MediaMplayerPlugin': stop_evt = player._mplayer_stopped_event elif media_cls == 'MediaMpvPlugin': - stop_evt = player._mpv_stopped_event + stop_evt = threading.Event() + def stop_callback(): + stop_evt.set() + player.on_stop(stop_callback) elif media_cls == 'MediaOmxplayerPlugin': stop_evt = threading.Event() def stop_callback(): @@ -282,6 +289,24 @@ class MediaWebtorrentPlugin(MediaPlugin): os.makedirs(d, exist_ok=True) return d + def get_subtitles(self, filepath): + try: + plugin = get_plugin('media.subtitles') + if not plugin or not plugin.languages: + return + + subs = plugin.get_subtitles(filepath).output + if not subs: + return + + sub = plugin.download_subtitles(subs[0]['SubDownloadLink'], + filepath).output + + if sub: + return sub['filename'] + except Exception as e: + self.logger.warning('Could not get subtitles for {}: {}'.format( + filepath, str(e))) @action def play(self, resource, player=None, download_only=False, **player_args):