From ded4ac3b95b3b866a4230944847dde103e513026 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Fri, 20 Apr 2018 12:17:27 +0200 Subject: [PATCH] - Introduced a more consistent Enum for managing playing states across different players - media.ctrl can now spot which player is playing and control only the right one - Extended video.omxplayer plugin methods --- platypush/plugins/media/__init__.py | 8 ++++ platypush/plugins/media/ctrl.py | 55 +++++++++++++++++------ platypush/plugins/video/omxplayer.py | 62 +++++++++++++++++++++++--- platypush/plugins/video/torrentcast.py | 11 +++-- 4 files changed, 113 insertions(+), 23 deletions(-) diff --git a/platypush/plugins/media/__init__.py b/platypush/plugins/media/__init__.py index e69de29bb..ba88c0b9f 100644 --- a/platypush/plugins/media/__init__.py +++ b/platypush/plugins/media/__init__.py @@ -0,0 +1,8 @@ +import enum + + +class PlayerState(enum.Enum): + STOP = 'stop' + PLAY = 'play' + PAUSE = 'pause' + diff --git a/platypush/plugins/media/ctrl.py b/platypush/plugins/media/ctrl.py index c14cfab51..dec530c6b 100644 --- a/platypush/plugins/media/ctrl.py +++ b/platypush/plugins/media/ctrl.py @@ -1,10 +1,9 @@ import re import subprocess -from omxplayer import OMXPlayer - from platypush.context import get_plugin from platypush.message.response import Response +from platypush.plugins.media import PlayerState from .. import Plugin @@ -18,8 +17,11 @@ class MediaCtrlPlugin(Plugin): - spotify:track:track_id [leverages plugins.music.mpd] """ - def __init__(self, omxplayer_args=[], torrentcast_port=9090, *args, **kwargs): - self.omxplayer_args = omxplayer_args + _supported_plugins = { + 'music.mpd', 'video.omxplayer', 'video.torrentcast' + } + + def __init__(self, torrentcast_port=9090, *args, **kwargs): self.torrentcast_port = torrentcast_port self.url = None self.plugin = None @@ -52,6 +54,25 @@ class MediaCtrlPlugin(Plugin): raise RuntimeError('Unknown URL type: {}'.format(url)) + def _get_playing_plugin(self): + if self.plugin: + status = self.plugin.status() + if status['state'] == PlayerState.PLAY or state['state'] == PlayerState.PAUSE: + return self.plugin + + for plugin in self._supported_plugins: + try: + player = get_plugin(plugin) + except: + continue + + status = player.status().output + if status['state'] == PlayerState.PLAY.value or status['state'] == PlayerState.PAUSE.value: + return player + + return None + + def play(self, url): (type, resource) = self._get_type_and_resource_by_url(url) response = Response(output='', errors = []) @@ -67,38 +88,46 @@ class MediaCtrlPlugin(Plugin): return self.plugin.play(resource) def pause(self): - if self.plugin: return self.plugin.pause() + plugin = self._get_playing_plugin() + if plugin: return plugin.pause() def stop(self): - if self.plugin: - ret = self.plugin.stop() + plugin = self._get_playing_plugin() + if plugin: + ret = plugin.stop() self.plugin = None return ret def voldown(self): - if self.plugin: return self.plugin.voldown() + plugin = self._get_playing_plugin() + if plugin: return plugin.voldown() def volup(self): - if self.plugin: return self.plugin.volup() + plugin = self._get_playing_plugin() + if plugin: return plugin.volup() def back(self): - if self.plugin: return self.plugin.back() + plugin = self._get_playing_plugin() + if plugin: return plugin.back() def forward(self): - if self.plugin: return self.plugin.forward() + plugin = self._get_playing_plugin() + if plugin: return plugin.forward() def next(self): - if self.plugin: return self.plugin.next() + plugin = self._get_playing_plugin() + if plugin: return plugin.next() def previous(self): - if self.plugin: return self.plugin.previous() + plugin = self._get_playing_plugin() + if plugin: return plugin.previous() # vim:sw=4:ts=4:et: diff --git a/platypush/plugins/video/omxplayer.py b/platypush/plugins/video/omxplayer.py index c0a181a30..94f558c44 100644 --- a/platypush/plugins/video/omxplayer.py +++ b/platypush/plugins/video/omxplayer.py @@ -10,6 +10,7 @@ from bs4 import BeautifulSoup from dbus.exceptions import DBusException from omxplayer import OMXPlayer +from platypush.plugins.media import PlayerState from platypush.message.response import Response from platypush.message.event.video import VideoPlayEvent, VideoPauseEvent, \ VideoStopEvent, NewPlayingVideoEvent @@ -20,11 +21,9 @@ class VideoOmxplayerPlugin(Plugin): def __init__(self, args=[], *argv, **kwargs): self.args = args self.player = None - self.cur_video = None self.videos_queue = [] def play(self, resource): - self.cur_video = resource if resource.startswith('youtube:') \ or resource.startswith('https://www.youtube.com/watch?v='): resource = self._get_youtube_content(resource) @@ -50,7 +49,6 @@ class VideoOmxplayerPlugin(Plugin): self.player.quit() self.player = None - self.cur_video = None return self.status() def voldown(self): @@ -84,17 +82,67 @@ class VideoOmxplayerPlugin(Plugin): return Response(output={'status': 'no media'}, errors = []) + def hide_subtitles(self): + if self.player: self.player.hide_subtitles() + return self.status() + + def hide_video(self): + if self.player: self.player.hide_video() + return self.status() + + def is_playing(self): + if self.player: return self.player.is_playing() + else: return False + + def load(self, source, pause=False): + if self.player: self.player.load(source, pause) + return self.status() + + def metadata(self): + if self.player: return Response(output=self.player.metadata()) + return self.status() + + def mute(self): + if self.player: self.player.mute() + return self.status() + + def unmute(self): + if self.player: self.player.unmute() + return self.status() + + def seek(self, relative_position): + if self.player: self.player.seek(relative_position) + return self.status() + + def set_position(self, position): + if self.player: self.player.set_seek(position) + return self.status() + + def set_volume(self, volume): + if self.player: self.player.set_volume(volume) + return self.status() + def status(self): + state = PlayerState.STOP.value + if self.player: + state = self.player.playback_status().lower() + if state == 'playing': state = PlayerState.PLAY.value + elif state == 'stopped': state = PlayerState.STOP.value + elif state == 'paused': state = PlayerState.PAUSE.value + return Response(output=json.dumps({ 'source': self.player.get_source(), - 'status': self.player.playback_status(), + 'state': state, 'volume': self.player.volume(), 'elapsed': self.player.position(), + 'duration': self.player.duration(), + 'width': self.player.width(), + 'height': self.player.height(), })) else: return Response(output=json.dumps({ - 'status': 'Not initialized' + 'state': PlayerState.STOP.value })) def _init_player_handlers(self): @@ -102,10 +150,10 @@ class VideoOmxplayerPlugin(Plugin): return self.player.playEvent += lambda _: \ - self.bus.post(VideoPlayEvent(video=self.cur_video)) + self.bus.post(VideoPlayEvent(video=self.player.get_source()) self.player.pauseEvent += lambda _: \ - self.bus.post(VideoPauseEvent(video=self.cur_video)) + self.bus.post(VideoPauseEvent(video=self.player.get_source()) self.player.stopEvent += lambda _: \ self.bus.post(VideoStopEvent()) diff --git a/platypush/plugins/video/torrentcast.py b/platypush/plugins/video/torrentcast.py index 0fb40b6c4..45845986f 100644 --- a/platypush/plugins/video/torrentcast.py +++ b/platypush/plugins/video/torrentcast.py @@ -4,6 +4,7 @@ import urllib3 import urllib.request import urllib.parse +from platypush.plugins.media import PlayerState from platypush.message.response import Response from .. import Plugin @@ -12,7 +13,7 @@ class VideoTorrentcastPlugin(Plugin): def __init__(self, server='localhost', port=9090, *args, **kwargs): self.server = server self.port = port - self.playing = False + self.state = PlayerState.STOP.value def play(self, url): request = urllib.request.urlopen( @@ -22,7 +23,7 @@ class VideoTorrentcastPlugin(Plugin): }).encode() ) - self.playing = True + self.state = PlayerState.PLAY.value return Response(output=request.read()) def pause(self): @@ -30,6 +31,7 @@ class VideoTorrentcastPlugin(Plugin): request = http.request('POST', 'http://{}:{}/pause/'.format(self.server, self.port)) + self.state = PlayerState.PAUSE.value return Response(output=request.read()) def stop(self): @@ -37,7 +39,7 @@ class VideoTorrentcastPlugin(Plugin): request = http.request('POST', 'http://{}:{}/stop/'.format(self.server, self.port)) - self.playing = False + self.state = PlayerState.STOP.value return Response(output=request.read()) def search(self, query): @@ -75,6 +77,9 @@ class VideoTorrentcastPlugin(Plugin): def back(self): return Response(output='Unsupported method') def forward(self): return Response(output='Unsupported method') + def status(self): + return Response(output={ 'state': self.state }) + # vim:sw=4:ts=4:et: