def __init__(self, _): juice.Juice.__init__(self, False) self.codec = Codecker(PT_PCMU) self.currentRecordings = {} self.currentPlayouts = {} self.cookies = 0
class MediaServerControlProtocol(batch.JuiceChild): #runs in RTP subprocess file = None def __init__(self, _): juice.Juice.__init__(self, False) self.codec = Codecker(PT_PCMU) self.currentRecordings = {} self.currentPlayouts = {} self.cookies = 0 def dropCall(self, cookie): pass def incomingRTP(self, cookie, packet): rtp, fObj = self.currentRecordings[cookie] if packet.header.ct is PT_NTE: data = packet.data key = ord(data[0]) start = (ord(data[1]) & 128) and True or False if start: DTMF(cookie=cookie, key=key).do(self) else: #print "stop inbound dtmf", key return else: if fObj is not None: fObj.write(self.codec.decode(packet)) def command_START_RECORDING(self, cookie, filename, format="raw"): rtp, currentFile = self.currentRecordings[cookie] formats = {"wav": WavWriter, "raw": (lambda f: f)} if format not in formats: raise ValueError("no support for writing format %r" % (format,)) if currentFile is not None: log.msg("Uh oh we were already recording in %s" % (currentFile)) currentFile.close() log.msg("FORMAT IS! %s" % (formats[format],)) self.currentRecordings[cookie] = (rtp, formats[format](open(filename, 'wb'))) return {} command_START_RECORDING.command = StartRecording def command_STOP_RECORDING(self, cookie): #XXX what should this return if cookie in self.currentRecordings: rtp, f = self.currentRecordings[cookie] self.currentRecordings[cookie] = (rtp, None) if f: f.close() return {} command_STOP_RECORDING.command = StopRecording def command_PLAY_FILE(self, cookie, filename, format="raw"): """ Play a shtoom-format sound file. (Raw unsigned linear, 16 bit 8000Hz audio. sox options: -u -w -r 8000) """ rtp, _ = self.currentRecordings[cookie] formats = {"wav": (WavReader, 160), "raw": ((lambda f: f), 320), "gsm": (GSMReader, 320)} if format not in formats: raise ValueError("no support for format %r" % (format,)) codec, samplesize = formats[format] f = codec(open(filename)) d = defer.Deferred() def playSample(): data = f.read(samplesize) if data == '': self.stopPlaying(cookie, True) else: sample = self.codec.handle_audio(data) rtp.handle_media_sample(sample) if cookie in self.currentPlayouts: self.stopPlaying(cookie, False) LC = task.LoopingCall(playSample) LC.start(0.020) self.currentPlayouts[cookie] = LC, d return d command_PLAY_FILE.command = PlayFile def command_CREATE_RTPSOCKET(self, host): c = self.makeCookie() rtp = RTPProtocol(self, c) self.currentRecordings[c] = (rtp, None) rtp.createRTPSocket(host, False) return {"cookie": c} command_CREATE_RTPSOCKET.command = CreateRTPSocket def command_GET_SDP(self, cookie, othersdp=None): rtp, _ = self.currentRecordings[cookie] if othersdp: sdptxt = SDP(othersdp) else: sdptxt = None return {"sdp": rtp.getSDP(sdptxt).show()} command_GET_SDP.command = GetSDP def command_STOP(self, cookie): rtp, _ = self.currentRecordings[cookie] self.stopPlaying(cookie, False) self.command_STOP_RECORDING(cookie) del self.currentRecordings[cookie] rtp.stopSendingAndReceiving() rtp.timeouterLoop.stop() return {} command_STOP.command = RTPStop def command_START(self, cookie, targethost, targetport): rtp, _ = self.currentRecordings[cookie] rtp.start((targethost, targetport)) return {} command_START.command = RTPStart def command_STOP_PLAYING(self, cookie): self.stopPlaying(cookie, False) return {} command_STOP_PLAYING.command = StopPlaying def stopPlaying(self, cookie, finishedPlaying): if cookie not in self.currentPlayouts: return LC, d = self.currentPlayouts[cookie] if LC: LC.stop() LC = None d.callback({"done": finishedPlaying}) del self.currentPlayouts[cookie] def makeCookie(self): self.cookies += 1 return "cookie%s" % (self.cookies,)
class MediaServerControlProtocol(batch.JuiceChild): #runs in RTP subprocess file = None def __init__(self, _): juice.Juice.__init__(self, False) self.codec = Codecker(PT_PCMU) self.currentRecordings = {} self.currentPlayouts = {} self.cookies = 0 def dropCall(self, cookie): pass def incomingRTP(self, cookie, packet): rtp, fObj = self.currentRecordings[cookie] if packet.header.ct is PT_NTE: data = packet.data key = ord(data[0]) start = (ord(data[1]) & 128) and True or False if start: DTMF(cookie=cookie, key=key).do(self) else: #print "stop inbound dtmf", key return else: if fObj is not None: fObj.write(self.codec.decode(packet)) def command_START_RECORDING(self, cookie, filename, format="raw"): rtp, currentFile = self.currentRecordings[cookie] formats = {"wav": WavWriter, "raw": (lambda f: f)} if format not in formats: raise ValueError("no support for writing format %r" % (format, )) if currentFile is not None: log.msg("Uh oh we were already recording in %s" % (currentFile)) currentFile.close() log.msg("FORMAT IS! %s" % (formats[format], )) self.currentRecordings[cookie] = (rtp, formats[format](open(filename, 'wb'))) return {} command_START_RECORDING.command = StartRecording def command_STOP_RECORDING(self, cookie): #XXX what should this return if cookie in self.currentRecordings: rtp, f = self.currentRecordings[cookie] self.currentRecordings[cookie] = (rtp, None) if f: f.close() return {} command_STOP_RECORDING.command = StopRecording def command_PLAY_FILE(self, cookie, filename, format="raw"): """ Play a shtoom-format sound file. (Raw unsigned linear, 16 bit 8000Hz audio. sox options: -u -w -r 8000) """ rtp, _ = self.currentRecordings[cookie] formats = { "wav": (WavReader, 160), "raw": ((lambda f: f), 320), "gsm": (GSMReader, 320) } if format not in formats: raise ValueError("no support for format %r" % (format, )) codec, samplesize = formats[format] f = codec(open(filename)) d = defer.Deferred() def playSample(): data = f.read(samplesize) if data == '': self.stopPlaying(cookie, True) else: sample = self.codec.handle_audio(data) rtp.handle_media_sample(sample) if cookie in self.currentPlayouts: self.stopPlaying(cookie, False) LC = task.LoopingCall(playSample) LC.start(0.020) self.currentPlayouts[cookie] = LC, d return d command_PLAY_FILE.command = PlayFile def command_CREATE_RTPSOCKET(self, host): c = self.makeCookie() rtp = RTPProtocol(self, c) self.currentRecordings[c] = (rtp, None) rtp.createRTPSocket(host, False) return {"cookie": c} command_CREATE_RTPSOCKET.command = CreateRTPSocket def command_GET_SDP(self, cookie, othersdp=None): rtp, _ = self.currentRecordings[cookie] if othersdp: sdptxt = SDP(othersdp) else: sdptxt = None return {"sdp": rtp.getSDP(sdptxt).show()} command_GET_SDP.command = GetSDP def command_STOP(self, cookie): rtp, _ = self.currentRecordings[cookie] self.stopPlaying(cookie, False) self.command_STOP_RECORDING(cookie) del self.currentRecordings[cookie] rtp.stopSendingAndReceiving() rtp.timeouterLoop.stop() return {} command_STOP.command = RTPStop def command_START(self, cookie, targethost, targetport): rtp, _ = self.currentRecordings[cookie] rtp.start((targethost, targetport)) return {} command_START.command = RTPStart def command_STOP_PLAYING(self, cookie): self.stopPlaying(cookie, False) return {} command_STOP_PLAYING.command = StopPlaying def stopPlaying(self, cookie, finishedPlaying): if cookie not in self.currentPlayouts: return LC, d = self.currentPlayouts[cookie] if LC: LC.stop() LC = None d.callback({"done": finishedPlaying}) del self.currentPlayouts[cookie] def makeCookie(self): self.cookies += 1 return "cookie%s" % (self.cookies, )