Package deefuzzer :: Package tools :: Module gstplayer
[hide private]
[frames] | no frames]

Source Code for Module deefuzzer.tools.gstplayer

  1  #!/usr/bin/env python 
  2  # 
  3  # Based on: 
  4  # decodebin.py - Audio autopluging example using 'decodebin' element 
  5  # Copyright (C) 2006 Jason Gerard DeRose <jderose@jasonderose.org> 
  6  # Copyright (C) 2006 yokamaru https://gist.github.com/yokamaru/850506 
  7  # Copyright (C) 2013 Guillaume Pellerin <yomguy@parisson.com> 
  8   
  9  # This library is free software; you can redistribute it and/or 
 10  # modify it under the terms of the GNU Library General Public 
 11  # License as published by the Free Software Foundation; either 
 12  # version 2 of the License, or (at your option) any later version. 
 13  # 
 14  # This library is distributed in the hope that it will be useful, 
 15  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 16  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 17  # Library General Public License for more details. 
 18  # 
 19  # You should have received a copy of the GNU Library General Public 
 20  # License along with this library; if not, write to the 
 21  # Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 22  # Boston, MA 02111-1307, USA. 
 23   
 24  # Doc : https://code.google.com/p/raspberry-gpio-python/wiki/Inputs 
 25   
 26   
 27  DEBUG = False 
 28   
 29  import gobject 
 30  gobject.threads_init() 
 31  import pygst 
 32  pygst.require("0.10") 
 33  import gst 
 34  import os, sys 
 35  import time 
 36  import urlparse, urllib 
 37  from threading import Thread 
 38   
 39   
