gnuradionetwork/stream.py

128 řádky
3.5 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
# See LICENSE.txt for copyright info
import subprocess
from frn.protocol.client import FRNClient, FRNClientFactory
from frn.user import FRNUser
from twisted.internet import reactor, task
from twisted.internet.defer import DeferredList
from twisted.python import log
import os, string
from Queue import Queue
from twisted.internet.task import LoopingCall
import fcntl
from twisted.internet.protocol import ProcessProtocol
class StreamingProtocol(ProcessProtocol):
_silenceFrame = open("sounds/silence-gsm.gsm", "rb").read()
def __init__(self):
self._frames = Queue()
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):
return self.clientsById[client_id]['on']
else:
return client_id
def audioFrameReceived(self, from_id, frames):
self._stream.feed(frames)
self.pong()
def loginResponse(self, info):
log.msg("Login: %s" % info['al'])
def clientsListUpdated(self, clients):
self.clients = clients
self.clientsById = dict([(i['id'], i) for i in clients])
class FRNStreamFactory(FRNClientFactory):
protocol = FRNStream
reactor = reactor
if __name__ == '__main__':
import sys
from os.path import dirname, join as pjoin
from ConfigParser import ConfigParser
log.startLogging(sys.stderr)
basedir = dirname(__file__)
acfg = ConfigParser()
acfg.read(['/etc/grn/accounts.conf',
pjoin(basedir,'accounts.conf'), 'accounts.conf'])
scfg = ConfigParser()
scfg.read(['/etc/grn/servers.conf',
pjoin(basedir,'servers.conf'), 'servers.conf'])
argc = len(sys.argv)
if argc >= 3:
server_name, network_name = sys.argv[2].split(':',1)
account_cfg = acfg.items(sys.argv[1])+[('network', network_name)]
server_cfg = scfg.items(server_name)
server = scfg.get(server_name, 'server')
port = scfg.getint(server_name, 'port')
d = dict(account_cfg)
user = FRNUser(
EA=d['email'],
PW=d['password'], ON=d['operator'],
BC=d['transmission'], DS=d['description'],
NN=d['country'], CT=d['city'], NT=d['network'])
reactor.connectTCP(server, port, FRNStreamFactory(user))
reactor.run()
# vim: set et ai sw=4 ts=4 sts=4: