Refactored and fixed many bugs on the media.omxplayer plugin

This commit is contained in:
Fabio Manganiello 2021-02-04 01:44:21 +01:00
parent 165f85f8dc
commit 2834ed2a7c
2 changed files with 64 additions and 37 deletions

View File

@ -162,7 +162,8 @@ class MediaPlugin(Plugin):
def _is_youtube_resource(resource): def _is_youtube_resource(resource):
return resource.startswith('youtube:') \ return resource.startswith('youtube:') \
or resource.startswith('https://youtu.be/') \ or resource.startswith('https://youtu.be/') \
or resource.startswith('https://www.youtube.com/watch?v=') or resource.startswith('https://www.youtube.com/watch?v=') \
or resource.startswith('https://youtube.com/watch?v=')
def _get_resource(self, resource): def _get_resource(self, resource):
""" """
@ -477,7 +478,7 @@ class MediaPlugin(Plugin):
@staticmethod @staticmethod
def get_youtube_video_url(url): def get_youtube_video_url(url):
youtube_dl = subprocess.Popen(['youtube-dl', '-f', 'best', '-g', url], stdout=subprocess.PIPE) youtube_dl = subprocess.Popen(['youtube-dl', '-f', 'best', '-g', url], stdout=subprocess.PIPE)
url = youtube_dl.communicate()[0].decode() url = youtube_dl.communicate()[0].decode().strip()
youtube_dl.wait() youtube_dl.wait()
return url return url

View File

