sound_type.py
Go to the documentation of this file.
1 import os
2 import threading
3 
4 import rospy
5 
6 from sound_play.msg import SoundRequest
7 
8 try:
9  import gi
10  gi.require_version('Gst', '1.0')
11  from gi.repository import Gst as Gst
12 except Exception:
13  str = """
14 **************************************************************
15 Error opening pygst. Is gstreamer installed?
16 **************************************************************
17 """
18  rospy.logfatal(str)
19  # print str
20  exit(1)
21 
22 
23 class SoundType(object):
24  STOPPED = 0
25  LOOPING = 1
26  COUNTING = 2
27 
28  def __init__(self, file, device, volume=1.0):
29  self.lock = threading.RLock()
30  self.state = self.STOPPED
31  self.sound = Gst.ElementFactory.make("playbin", None)
32  if self.sound is None:
33  raise Exception("Could not create sound player")
34 
35  if device:
36  self.sink = Gst.ElementFactory.make("alsasink", "sink")
37  self.sink.set_property("device", device)
38  self.sound.set_property("audio-sink", self.sink)
39 
40  if (":" in file):
41  uri = file
42  elif os.path.isfile(file):
43  uri = "file://" + os.path.abspath(file)
44  else:
45  rospy.logerr('Error: URI is invalid: %s' % file)
46 
47  self.uri = uri
48  self.volume = volume
49  self.sound.set_property('uri', uri)
50  self.sound.set_property("volume", volume)
51  self.staleness = 1
52  self.file = file
53 
54  self.bus = self.sound.get_bus()
55  self.bus.add_signal_watch()
56  self.bus_conn_id = self.bus.connect("message", self.on_stream_end)
57 
58  def on_stream_end(self, bus, message):
59  if message.type == Gst.MessageType.EOS:
60  if (self.state == self.LOOPING):
61  self.sound.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0)
62  else:
63  self.stop()
64 
65  def __del__(self):
66  # stop our GST object so that it gets garbage-collected
67  self.dispose()
68 
69  def update(self):
70  if self.bus is not None:
71  self.bus.poll(Gst.MessageType.ERROR, 10)
72 
73  def loop(self):
74  self.lock.acquire()
75  try:
76  self.staleness = 0
77  if self.state == self.COUNTING:
78  self.stop()
79 
80  if self.state == self.STOPPED:
81  self.sound.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0)
82  self.sound.set_state(Gst.State.PLAYING)
83  self.state = self.LOOPING
84  finally:
85  self.lock.release()
86 
87  def dispose(self):
88  self.lock.acquire()
89  try:
90  if self.bus is not None:
91  self.sound.set_state(Gst.State.NULL)
92  self.bus.disconnect(self.bus_conn_id)
93  self.bus.remove_signal_watch()
94  self.bus = None
95  self.sound = None
96  self.sink = None
97  self.state = self.STOPPED
98  except Exception as e:
99  rospy.logerr('Exception in dispose: %s' % str(e))
100  finally:
101  self.lock.release()
102 
103  def stop(self):
104  if self.state != self.STOPPED:
105  self.lock.acquire()
106  try:
107  self.sound.set_state(Gst.State.NULL)
108  self.state = self.STOPPED
109  finally:
110  self.lock.release()
111 
112  def single(self):
113  self.lock.acquire()
114  try:
115  rospy.logdebug("Playing %s" % self.uri)
116  self.staleness = 0
117  if self.state == self.LOOPING:
118  self.stop()
119 
120  self.sound.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0)
121  self.sound.set_state(Gst.State.PLAYING)
122  self.state = self.COUNTING
123  finally:
124  self.lock.release()
125 
126  def command(self, cmd):
127  if cmd == SoundRequest.PLAY_STOP:
128  self.stop()
129  elif cmd == SoundRequest.PLAY_ONCE:
130  self.single()
131  elif cmd == SoundRequest.PLAY_START:
132  self.loop()
133 
134  def get_staleness(self):
135  self.lock.acquire()
136  position = 0
137  duration = 0
138  try:
139  position = self.sound.query_position(Gst.Format.TIME)[1]
140  duration = self.sound.query_duration(Gst.Format.TIME)[1]
141  except Exception:
142  position = 0
143  duration = 0
144  finally:
145  self.lock.release()
146 
147  if position != duration:
148  self.staleness = 0
149  else:
150  self.staleness = self.staleness + 1
151  return self.staleness
152 
153  def get_playing(self):
154  return self.state == self.COUNTING
sound_play.sound_type.SoundType.bus_conn_id
bus_conn_id
Definition: sound_type.py:56
sound_play.sound_type.SoundType.dispose
def dispose(self)
Definition: sound_type.py:87
sound_play.sound_type.SoundType
Definition: sound_type.py:23
sound_play.sound_type.SoundType.__del__
def __del__(self)
Definition: sound_type.py:65
sound_play.sound_type.str
string str
Definition: sound_type.py:13
sound_play.sound_type.SoundType.single
def single(self)
Definition: sound_type.py:112
sound_play.sound_type.SoundType.sound
sound
Definition: sound_type.py:31
sound_play.sound_type.SoundType.get_playing
def get_playing(self)
Definition: sound_type.py:153
sound_play.sound_type.SoundType.file
file
Definition: sound_type.py:52
sound_play.sound_type.SoundType.command
def command(self, cmd)
Definition: sound_type.py:126
sound_play.sound_type.SoundType.loop
def loop(self)
Definition: sound_type.py:73
sound_play.sound_type.SoundType.volume
volume
Definition: sound_type.py:48
sound_play.sound_type.SoundType.STOPPED
int STOPPED
Definition: sound_type.py:24
sound_play.sound_type.SoundType.on_stream_end
def on_stream_end(self, bus, message)
Definition: sound_type.py:58
sound_play.sound_type.SoundType.COUNTING
int COUNTING
Definition: sound_type.py:26
sound_play.sound_type.SoundType.stop
def stop(self)
Definition: sound_type.py:103
sound_play.sound_type.SoundType.sink
sink
Definition: sound_type.py:36
sound_play.sound_type.SoundType.bus
bus
Definition: sound_type.py:54
sound_play.sound_type.SoundType.lock
lock
Definition: sound_type.py:29
sound_play.sound_type.SoundType.update
def update(self)
Definition: sound_type.py:69
sound_play.sound_type.SoundType.state
state
Definition: sound_type.py:30
sound_play.sound_type.SoundType.__init__
def __init__(self, file, device, volume=1.0)
Definition: sound_type.py:28
sound_play.sound_type.SoundType.get_staleness
def get_staleness(self)
Definition: sound_type.py:134
sound_play.sound_type.SoundType.uri
uri
Definition: sound_type.py:47
sound_play.sound_type.SoundType.staleness
staleness
Definition: sound_type.py:51
sound_play.sound_type.SoundType.LOOPING
int LOOPING
Definition: sound_type.py:25


sound_play
Author(s): Blaise Gassend
autogenerated on Thu Apr 4 2024 02:45:08