|
|
@@ -15,18 +15,56 @@ from Queue import Queue |
|
|
|
from twisted.internet.task import LoopingCall |
|
|
|
import fcntl |
|
|
|
|
|
|
|
STREAM_CMD="""tools/gsmdecode|ffmpeg -ar 8000 -ac 1 -f s16le -i /dev/stdin http://127.0.0.1:8090/feed.ffm""" |
|
|
|
from twisted.internet.protocol import ProcessProtocol |
|
|
|
|
|
|
|
silence_frame = open("sounds/silence-gsm.gsm", "rb").read() |
|
|
|
class StreamingProtocol(ProcessProtocol): |
|
|
|
|
|
|
|
class FRNStream(FRNClient): |
|
|
|
_silenceFrame = open("sounds/silence-gsm.gsm", "rb").read() |
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
self._frames = Queue() |
|
|
|
self._stream = subprocess.Popen(STREAM_CMD, shell=True, |
|
|
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
|
|
self._streamtimer = LoopingCall.withCount(self.sendStreamFrame) |
|
|
|
self._streamtimer.start(0.20) |
|
|
|
self._streamTimer = LoopingCall.withCount(self.sendStreamFrame) |
|
|
|
|
|
|
|
def connectionMade(self): |
|
|
|
log.msg("Streaming process started") |
|
|
|
self._streamTimer.start(0.20) |
|
|
|
|
|
|
|
def inConnectionLost(self): |
|
|
|
log.msg("connection lost") |
|
|
|
self._streamTimer.stop() |
|
|
|
|
|
|
|
def processExited(self, status): |
|
|
|
log.msg("Streaming process exited (%s)" % str(status)) |
|
|
|
|
|
|
|
def sendStreamFrame(self, count): |
|
|
|
for i in range(count): |
|
|
|
if self._frames.empty(): |
|
|
|
frames = self._silenceFrame |
|
|
|
else: |
|
|
|
frames = self._frames.get_nowait() |
|
|
|
self.transport.write(frames) |
|
|
|
|
|
|
|
def feed(self, frame): |
|
|
|
self._frames.put_nowait(frame) |
|
|
|
|
|
|
|
def eof(self): |
|
|
|
self.transport.closeStdin() |
|
|
|
|
|
|
|
|
|
|
|
STREAM_CMD="""tools/gsmstream.sh""" |
|
|
|
|
|
|
|
class FRNStream(FRNClient): |
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
self._stream = StreamingProtocol() |
|
|
|
|
|
|
|
def connectionMade(self): |
|
|
|
FRNClient.connectionMade(self) |
|
|
|
reactor.spawnProcess(self._stream, "bash", ["bash", "-c", STREAM_CMD], os.environ) |
|
|
|
|
|
|
|
def connectionLost(self, reason): |
|
|
|
FRNClient.connectionLost(self, reason) |
|
|
|
self._stream.eof() |
|
|
|
|
|
|
|
def getClientName(self, client_id): |
|
|
|
if self.clientsById.has_key(client_id): |
|
|
@@ -35,20 +73,9 @@ class FRNStream(FRNClient): |
|
|
|
return client_id |
|
|
|
|
|
|
|
def audioFrameReceived(self, from_id, frames): |
|
|
|
self._frames.put_nowait(frames) |
|
|
|
self._stream.feed(frames) |
|
|
|
self.pong() |
|
|
|
|
|
|
|
def sendStreamFrame(self, count): |
|
|
|
for i in range(count): |
|
|
|
if self._frames.empty(): |
|
|
|
frames = silence_frame |
|
|
|
else: |
|
|
|
frames = self._frames.get_nowait() |
|
|
|
self._stream.stdin.write(frames) |
|
|
|
self._stream.stdin.flush() |
|
|
|
self._stream.stdout.flush() |
|
|
|
self._stream.stderr.flush() |
|
|
|
|
|
|
|
def loginResponse(self, info): |
|
|
|
log.msg("Login: %s" % info['al']) |
|
|
|
|
|
|
|