#!/usr/bin/python # # flufigut # # flufigut, the flumotion configuration utility, is a simple tool # that generates flumotion configuration files using pyhton jinja2 # template engine and simplejson. flufigut generates planet.xml # and worker.xml files from configuration templates and an easy to # understand representation of the flow structure written in json. # # # Copyright (C) 2012 Christian Pointner # Michael Gebetsroither # # This file is part of flufigut. # # flufigut is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # any later version. # # flufigut is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with flufigut. If not, see . # import string import random import sys import simplejson as json from exceptions import * from jinja2 import Environment, FileSystemLoader ### helper functions ############################################ # def rand_string(size=8, chars=string.ascii_lowercase + string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for x in range(size)) ### parse json file ############################################# # if len(sys.argv) <= 2: raise SystemExit("No template name and or configuration file given") cf = open(sys.argv[2], 'r') config = json.load(cf); cf.close(); ### initialization ############################################## # atmosphere = {} flow = {} machines = {} ### generate porter for all streamer/machines ################### # idx = 0 for streamer in config['streamer']: worker = 'streamer%i'%(idx) port = streamer['config']['port'] found = False for machine in config['globals']['machines'].keys(): if worker in config['globals']['machines'][machine]: if machine in machines: if 'porter' in machines[machine]: if port in machines[machine]['porter']: print "Porter: machine %s already uses port %i" % (machine, port) sys.exit(1) else: machines[machine]['porter'] = {} else: machines[machine] = { 'porter': {} } found = True machines[machine]['porter'][port] = { 'socket-path': "porter%i-%s"%(idx, rand_string()), 'username': rand_string(size=12), 'password': rand_string(size=12), } atmosphere['porter-%s-%i'%(machine, port)] = { 'type': "porter", 'desc': "Porter for %s on port %i"%(machine, port), 'worker': worker, 'properties': { 'port': port, 'socket-path': machines[machine]['porter'][port]['socket-path'], 'username': machines[machine]['porter'][port]['username'], 'password': machines[machine]['porter'][port]['password'], }, } if not found: print "Streamer %i has no machine assigned" % (idx) sys.exit(1) idx+=1 ### generate input components ################################### flow['input'] = {} flow['input']['raw-input'] = { 'type': config['input']['source'], 'desc': "capture raw AV from %s" % config['input']['source'], 'worker': 'input', 'properties': {}, } for property in config['input'].keys(): if property == 'samplerate': flow['input']['raw-input']['properties'][property] = config['input']['samplerate'] elif property == 'resolution': flow['input']['raw-input']['properties']['width'] = config['globals']['resolutions'][config['input'][property]]['width'] flow['input']['raw-input']['properties']['height'] = config['globals']['resolutions'][config['input'][property]]['height'] flow['input']['raw-input']['properties']['framerate'] = config['globals']['resolutions'][config['input'][property]]['rate'] elif property != 'source': flow['input']['raw-input']['properties'][property] = config['input'][property] resolutions = [ ] for format in config['transcode'].keys(): for profile in config['transcode'][format]: resolution = config['globals']['profiles'][profile]['video'] if resolution not in resolutions: if config['input']['resolution'] != resolution: if config['globals']['resolutions'][resolution]['rate'] != config['globals']['resolutions'][config['input']['resolution']]['rate']: print "video rate conversion is not yet supported!!!" sys.exit(-1) resolutions.append(resolution) for resolution in resolutions: flow['input']['resize-%s' % resolution] = { 'type': 'video-resize', 'desc': "resize video to %sx%s" % (config['globals']['resolutions'][resolution]['width'], config['globals']['resolutions'][resolution]['height']), 'worker': 'input', 'feeder': 'raw-input:video', 'properties': { 'width': config['globals']['resolutions'][resolution]['width'], 'height': config['globals']['resolutions'][resolution]['height'], }, } samplerates = [ ] for format in config['globals']['formats'].keys(): if 'samplerate' in config['globals']['formats'][format]: samplerate = config['globals']['formats'][format]['samplerate'] if samplerate not in samplerates: if config['input']['samplerate'] != samplerate: samplerates.append(samplerate) for samplerate in samplerates: flow['input']['resample-%s' % samplerate] = { 'type': 'audio-resample', 'desc': "resample audio to %s Hz" % samplerate, 'worker': 'input', 'feeder': 'raw-input:audio', 'properties': { 'samplerate': samplerate, }, } ### generate encoder and muxer components ####################### flow['encoder'] = {} flow['muxer'] = {} # for encoder in config['encoder']['video'].keys(): # for resolution in config['encoder']['video'][encoder].keys(): # if resolution == config['input']['resolution']: # feeder = 'raw-input:video' # else: # feeder = 'resize-%s' % resolution # flow['encoder']['encode-%s-%s' % (encoder, resolution)] = { # 'type': '%s-encode' % encoder, # 'desc': "%s encoder for %sx%s" % (encoder, config['globals']['resolutions'][resolution]['width'], config['globals']['resolutions'][resolution]['height']), # 'worker': 'encoder-%s' % encoder, # 'feeder': feeder, # 'properties': { # 'bitrate': config['encoder']['video'][encoder][resolution], # }, # } # for encoder in config['encoder']['audio'].keys(): # for audiorate in config['encoder']['audio'][encoder]: # if config['globals']['audiorates'][audiorate]['samplerate'] == config['input']['samplerate']: # feeder = 'raw-input:audio' # else: # feeder = 'resample-%s' % config['globals']['audiorates'][audiorate]['samplerate'] # flow['encoder']['encode-%s-%s' % (encoder, audiorate)] = { # 'type': '%s-encode' % encoder, # 'desc': "%s encoder for %i kbit/s @ %i Hz" % (encoder, config['globals']['audiorates'][audiorate]['bitrate'], config['globals']['audiorates'][audiorate]['samplerate']), # 'worker': 'encoder-%s' % encoder, # 'feeder': feeder, # 'properties': { # 'bitrate': config['globals']['audiorates'][audiorate]['bitrate'], # }, # } # for format in config['muxer'].keys(): # muxer = config['globals']['formats'][format]['muxer'] # for profile in config['muxer'][format]: # resolution = config['globals']['profiles'][profile]['video'] # arate = config['globals']['profiles'][profile]['audio'] # feeder_audio = 'encoder-%s-%s' % (config['globals']['formats'][format]['audio'], arate) # if 'video' in config['globals']['formats'][format]: # feeder_video = 'encoder-%s-%s' % (config['globals']['formats'][format]['video'], resolution) # else: # feeder_video = 'none' # flow['muxer']['muxer-%s-%s' % (muxer, profile)] = { # 'type': '%s-mux' % muxer, # 'desc': "%s muxer profile %s" % (format, profile), # 'worker': 'muxer-%s' % muxer, # 'feeder_audio': feeder_audio, # 'feeder_video': feeder_video, # 'properties': {}, # } ### generate streamer components ################################ flow['streamer'] = {} # TODO ### initialize and render templates ############################# # env = Environment(loader=FileSystemLoader('../templates/%s/' % (sys.argv[1])), line_statement_prefix = '%%') template = env.get_template('planet.xml') planet = template.render(globals=config['globals'], atmosphere=atmosphere, flow=flow) sys.stdout.write(planet.encode("utf8")) ### end #########################################################