comparison service/playSound/playSound.py @ 669:b27a4652cd84

playsound is working ok on dash right now Ignore-this: 3a0b801cb75eb157a7d189f9de5d7b0c
author drewp@bigasterisk.com
date Sun, 22 Dec 2019 00:34:08 -0800
parents aaabba10ce04
children
comparison
equal deleted inserted replaced
668:aaabba10ce04 669:b27a4652cd84
1 """ 1 """
2 play sounds according to POST requests. 2 play sounds according to POST requests.
3 """ 3 """
4 from docopt import docopt 4 from docopt import docopt
5 import cyclone.web 5 import cyclone.web
6 import os, sys, tempfile, itertools 6 import os, sys, tempfile, itertools, subprocess
7 import treq
7 from twisted.internet import reactor 8 from twisted.internet import reactor
8 from cyclone.httpclient import fetch 9 from twisted.internet.defer import inlineCallbacks
9 from twisted.web.static import File 10 from twisted.web.static import File
10 from standardservice.logsetup import log, verboseLogging 11 from standardservice.logsetup import log, verboseLogging
11 12
12 class LOADING(object): pass 13 class LOADING(object): pass
13 14
16 self.buffers = {} # URIRef : path 17 self.buffers = {} # URIRef : path
17 self.playingSources = [] 18 self.playingSources = []
18 self.queued = [] 19 self.queued = []
19 self.volume = 1 # level for the next sound that's played (or existing instances of the same sound) 20 self.volume = 1 # level for the next sound that's played (or existing instances of the same sound)
20 21
22 @inlineCallbacks
21 def _getSound(self, uri): 23 def _getSound(self, uri):
22 def done(resp): 24 resp = yield treq.get(uri.encode('utf8'))
23 print('save') 25 body = yield treq.content(resp)
24 body = bytes(resp.body) 26 path = '/tmp/sound_%s' % hash(uri)
25 path = '/tmp/sound_%s' % hash(uri) 27 with open(path, 'wb') as out:
26 with open(path, 'wb') as out: 28 out.write(body)
27 out.write(body) 29 log.info('write %s bytes to %s', len(body), path)
28 log.info('write %s bytes to %s', len(resp.body), path) 30 self.buffers[uri] = path
29 self.buffers[uri] = path 31 print('donesave')
30 print('donesave')
31
32 return fetch(uri.encode('utf8')).addCallback(done).addErrback(log.error)
33 32
34 def playEffect(self, uri: str): 33 def playEffect(self, uri: str):
35 if uri not in self.buffers: 34 if uri not in self.buffers:
36 self.buffers[uri] = LOADING 35 self.buffers[uri] = LOADING
37 self._getSound(uri).addCallback(lambda ret: self.playEffect(uri)) 36 self._getSound(uri).addCallback(lambda ret: self.playEffect(uri)).addErrback(log.error)
38 return 37 return b'will play after load'
39 if self.buffers[uri] is LOADING: 38 if self.buffers[uri] is LOADING:
40 # The first playback loads then plays, but any attempts 39 # The first playback loads then plays, but any attempts
41 # during that load are dropped, not queued. 40 # during that load are dropped, not queued.
42 return 41 return
43 snd = self.buffers[uri] 42 snd = self.buffers[uri]
44 print('subp') 43 print('subp')
45 subprocess.check_call(['paplay', snd]) 44 subprocess.check_call(['paplay', snd])
46 return 45 return b'played'
47 46
48 def done(self, src): 47 def done(self, src):
49 try: 48 try:
50 self.playingSources.remove(src) 49 self.playingSources.remove(src)
51 except ValueError: 50 except ValueError:
63 self.render('index.html') 62 self.render('index.html')
64 63
65 class PlaySound(cyclone.web.RequestHandler): 64 class PlaySound(cyclone.web.RequestHandler):
66 def post(self): 65 def post(self):
67 uri = self.get_argument('uri') 66 uri = self.get_argument('uri')
68 self.settings.sfx.playEffect(uri) 67 return self.settings.sfx.playEffect(uri)
69 return "ok"
70 68
71 class Volume(cyclone.web.RequestHandler): 69 class Volume(cyclone.web.RequestHandler):
72 def put(self): 70 def put(self):
73 self.settings.sfx.setVolume(float(self.get_argument('v'))) 71 self.settings.sfx.setVolume(float(self.get_argument('v')))
74 return "ok" 72 return b"ok"
75 73
76 class StopAll(cyclone.web.RequestHandler): 74 class StopAll(cyclone.web.RequestHandler):
77 def post(self): 75 def post(self):
78 self.settings.sfx.stopAll() 76 self.settings.sfx.stopAll()
79 return "ok" 77 return b"ok"
80 78
81 79
82 if __name__ == '__main__': 80 if __name__ == '__main__':
83 arg = docopt(''' 81 arg = docopt('''
84 Usage: playSound.py [options] 82 Usage: playSound.py [options]