@ -1,9 +1,10 @@
import enum import enum
import math
import urllib.parse import urllib.parse
from platypush.context import get_bus from platypush.context import get_bus
from platypush.plugins.media import MediaPlugin, PlayerState from platypush.plugins.media import MediaPlugin, PlayerState
from platypush.message.event.media import MediaPlayEvent, MediaPauseEvent, MediaStopEvent, MediaSeekEvent from platypush.message.event.media import MediaPlayEvent, MediaPauseEvent, MediaStopEvent, MediaSeekEvent, MediaPlayRequestEvent
from platypush.plugins import action from platypush.plugins import action
@ -43,9 +44,9 @@ class MediaOmxplayerPlugin(MediaPlugin):
self._handlers = {e.value: [] for e in PlayerEvent} self._handlers = {e.value: [] for e in PlayerEvent}
@action @action
def play(self, resource, subtitles=None, *args, **kwargs): def play(self, resource=None, subtitles=None, *args, **kwargs):
""" """
Play a resource. Play or resume playing a resource.
:param resource: Resource to play. Supported types: :param resource: Resource to play. Supported types:
@ -56,6 +57,15 @@ class MediaOmxplayerPlugin(MediaPlugin):
:param subtitles: Subtitles file :param subtitles: Subtitles file
""" """
if not resource:
if not self._player:
self.logger.warning('No OMXPlayer instances running')
else:
self._player.play()
return self.status()
self._post_event(MediaPlayRequestEvent, resource=resource)
if subtitles: if subtitles:
args += ('--subtitles', subtitles) args += ('--subtitles', subtitles)
@ -75,17 +85,17 @@ class MediaOmxplayerPlugin(MediaPlugin):
try: try:
from omxplayer import OMXPlayer from omxplayer import OMXPlayer
self._player = OMXPlayer(resource, args=self.args) self._player = OMXPlayer(resource, args=self.args)
self._init_player_handlers()
except DBusException as e: except DBusException as e:
self.logger.warning('DBus connection failed: you will probably not ' + self.logger.warning('DBus connection failed: you will probably not ' +
'be able to control the media') 'be able to control the media')
self.logger.exception(e) self.logger.exception(e)
self._player.pause()
if self.volume: if self.volume:
self.set_volume(volume=self.volume) self.set_volume(self.volume)
self._post_event(MediaPlayEvent, resource=resource)
self._init_player_handlers()
self._player.play()
return self.status() return self.status()
@action @action
@ -111,35 +121,52 @@ class MediaOmxplayerPlugin(MediaPlugin):
self._player.quit() self._player.quit()
except OMXPlayerDeadError: except OMXPlayerDeadError:
pass pass
finally:
self._player = None self._player = None
return {'status': 'stop'} return {'status': 'stop'}
@action def get_volume(self) -> float:
def voldown(self): """
""" Volume down by 10% """ :return: The player volume in percentage [0, 100].
"""
if self._player: if self._player:
self._player.set_volume(max(0, self._player.volume()-0.1)) return self._player.volume()*100
@action
def voldown(self, step=10.0):
"""
Decrease the volume.
:param step: Volume decrease step between 0 and 100 (default: 10%).
:type step: float
"""
if self._player:
self.set_volume(max(0, self.get_volume()-step))
return self.status() return self.status()
@action @action
def volup(self): def volup(self, step=10.0):
""" Volume up by 10% """ """
Increase the volume.
:param step: Volume increase step between 0 and 100 (default: 10%).
:type step: float
"""
if self._player: if self._player:
self._player.set_volume(min(1, self._player.volume()+0.1)) self.set_volume(min(100, self.get_volume()+step))
return self.status() return self.status()
@action @action
def back(self, offset=60): def back(self, offset=30):
""" Back by (default: 60) seconds """ """ Back by (default: 30) seconds """
if self._player: if self._player:
self._player.seek(-offset) self._player.seek(-offset)
return self.status() return self.status()
@action @action
def forward(self, offset=60): def forward(self, offset=30):
""" Forward by (default: 60) seconds """ """ Forward by (default: 30) seconds """
if self._player: if self._player:
self._player.seek(offset) self._player.seek(offset)
return self.status() return self.status()
@ -216,30 +243,27 @@ class MediaOmxplayerPlugin(MediaPlugin):
return self.status() return self.status()
@action @action
def seek(self, relative_position): def seek(self, position):
""" """
Seek backward/forward by the specified number of seconds Seek to the specified number of seconds from the start.
:param relative_position: Number of seconds relative to the current cursor :param position: Number of seconds from the start
:type relative_position: int :type position: float
""" """
if self._player: if self._player:
self._player.seek(relative_position) self._player.set_position(position)
return self.status() return self.status()
@action @action
def set_position(self, position): def set_position(self, position):
""" """
Seek backward/forward to the specified absolute position Seek to the specified number of seconds from the start (same as :meth:`.seek`).
:param position: Number of seconds from the start :param position: Number of seconds from the start
:type position: int :type position: float
""" """
return self.seek(position)
if self._player:
self._player.seek(position)
return self.status()
@action @action
def set_volume(self, volume): def set_volume(self, volume):
@ -247,7 +271,7 @@ class MediaOmxplayerPlugin(MediaPlugin):
Set the volume Set the volume
:param volume: Volume value between 0 and 100 :param volume: Volume value between 0 and 100
:type volume: int :type volume: float
""" """
if self._player: if self._player:
@ -314,7 +338,7 @@ class MediaOmxplayerPlugin(MediaPlugin):
'state': state, 'state': state,
'title': urllib.parse.unquote(self._player.get_source()).split('/')[-1] if self._player.get_source().startswith('file://') else None, 'title': urllib.parse.unquote(self._player.get_source()).split('/')[-1] if self._player.get_source().startswith('file://') else None,
'url': self._player.get_source(), 'url': self._player.get_source(),
'volume': self._player.volume() * 100, 'volume': self.get_volume(),
'volume_max': 100, 'volume_max': 100,
} }
@ -349,14 +373,14 @@ class MediaOmxplayerPlugin(MediaPlugin):
return _f return _f
def on_stop(self): def on_stop(self):
def _f(player): def _f(player, *_, **__):
self._post_event(MediaStopEvent) self._post_event(MediaStopEvent)
for callback in self._handlers[PlayerEvent.STOP.value]: for callback in self._handlers[PlayerEvent.STOP.value]:
callback() callback()
return _f return _f
def on_seek(self): def on_seek(self):
def _f(player): def _f(player, *_, **__):
self._post_event(MediaSeekEvent, position=player.position()) self._post_event(MediaSeekEvent, position=player.position())
return _f return _f
@ -367,7 +391,9 @@ class MediaOmxplayerPlugin(MediaPlugin):
self._player.playEvent += self.on_play() self._player.playEvent += self.on_play()
self._player.pauseEvent += self.on_pause() self._player.pauseEvent += self.on_pause()
self._player.stopEvent += self.on_stop() self._player.stopEvent += self.on_stop()
self._player.exitEvent += self.on_stop()
self._player.positionEvent += self.on_seek() self._player.positionEvent += self.on_seek()
self._player.seekEvent += self.on_seek()
# vim:sw=4:ts=4:et: # vim:sw=4:ts=4:et: