Fixed support for subtitles in torrent files and better synchronization between mpv and torrent

This commit is contained in:
Fabio Manganiello 2019-02-19 13:13:17 +01:00
parent 377c963994
commit 185aff6be3
2 changed files with 46 additions and 17 deletions

View file

@ -43,19 +43,13 @@ class MediaMpvPlugin(MediaPlugin):
self._player = None self._player = None
self._is_playing_torrent = False 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): def _init_mpv(self, args=None):
import mpv 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() mpv_args = self.args.copy()
if args: if args:
mpv_args.update(args) mpv_args.update(args)
@ -67,10 +61,10 @@ class MediaMpvPlugin(MediaPlugin):
self._player.register_event_callback(self._event_callback()) self._player.register_event_callback(self._event_callback())
def _event_callback(self): def _event_callback(self):
playback_rebounce_event = threading.Event()
def callback(event): def callback(event):
from mpv import MpvEventID as Event from mpv import MpvEventID as Event
from mpv import MpvEventEndFile as EndFile
self.logger.info('Received mpv event: {}'.format(event)) self.logger.info('Received mpv event: {}'.format(event))
evt = event.get('event_id') evt = event.get('event_id')
@ -79,23 +73,29 @@ class MediaMpvPlugin(MediaPlugin):
bus = get_bus() bus = get_bus()
if evt == Event.FILE_LOADED or evt == Event.START_FILE: if evt == Event.FILE_LOADED or evt == Event.START_FILE:
playback_rebounce_event.set() self._playback_rebounce_event.set()
self._mpv_stopped_event.clear()
bus.post(NewPlayingMediaEvent(resource=self._get_current_resource())) bus.post(NewPlayingMediaEvent(resource=self._get_current_resource()))
bus.post(MediaPlayEvent(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: elif evt == Event.PAUSE:
bus.post(MediaPauseEvent(resource=self._get_current_resource())) bus.post(MediaPauseEvent(resource=self._get_current_resource()))
elif evt == Event.UNPAUSE: elif evt == Event.UNPAUSE:
bus.post(MediaPlayEvent(resource=self._get_current_resource())) bus.post(MediaPlayEvent(resource=self._get_current_resource()))
elif evt == Event.SHUTDOWN: elif evt == Event.SHUTDOWN or (
playback_rebounced = playback_rebounce_event.wait(timeout=2) 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: if playback_rebounced:
playback_rebounce_event.clear() self._playback_rebounce_event.clear()
return return
self._player = None self._player = None
self._mpv_stopped_event.set()
bus.post(MediaStopEvent()) bus.post(MediaStopEvent())
for callback in self._on_stop_callbacks:
callback()
return callback return callback
def _get_youtube_link(self, resource): def _get_youtube_link(self, resource):
@ -143,6 +143,7 @@ class MediaMpvPlugin(MediaPlugin):
args['sub_file'] = self.get_subtitles_file(subtitles) args['sub_file'] = self.get_subtitles_file(subtitles)
resource = self._get_resource(resource) resource = self._get_resource(resource)
if resource.startswith('file://'): if resource.startswith('file://'):
resource = resource[7:] resource = resource[7:]
elif resource.startswith('magnet:?'): elif resource.startswith('magnet:?'):
@ -397,6 +398,9 @@ class MediaMpvPlugin(MediaPlugin):
PlayerState.PLAY.value), PlayerState.PLAY.value),
} }
def on_stop(self, callback):
self._on_stop_callbacks.append(callback)
def _get_current_resource(self): def _get_current_resource(self):
if not self._player or not self._player.stream_path: if not self._player or not self._player.stream_path:
return return

View file

@ -236,6 +236,10 @@ class MediaWebtorrentPlugin(MediaPlugin):
media_file, player.__class__.__name__, media_file, player.__class__.__name__,
webtorrent_url)) webtorrent_url))
subfile = self.get_subtitles(media)
if subfile:
player_args['subtitles'] = subfile
player.play(media, **player_args) player.play(media, **player_args)
self.logger.info('Waiting for player to terminate') self.logger.info('Waiting for player to terminate')
@ -260,7 +264,10 @@ class MediaWebtorrentPlugin(MediaPlugin):
if media_cls == 'MediaMplayerPlugin': if media_cls == 'MediaMplayerPlugin':
stop_evt = player._mplayer_stopped_event stop_evt = player._mplayer_stopped_event
elif media_cls == 'MediaMpvPlugin': 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': elif media_cls == 'MediaOmxplayerPlugin':
stop_evt = threading.Event() stop_evt = threading.Event()
def stop_callback(): def stop_callback():
@ -282,6 +289,24 @@ class MediaWebtorrentPlugin(MediaPlugin):
os.makedirs(d, exist_ok=True) os.makedirs(d, exist_ok=True)
return d 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 @action
def play(self, resource, player=None, download_only=False, **player_args): def play(self, resource, player=None, download_only=False, **player_args):