Author: tack
Date: Wed Apr 19 01:04:53 2006
New Revision: 1413
Modified:
trunk/player/src/generic.py
Log:
Basically rewrite the generic player. This is basically the code from
kaa.canvas.Movie as much of this logic has been worked out already. It fixes
several issues, the main issue being that we shouldn't spawn a new player if
the current player is of the same type, but if we have to, we must kill the
current player (and wait for it to die) in case it has a lock on devices the
new player will need (particularly sound device).
Modified: trunk/player/src/generic.py
==============================================================================
--- trunk/player/src/generic.py (original)
+++ trunk/player/src/generic.py Wed Apr 19 01:04:53 2006
@@ -1,12 +1,17 @@
-import xine
import mplayer
+import xine
from base import *
class Player(object):
def __init__(self):
- object.__setattr__(self, 'player', None)
+ self._player = None
- object.__setattr__(self, 'signals', {
+ # We update the signals dict if it already exists in order to play
+ # friendly with multiple inheritance.
+ if not hasattr(self, "signals"):
+ self.signals = {}
+
+ self.signals.update({
"pause": notifier.Signal(),
"play": notifier.Signal(),
"pause_toggle": notifier.Signal(),
@@ -20,27 +25,115 @@
"osd_configure": notifier.Signal(), # CAP_OSD
# Process is about to die (shared memory will go away)
"quit": notifier.Signal()
- })
+ })
def open(self, mrl):
- if self.player and self.player.get_state() \
- not in (STATE_NOT_RUNNING, STATE_IDLE):
+ if self._player and self.get_state() not in (STATE_NOT_RUNNING,
STATE_IDLE):
raise PlayerError('player is running')
cls = get_player_class(mrl)
if not cls:
raise PlayerError("No supported player found to play %s", mrl)
- # if not self.player or cls.get_player_id() !=
self.player.get_player_id():
- object.__setattr__(self, 'player', cls())
- for signal in self.signals.keys():
- self.player.signals[signal].connect_weak(self.signals[signal].emit)
- return self.player.open(mrl)
-
- def __getattr__(self, attr):
- if not self.player:
- raise PlayerError("No mrl loaded")
- return getattr(self.player, attr)
-
- def __setattr__(self, attr, value):
- if not self.player:
- raise PlayerError("No mrl loaded")
- return setattr(self.player, attr, value)
+ new_player = cls()
+ if 1:#not self._player or new_player.get_player_id() !=
self._player.get_player_id():
+ # Hook our signals to the player we're proxying for.
+ for signal in self.signals.keys():
+
new_player.signals[signal].connect_weak(self.signals[signal].emit)
+
+ if self._player:
+ # An active player already exists. We need to kill it, in case
+ # it's got something locked that our new instance needs. We
can't
+ # start the new player until the old one is gone, so we
construct
+ # a state machine by using signals.
+ self._player.signals["quit"].connect(new_player.open, mrl)
+ self._player.die()
+ self._player = new_player
+ return
+
+ self._player = new_player
+
+ return self._player.open(mrl)
+
+
+ def open(self, mrl, caps = None):
+ cls = get_player_class(mrl = mrl, caps = caps)
+ if not cls:
+ raise PlayerError("No supported player found to play %s", mrl)
+
+ if self._player != None:
+ self._player.stop()
+ if isinstance(self._player, cls):
+ return self._player.open(mrl)
+
+ # Continue open once our current player is dead. We want to wait
+ # before spawning the new one so that it releases the audio
+ # device.
+ self._player.signals["quit"].connect_once(self._open, mrl, cls)
+ self._player.die()
+ return
+
+ return self._open(mrl, cls)
+
+ def _open(self, mrl, cls):
+ self._player = cls()
+
+ for signal in self.signals:
+ if signal in self._player.signals:
+
self._player.signals[signal].connect_weak(self.signals[signal].emit)
+
+ self._player.open(mrl)
+
+
+ def play(self, **kwargs):
+ if not self._player:
+ raise PlayerError, "Play called before open"
+ return
+
+ if self._open in self._player.signals["quit"]:
+ # Waiting for old player to die.
+ self.signals["open"].connect_once(self.play, **kwargs)
+ return
+
+ self._player.play(**kwargs)
+
+ def stop(self):
+ if self._player:
+ self._player.stop()
+
+ def pause(self):
+ if self._player:
+ self._player.pause()
+
+ def pause_toggle(self):
+ if self._player:
+ self._player.pause_toggle()
+
+ def seek_relative(self, offset):
+ if self._player:
+ self._player.seek_relative(offset)
+
+ def seek_absolute(self, position):
+ if self._player:
+ self._player.seek_absolute(position)
+
+ def seek_percentage(self, percent):
+ if self._player:
+ self._player.seek_percent(position)
+
+ def get_position(self):
+ if self._player:
+ self._player.get_position()
+ return 0.0
+
+ def get_info(self):
+ if self._player:
+ self._player.get_info()
+ return {}
+
+ def nav_command(self, input):
+ if self._player:
+ self._player.nav_command(input)
+
+ def is_in_menu(self):
+ if self._player:
+ return self._player.is_in_menu()
+ return False
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog