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
25 from panucci
.backends
import base
27 gobject
.threads_init()
29 class Player(base
.BasePlayer
):
30 """A player that uses Gstreamer for playback"""
33 base
.BasePlayer
.__init
__(self
)
34 self
.__log
= logging
.getLogger('panucci.backends.GStreamerPlayer')
36 # Workaround for weird bug
37 self
.initial_pause_position
= True
39 def _get_position_duration(self
):
41 if self
.initial_pause_position
== True:
44 pos_int
= self
.__player
.query_position(gst
.FORMAT_TIME
, None)[0]
45 dur_int
= self
.__player
.query_duration(gst
.FORMAT_TIME
, None)[0]
47 self
.__log
.exception('Error getting position...')
50 return pos_int
, dur_int
53 if self
.__player
is None:
54 return self
.STATE_NULL
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
):
64 self
.__player
.set_property("uri", uri
)
65 self
.__player
.set_state(gst
.STATE_PAUSED
)
66 self
.initial_pause_position
= True
69 self
.__player
.set_state(gst
.STATE_PAUSED
)
70 pos
, dur
= self
.get_position_duration()
71 self
.notify('paused', pos
, dur
, caller
=self
.pause
)
76 self
.__player
.set_state(gst
.STATE_PLAYING
)
77 self
.initial_pause_position
= False
82 def _stop(self
, player
):
83 self
.notify('stopped', caller
=self
.stop
)
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
)
90 self
.__player
.set_state(gst
.STATE_NULL
)
93 def _seek(self
, position
):
97 self
.__player
.seek_simple(gst
.FORMAT_TIME
, gst
.SEEK_FLAG_FLUSH
, position
)
99 self
.__log
.exception( 'Error seeking' )
102 self
.initial_pause_position
= False
105 def _get_volume_level(self
):
107 return int(self
.__player
.get_property("volume") * 100)
109 def _set_volume_level(self
, percent
):
111 self
.__player
.set_property("volume", float(percent
) / 100)
113 def __setup_player(self
):
114 self
.__log
.debug("Creating playbin-based gstreamer player")
116 self
.__player
.set_state(gst
.STATE_NULL
)
118 self
.__player
= gst
.element_factory_make('playbin2', 'player')
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
):
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
)