This development deserves a new version number!
[pylooper.git] / gstplayer.py
blob21934341667dda895fa6e24b3b793c10388a34f4
1 import os, os.path
2 from mutagen.mp3 import MP3
4 try:
5 import pygst
6 pygst.require('0.10')
7 import gst
8 except:
9 raise ImportError('You need gstreamer version >=0.10 and its python bindings')
10 try:
11 import gobject
12 except:
13 raise ImportError('You need gobject')
15 from player import Player, isblank
16 import settings
18 class GstPlayer(Player):
19 """Implements Player with the python gstreamer bindings."""
21 def __init__(self):
22 super(GstPlayer, self).__init__()
24 self.player = gst.element_factory_make('playbin', 'player')
25 self.audio = None
27 @property
28 def isplaying(self):
29 if self.player and self.player.get_state()[1] is gst.STATE_PLAYING:
30 return True
31 else:
32 return False
34 @property
35 def ispaused(self):
36 if self.player and self.player.get_state()[1] is not gst.STATE_PAUSED:
37 return False
38 else:
39 return True
41 @property
42 def position(self):
43 try:
44 return self.player.query_position(gst.Format(gst.FORMAT_TIME), None)[0]
45 except:
46 return 0
48 @property
49 def duration(self):
50 if self.audio:
51 # we do everything in nanoseconds like gstreamer does
52 return self.audio.info.length * 1000000000
53 else:
54 return 0
56 def play(self):
57 if isblank(self.status.filepath):
58 return False
60 if isblank(self.player.get_property('uri')):
61 self.load()
63 if not gst.uri_is_valid(self.player.get_property('uri')):
64 return false
66 self.seek_if_needed()
67 if self.player.set_state(gst.STATE_PLAYING) is gst.STATE_CHANGE_FAILURE:
68 return False
69 self.timer = self.new_timer()
70 return True
72 def pause(self):
73 if self.player.set_state(gst.STATE_PAUSED) is gst.STATE_CHANGE_FAILURE:
74 return False
75 gobject.source_remove(self.timer)
76 return True
78 def stop(self, widget=None):
79 self.player.seek_simple(gst.Format(gst.FORMAT_TIME), gst.SEEK_FLAG_FLUSH, self.status.begin)
81 if self.player.set_state(gst.STATE_NULL) is gst.STATE_CHANGE_FAILURE:
82 return False
84 if self.timer:
85 gobject.source_remove(self.timer)
87 return True
89 def load(self):
90 self.status.begin = 0
91 if not self.stop():
92 return False
94 if os.path.exists(self.status.filepath):
95 self.player.set_property('uri', 'file://' + self.status.filepath)
96 self.player.set_state(gst.STATE_READY)
98 self.audio = MP3(self.status.filepath)
99 self.status.end = self.duration
100 return True
102 return False
104 def check_status(self):
105 if self.timer:
106 gobject.source_remove(self.timer)
108 wasplaying = self.isplaying
110 self.seek_if_needed()
112 if wasplaying:
113 self.timer = self.new_timer()
115 def seek_if_needed(self):
116 if not self.status.begin <= self.position < self.status.end:
117 self.player.seek_simple(gst.Format(gst.FORMAT_TIME),
118 gst.SEEK_FLAG_FLUSH, long(self.status.begin))
120 def new_timer(self):
121 return gobject.timeout_add(int(min(self.status.end - self.position, 1000000000) / 1000000), self.check_status)