Bump to 0.8.7
[nqaap] / src / opt / Nqa-Audiobook-player / SimpleGStreamer.py
1 import os
2 import logging
3
4 import gst
5
6 import gtk_toolbox
7
8
9 _moduleLogger = logging.getLogger(__name__)
10
11
12 class SimplePlayer(object):
13
14         # @todo Add pitch/speed control
15         # http://github.com/jwagner/playitslowly/blob/master/playitslowly/pipeline.py
16
17         def __init__(self, on_playing_done = None):
18                 #Fields
19                 self.playing = False
20                 self.__filename = ""
21                 self.__elapsed = 0
22                 self.__duration = 0
23
24                 #Event callbacks
25                 self.on_playing_done = on_playing_done
26
27                 #Set up GStreamer
28                 self.player = gst.element_factory_make("playbin2", "player")
29                 fakesink = gst.element_factory_make("fakesink", "fakesink")
30                 self.player.set_property("video-sink", fakesink)
31                 bus = self.player.get_bus()
32                 bus.add_signal_watch()
33                 bus.connect("message", self.on_message)
34
35                 #Constants
36                 self.time_format = gst.Format(gst.FORMAT_TIME)
37                 self.seek_flag = gst.SEEK_FLAG_FLUSH
38
39         @property
40         def has_file(self):
41                 return 0 < len(self.__filename)
42
43         @gtk_toolbox.log_exception(_moduleLogger)
44         def on_message(self, bus, message):
45                 t = message.type
46                 if t == gst.MESSAGE_EOS:                # End-Of-Stream
47                         self.player.set_state(gst.STATE_NULL)
48                         self.playing = False
49                         if self.on_playing_done is not None: # event callback
50                                 self.on_playing_done(self)
51                 elif t == gst.MESSAGE_ERROR:
52                         self.player.set_state(gst.STATE_NULL)
53                         err, debug = message.parse_error()
54                         #print "Error: %s" % err, debug
55                         _moduleLogger.error("Error: %s, (%s)" % (err, debug))
56                         self.playing = False
57
58         def set_file(self, file):
59                 _moduleLogger.info("set file: %s", file)
60                 if os.path.isfile(file):
61                         if self.__filename != file:
62                                 self._invalidate_cache()
63                         if self.playing:
64                                 self.stop()
65
66                         file = os.path.abspath(file) # ensure absolute path
67                         _moduleLogger.debug("set file (absolute path): %s "%file)
68                         self.player.set_property("uri", "file://" + file)
69                         self.__filename = file
70                 else:
71                         _moduleLogger.error("File: %s not found" % file)
72
73         def play(self):
74                 _moduleLogger.info("Started playing")
75                 self.player.set_state(gst.STATE_PLAYING)
76                 self.playing = True
77
78         def stop(self):
79                 self.player.set_state(gst.STATE_NULL)
80                 self.playing = False
81                 _moduleLogger.info("Stopped playing")
82
83         def elapsed(self):
84                 try:
85                         self.__elapsed = self.player.query_position(self.time_format, None)[0]
86                 except:
87                         pass
88                 return self.__elapsed
89
90         def duration(self):
91                 try:
92                         self.__duration = self.player.query_duration(self.time_format, None)[0]
93                 except:
94                         _moduleLogger.exception("Query failed")
95                         pass
96                 return self.__duration
97
98         def seek_time(self, ns):
99                 _moduleLogger.debug("Seeking to: %s", ns)
100                 self.player.seek_simple(self.time_format, self.seek_flag, ns)
101
102         def _invalidate_cache(self):
103                 self.__elapsed = 0
104                 self.__duration = 0
105
106         def __seek_percent(self, percent):
107                 format = gst.Format(gst.FORMAT_PERCENT)
108                 self.player.seek_simple(format, self.seek_flag, percent)