40 -def path2url(path):
41 return urlparse.urljoin( 42 'file:', urllib.pathname2url(path))
43 44
45 -class OSCController(Thread):
46
47 - def __init__(self, port):
48 Thread.__init__(self) 49 import liblo 50 self.port = port 51 try: 52 self.server = liblo.Server(self.port) 53 except liblo.ServerError, err: 54 print str(err)
55
56 - def add_method(self, path, type, method):
57 self.server.add_method(path, type, method)
58
59 - def run(self):
60 while True: 61 self.server.recv(100)
62 63
64 -class GPIOController(Thread):
65
66 - def __init__(self):
67 Thread.__init__(self) 68 import RPi.GPIO as GPIO 69 self.server = GPIO 70 self.server.setmode(self.server.BCM) 71 self.method = self.server.RISING
72
73 - def add_channel_callback(self, channel, callback, bouncetime):
74 self.server.setup(channel, self.server.IN, pull_up_down=self.method) 75 self.server.add_event_detect(channel, self.method, callback=callback, bouncetime=bouncetime)
76
77 - def run(self):
78 pass
79 80 81
82 -class PiPlayer(object):
83 84 osc_port = 12345 85 gpio_channel_play = 22 86 gpio_channel_stop = 24 87 playing = False 88 looping = False 89 auto_next = False 90 alsa_device = 'hw:0' 91 gpio_parasite_filter_time = 0.02 92
93 - def __init__(self, play_dir):
94 # Playlist 95 self.play_dir = play_dir 96 self. playlist = [] 97 self.set_playlist() 98 99 # OSC controller 100 self.osc_controller = OSCController(self.osc_port) 101 self.osc_controller.add_method('/play', 'i', self.osc_play_pause) 102 self.osc_controller.add_method('/stop', 'i', self.osc_stop) 103 self.osc_controller.start() 104 105 # GPIO controller 106 self.gpio_controller = GPIOController() 107 self.gpio_controller.add_channel_callback(self.gpio_channel_play, self.gpio_play, 3000) 108 self.gpio_controller.add_channel_callback(self.gpio_channel_stop, self.gpio_stop, 1000) 109 self.gpio_controller.start() 110 111 # The pipeline 112 self.pipeline = gst.Pipeline() 113 114 # Create bus and connect several handlers 115 self.bus = self.pipeline.get_bus() 116 self.bus.add_signal_watch() 117 self.bus.connect('message::eos', self.on_eos) 118 #self.bus.connect('message::tag', self.on_tag) 119 self.bus.connect('message::error', self.on_error) 120 121 # Create elements 122 self.srcdec = gst.element_factory_make('uridecodebin') 123 self.conv = gst.element_factory_make('audioconvert') 124 self.rsmpl = gst.element_factory_make('audioresample') 125 self.sink = gst.element_factory_make('alsasink') 126 127 # Set 'uri' property on uridecodebin 128 #self.srcdec.set_property('uri', 'file:///fake') 129 self.play_id = 0 130 self.uri = self.playlist[self.play_id] 131 self.srcdec.set_property('uri', self.uri) 132 133 # Connect handler for 'pad-added' signal 134 self.srcdec.connect('pad-added', self.on_pad_added) 135 136 # Eq 137 #self.eq = gst.element_factory_make('equalizer-10bands') 138 #self.eq.set_property('band0', -24.0) 139 140 # ALSA 141 self.sink.set_property('device', self.alsa_device) 142 143 # Add elements to pipeline 144 self.pipeline.add(self.srcdec, self.conv, self.rsmpl, self.sink) 145 146 # Link *some* elements 147 # This is completed in self.on_new_decoded_pad() 148 gst.element_link_many(self.conv, self.rsmpl, self.sink) 149 150 # Reference used in self.on_new_decoded_pad() 151 self.apad = self.conv.get_pad('sink') 152 153 # The MainLoop 154 self.mainloop = gobject.MainLoop() 155 156 if self.playing: 157 self.play()
158
159 - def on_pad_added(self, element, pad):
160 caps = pad.get_caps() 161 name = caps[0].get_name() 162 #print 'on_pad_added:', name 163 if name == 'audio/x-raw-float' or name == 'audio/x-raw-int': 164 if not self.apad.is_linked(): # Only link once 165 pad.link(self.apad)
166
167 - def on_eos(self, bus, msg):
168 if self.auto_next: 169 self.next() 170 else: 171 self.stop()
172
173 - def on_tag(self, bus, msg):
174 taglist = msg.parse_tag() 175 print 'on_tag:' 176 for key in taglist.keys(): 177 print '\t%s = %s' % (key, taglist[key])
178
179 - def on_error(self, bus, msg):
180 error = msg.parse_error() 181 print 'on_error:', error[1] 182 self.mainloop.quit()
183
184 - def set_playlist(self):
185 for root, dirs, files in os.walk(self.play_dir): 186 for filename in files: 187 path = root + os.sep + filename 188 self.playlist.append(path2url(path)) 189 self.playlist.sort()
190
191 - def next(self):
192 self.play_id += 1 193 if self.play_id >= len(self.playlist): 194 self.play_id = 0 195 self.uri = self.playlist[self.play_id] 196 self.pipeline.set_state(gst.STATE_NULL) 197 self.srcdec.set_property('uri', self.uri) 198 self.pipeline.set_state(gst.STATE_PLAYING) 199 if DEBUG: 200 print self.play_id, self.uri
201
202 - def gpio_parasite_filter(self):
203 time.sleep(self.gpio_parasite_filter_time) 204 return self.gpio_controller.server.input(self.gpio_channel_play)
205
206 - def play(self):
207 if not self.playing: 208 self.pipeline.set_state(gst.STATE_PLAYING) 209 self.playing = True 210 elif self.auto_next: 211 self.next()
212
213 - def stop(self):
214 if self.playing: 215 self.pipeline.set_state(gst.STATE_NULL) 216 self.playing = False
217
218 - def pause(self):
219 if self.playing: 220 self.pipeline.set_state(gst.STATE_PAUSED) 221 self.playing = False
222
223 - def osc_play_pause(self, path, value):
224 value = value[0] 225 if value and not self.playing: 226 self.play() 227 else: 228 self.pause()
229
230 - def osc_stop(self, path, value):
231 value = value[0] 232 if value and self.playing: 233 self.stop()
234
235 - def gpio_play(self, channel):
236 if self.gpio_parasite_filter(): 237 self.play()
238
239 - def gpio_stop(self, channel):
240 if self.gpio_parasite_filter(): 241 self.stop()
242
243 - def run(self):
244 self.mainloop.run()
245
246 - def quit(self):
247 self.mainloop.quit()
248