From 93f8a50b4f0270dcbc6842d59ec87c50c85d3f55 Mon Sep 17 00:00:00 2001 From: Christophe Benz Date: Sun, 28 Nov 2010 23:43:47 +0100 Subject: [PATCH] clean media player code, ability to configure player in videoob and radioob --- weboob/applications/radioob/radioob.py | 26 +++++---- weboob/applications/videoob/videoob.py | 29 +++++----- weboob/tools/application/media_player.py | 71 +++++++++++++++--------- 3 files changed, 74 insertions(+), 52 deletions(-) diff --git a/weboob/applications/radioob/radioob.py b/weboob/applications/radioob/radioob.py index 9323912b..35cbad57 100644 --- a/weboob/applications/radioob/radioob.py +++ b/weboob/applications/radioob/radioob.py @@ -21,7 +21,7 @@ import sys from weboob.capabilities.radio import ICapRadio from weboob.capabilities.base import NotLoaded from weboob.tools.application.repl import ReplApplication -from weboob.tools.application.media_player import MediaPlayer +from weboob.tools.application.media_player import InvalidMediaPlayer, MediaPlayer, MediaPlayerNotFound from weboob.tools.application.formatters.iformatter import IFormatter @@ -62,10 +62,11 @@ class Radioob(ReplApplication): def __init__(self, *args, **kwargs): ReplApplication.__init__(self, *args, **kwargs) - try: - self.player = MediaPlayer(self.logger) - except OSError: - self.player = None + self.player = MediaPlayer(self.logger) + + def main(self, argv): + self.load_config() + return ReplApplication.main(self, argv) def _get_radio(self, _id, fields=None): if self.interactive: @@ -105,13 +106,14 @@ class Radioob(ReplApplication): if not radio: print >>sys.stderr, 'Radio not found: ' % _id return - - if self.player: - self.player.play(radio.streams[0]) - else: - print 'No player has been found on this system.' - print 'The URL of this radio is:' - print ' %s' % radio.streams[0].url + try: + player_name = self.config.get('media_player') + if not player_name: + self.logger.debug(u'You can set the media_player key to the player you prefer in the radioob ' + 'configuration file.') + self.player.play(radio.streams[0], player_name=player_name) + except (InvalidMediaPlayer, MediaPlayerNotFound), e: + print '%s\nVideo URL: %s' % (e, radio.streams[0].url) def complete_info(self, text, line, *ignored): args = line.split(' ') diff --git a/weboob/applications/videoob/videoob.py b/weboob/applications/videoob/videoob.py index ac980bd6..619ce6c2 100644 --- a/weboob/applications/videoob/videoob.py +++ b/weboob/applications/videoob/videoob.py @@ -21,7 +21,7 @@ import sys from weboob.capabilities.video import ICapVideo from weboob.capabilities.base import NotLoaded from weboob.tools.application.repl import ReplApplication -from weboob.tools.application.media_player import MediaPlayer +from weboob.tools.application.media_player import InvalidMediaPlayer, MediaPlayer, MediaPlayerNotFound from weboob.tools.application.formatters.iformatter import IFormatter @@ -51,23 +51,25 @@ class VideoListFormatter(IFormatter): result += u' (%s/%s)' % (item['rating'], item['rating_max']) return result + class Videoob(ReplApplication): APPNAME = 'videoob' VERSION = '0.4' COPYRIGHT = 'Copyright(C) 2010 Christophe Benz, Romain Bignon, John Obbele' CAPS = ICapVideo EXTRA_FORMATTERS = {'video_list': VideoListFormatter} - COMMANDS_FORMATTERS = {'search': 'video_list'} + COMMANDS_FORMATTERS = {'search': 'video_list'} nsfw = True videos = [] def __init__(self, *args, **kwargs): ReplApplication.__init__(self, *args, **kwargs) - try: - self.player = MediaPlayer(self.logger) - except OSError: - self.player = None + self.player = MediaPlayer(self.logger) + + def main(self, argv): + self.load_config() + return ReplApplication.main(self, argv) def _get_video(self, _id, fields=None): if self.interactive: @@ -107,13 +109,14 @@ class Videoob(ReplApplication): if not video: print 'Video not found: %s' % _id return - - if self.player: - self.player.play(video) - else: - print 'No player has been found on this system.' - print 'The URL of this video is:' - print ' %s' % video.url + try: + player_name = self.config.get('media_player') + if not player_name: + self.logger.debug(u'You can set the media_player key to the player you prefer in the videoob ' + 'configuration file.') + self.player.play(video, player_name=player_name) + except (InvalidMediaPlayer, MediaPlayerNotFound), e: + print '%s\nVideo URL: %s' % (e, video.url) def complete_info(self, text, line, *ignored): args = line.split(' ') diff --git a/weboob/tools/application/media_player.py b/weboob/tools/application/media_player.py index 6e538e29..576b4eb2 100644 --- a/weboob/tools/application/media_player.py +++ b/weboob/tools/application/media_player.py @@ -21,10 +21,32 @@ from subprocess import Popen, PIPE from weboob.tools.log import getLogger -__all__ = ['MediaPlayer'] + +__all__ = ['InvalidMediaPlayer', 'MediaPlayer', 'MediaPlayerNotFound'] -class MediaPlayer(): +PLAYERS = ( + ('parole', 'fd://0'), + ('totem', 'fd://0'), + ('mplayer', '-really-quiet -'), + ('vlc', '-'), + ('xine', 'stdin:/'), +) + + +class MediaPlayerNotFound(Exception): + def __init__(self): + Exception.__init__(self, u'No media player found on this system. Please install one of them: %s.' % \ + ', '.join(player[0] for player in PLAYERS)) + + +class InvalidMediaPlayer(Exception): + def __init__(self, player_name): + Exception.__init__(self, u'Invalid media player: %s. Valid media players: %s.' % ( + player_name, ', '.join(player[0] for player in PLAYERS))) + + +class MediaPlayer(object): """ Black magic invoking a media player to this world. @@ -32,45 +54,45 @@ class MediaPlayer(): world, the media player used is chosen from a static list of programs. See PLAYERS for more information. """ - - PLAYERS = [ - ('parole', 'fd://0'), - ('totem', 'fd://0'), - ('mplayer', '-really-quiet -'), - ('vlc', '-'), - ('xine', 'stdin:/'), - ] - def __init__(self, logger=None): self.logger = getLogger('mediaplayer', logger) - def get_player_name(self, preferred=None): - player_names = preferred if preferred else [player[0] for player in self.PLAYERS] - for player_name in player_names: + def guess_player_name(self): + for player_name in [player[0] for player in PLAYERS]: if self._find_in_path(os.environ['PATH'], player_name): return player_name + return None - def play(self, media): + def play(self, media, player_name=None): """ Play a media object, using programs from the PLAYERS list. This function dispatch calls to either _play_default or _play_rtmp for special rtmp streams using SWF verification. """ - if media.url.find('rtmp') == 0: - self._play_rtmp(media) + player_names = [player[0] for player in PLAYERS] + if player_name: + if player_name not in player_names: + raise InvalidMediaPlayer(player_name) else: - self._play_default(media) + self.logger.debug(u'No media player given. Using the first available from: %s.' % \ + ', '.join(player_names)) + player_name = self.guess_player_name() + if player_name is None: + raise MediaPlayerNotFound() + if media.url.find('rtmp') == 0: + self._play_rtmp(media, player_name) + else: + self._play_default(media, player_name) - def _play_default(self, media): + def _play_default(self, media, player_name): """ Play media.url with the media player. """ - player_name = self.get_player_name() print 'Invoking "%s %s".' % (player_name, media.url) os.spawnlp(os.P_NOWAIT, player_name, player_name, media.url) - def _play_rtmp(self, media): + def _play_rtmp(self, media, player_name): """ Download data with rtmpdump and pipe them to a media player. @@ -79,27 +101,22 @@ class MediaPlayer(): from the server. The last one is retrieved from the non-standard non-API compliant 'swf_player' attribute of the 'media' object. """ - if not self._find_in_path(os.environ['PATH'], 'rtmpdump'): self.logger.warning('"rtmpdump" binary not found') return self._play_default(media) - media_url = media.url try: player_url = media.swf_player rtmp = 'rtmpdump -r %s --swfVfy %s' % (media_url, player_url) - except AttributeError: self.logger.warning('Your media object does not have a "swf_player" attribute. SWF verification will be ' 'disabled and may prevent correct media playback.') - return self._play_default(media) rtmp += ' --quiet' - player_name = self.get_player_name() args = None - for (binary, stdin_args) in self.PLAYERS: + for (binary, stdin_args) in PLAYERS: if binary == player_name: args = stdin_args assert args is not None