Add experimental HTTP streaming using ffmpeg/ffserver

This commit is contained in:
Maurizio Porrato 2010-09-03 23:44:18 +02:00
parent ce03cf4447
commit 88b98baffd
5 changed files with 122 additions and 5 deletions

100
stream.py Executable file
View File

@ -0,0 +1,100 @@
#!/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
STREAM_CMD="""tools/gsmdecode|ffmpeg -ar 8000 -ac 1 -f s16le -i /dev/stdin http://127.0.0.1:8090/feed.ffm"""
silence_frame = open("sounds/silence-gsm.gsm", "rb").read()
class FRNStream(FRNClient):
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)
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._frames.put_nowait(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'])
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:

4
tools/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.o
*~
*%
gsmdecode

15
tools/Makefile Normal file
View File

@ -0,0 +1,15 @@
.PHONY: all clean
CC=gcc
CFLAGS=-Wall -O2 -I/usr/include/gsm
LDFLAGS=-lgsm
all: gsmdecode
clean:
$(RM) *~ *% *.o
$(RM) gsmdecode
gsmdecode: gsmdecode.c
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)

View File

@ -1,3 +1,4 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@ -6,12 +7,9 @@
int main() {
gsm handle = gsm_create();
int one = 1;
int zero = 0;
gsm_option(handle, GSM_OPT_WAV49, &one);
unsigned char src610[65];
gsm_frame src;
gsm_signal dst[160];
unsigned char outbuff[160];
while (!feof(stdin)) {
int rv = fread(src610, 65, 1, stdin);
if (rv < 0) {
@ -23,7 +21,6 @@ int main() {
}
int frameIndex = 0;
for (frameIndex = 0; frameIndex <= 1; frameIndex++) {
int iFrameIndex = !frameIndex;
gsm_decode(handle, src610 + 33 * frameIndex, dst);
rv = fwrite(dst, sizeof dst, 1, stdout);
if (rv < 0) {
@ -33,4 +30,6 @@ int main() {
}
}
gsm_destroy(handle);
return EXIT_SUCCESS;
}

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>