Debian packaging for 0.99.3 on Fremantle
[panucci.git] / src / panucci / backends / gstreamer.py
blob1e7ad7a88b7a347aa464b30e09ce13dc05f5c60c
1 # -*- coding: utf-8 -*-
3 # This file is part of Panucci.
4 # Copyright (c) 2008-2011 The Panucci Project
6 # Panucci is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Panucci is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Panucci. If not, see <http://www.gnu.org/licenses/>.
19 from __future__ import absolute_import
21 import gobject
22 import gst
23 import logging
25 from panucci.backends import base
27 gobject.threads_init()
29 class Player(base.BasePlayer):
30 """A player that uses Gstreamer for playback"""
32 def __init__(self):
33 base.BasePlayer.__init__(self)
34 self.__log = logging.getLogger('panucci.backends.GStreamerPlayer')
35 self.__player = None
36 # Workaround for weird bug
37 self.initial_pause_position = True
39 def _get_position_duration(self):
40 try:
41 if self.initial_pause_position == True:
42 pos_int = 0
43 else:
44 pos_int = self.__player.query_position(gst.FORMAT_TIME, None)[0]
45 dur_int = self.__player.query_duration(gst.FORMAT_TIME, None)[0]
46 except Exception, e:
47 self.__log.exception('Error getting position...')
48 pos_int = dur_int = 0
50 return pos_int, dur_int
52 def _get_state(self):
53 if self.__player is None:
54 return self.STATE_NULL
55 else:
56 state = self.__player.get_state()[1]
57 return { gst.STATE_NULL : self.STATE_STOPPED,
58 gst.STATE_PAUSED : self.STATE_PAUSED,
59 gst.STATE_PLAYING : self.STATE_PLAYING
60 }.get( state, self.STATE_NULL )
62 def _load_media(self, uri):
63 self.__setup_player()
64 self.__player.set_property("uri", uri)
65 self.__player.set_state(gst.STATE_PAUSED)
66 self.initial_pause_position = True
68 def _pause(self):
69 self.__player.set_state(gst.STATE_PAUSED)
70 pos, dur = self.get_position_duration()
71 self.notify('paused', pos, dur, caller=self.pause)
72 return pos
74 def _play(self):
75 if self.__player:
76 self.__player.set_state(gst.STATE_PLAYING)
77 self.initial_pause_position = False
78 return True
79 else:
80 return False
82 def _stop(self, player):
83 self.notify('stopped', caller=self.stop)
84 if self.__player:
85 self.__player.set_state(gst.STATE_NULL)
86 self.set_position_duration(0, 0)
87 self.initial_pause_position = True
88 self.__player.set_state(gst.STATE_PAUSED)
89 if player:
90 self.__player.set_state(gst.STATE_NULL)
91 self.__player = None
93 def _seek(self, position):
94 self.seeking = True
95 error = False
96 try:
97 self.__player.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, position)
98 except Exception, e:
99 self.__log.exception( 'Error seeking' )
100 error = True
101 self.seeking = False
102 self.initial_pause_position = False
103 return not error
105 def _get_volume_level(self):
106 if self.__player:
107 return int(self.__player.get_property("volume") * 100)
109 def _set_volume_level(self, percent):
110 if self.__player:
111 self.__player.set_property("volume", float(percent) / 100)
113 def __setup_player(self):
114 self.__log.debug("Creating playbin-based gstreamer player")
115 if self.__player:
116 self.__player.set_state(gst.STATE_NULL)
117 try:
118 self.__player = gst.element_factory_make('playbin2', 'player')
119 except:
120 self.__player = gst.element_factory_make('playbin', 'player')
121 bus = self.__player.get_bus()
122 bus.add_signal_watch()
123 bus.connect('message', self.__on_message)
125 def __on_message(self, bus, message):
126 t = message.type
127 if t == gst.MESSAGE_EOS:
128 self.notify( "eof", caller=self.__on_message )
129 elif t == gst.MESSAGE_ERROR:
130 err, debug = message.parse_error()
131 self.__log.critical( 'Error: %s %s', err, debug )
132 self.notify( "error", debug, caller=self.__on_message )
133 elif t == gst.MESSAGE_STATE_CHANGED:
134 if ( message.src == self.__player and
135 message.structure['new-state'] == gst.STATE_PLAYING ):
136 self.notify('playing', caller=self.__on_message)