From 3e56ff11b32829edcf81b4e51eaa76cdfafa69ae Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 16 Oct 2012 23:10:01 +0200 Subject: first part of multi source support --- src/flufigut.py | 505 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 251 insertions(+), 254 deletions(-) (limited to 'src/flufigut.py') diff --git a/src/flufigut.py b/src/flufigut.py index 651d8fb..a3759a5 100755 --- a/src/flufigut.py +++ b/src/flufigut.py @@ -57,7 +57,7 @@ cf.close(); # globals = config['globals'] input = config['input'] -transcode = config['transcode'] +mux = config['mux'] stream = config['stream'] atmosphere = {} flow = {} @@ -76,277 +76,274 @@ for machine in globals['machines']: ### generate input components ################################### flow['input'] = {} -input_name = "" -input_type = "" -input_samplerate = 0 -input_resolution = "" - -if 'input' not in worker: - worker['input'] = -1 -else: - worker['input'] = 1 +master = 0 for source in input: - input_name = 'input-%s' % source - input_type = input[source]['type'] - flow['input'][input_name] = { - 'type': input[source]['source'], - 'desc': "capture raw %s from %s" % (input[source]['type'], source), - 'worker': 'input', + name = 'input-%s' % source + if name not in worker: + worker[name] = -1 + else: + worker[name] = 1 + flow['input'][name] = { + 'type': input[source]['type'], + 'desc': "capture raw data from %s" % (source), + 'worker': name, + 'master': input[source]['master'], 'properties': {}, } + if input[source]['master']: + master += 1 properties = input[source]['properties'] for property in properties.keys(): if property == 'resolution': - flow['input'][input_name]['properties']['width'] = globals['resolutions'][properties[property]]['width'] - flow['input'][input_name]['properties']['height'] = globals['resolutions'][properties[property]]['height'] - flow['input'][input_name]['properties']['framerate'] = globals['resolutions'][properties[property]]['rate'] - input_resolution = properties[property] + flow['input'][name]['properties']['width'] = globals['resolutions'][properties[property]]['width'] + flow['input'][name]['properties']['height'] = globals['resolutions'][properties[property]]['height'] + flow['input'][name]['properties']['framerate'] = globals['resolutions'][properties[property]]['rate'] else: - flow['input'][input_name]['properties'][property] = properties[property] - if property == 'samplerate': - input_samplerate = properties[property] - - break # until now only one input source can be used - -if input_name == "": - raise SystemExit("no input defined!") - -samplerates = [ ] -resolutions = [ ] -for format in transcode.keys(): - if 'samplerate' in globals['formats'][format]: - samplerate = globals['formats'][format]['samplerate'] - if samplerate not in samplerates: - if input_samplerate != samplerate: - samplerates.append(samplerate) - for profile in transcode[format]: - if 'video' in globals['profiles'][profile]: - if input_resolution == "": - raise SystemExit("format definition needs video but no video input given") - resolution = globals['profiles'][profile]['video'] - if resolution not in resolutions: - if input_resolution != resolution: - if globals['resolutions'][resolution]['rate'] != globals['resolutions'][input_resolution]['rate']: - raise SystemExit("ERROR: video rate conversion is not yet supported!!!") - resolutions.append(resolution) - -for resolution in resolutions: - if 'resize' not in worker: - worker['resize'] = -1 - else: - worker['resize'] = 1 - if input_type == 'av': - feeder = '%s:%s' % (input_name, "video") - elif input_type == 'vo': - feeder = '%s' % (input_name) - else: - raise SystemExit("format definition needs video but no video input given") - flow['input']['resize-%s' % resolution] = { - 'type': 'video-resize', - 'desc': "resize video to %sx%s" % (globals['resolutions'][resolution]['width'], globals['resolutions'][resolution]['height']), - 'worker': 'resize', - 'feeder': feeder, - 'properties': { - 'width': globals['resolutions'][resolution]['width'], - 'height': globals['resolutions'][resolution]['height'], - }, - } - -for samplerate in samplerates: - if 'resample' not in worker: - worker['resample'] = -1 - else: - worker['resample'] = 1 - - if input_type == 'av': - feeder = '%s:%s' % (input_name, "audio") - elif input_type == 'ao': - feeder = '%s' % (input_name) - else: - raise SystemExit("format definition needs audio but no audio input given") - flow['input']['resample-%s' % samplerate] = { - 'type': 'audio-resample', - 'desc': "resample audio to %s Hz" % samplerate, - 'worker': 'resample', - 'feeder': feeder, - 'properties': { - 'samplerate': samplerate, - }, - } + flow['input'][name]['properties'][property] = properties[property] + +if master == 0: + raise SystemExit("You have not configured any master clock device!") +elif master > 1: + raise SystemExit("You have configured multiple master clock devices!") + + + +# samplerates = [ ] +# resolutions = [ ] +# for format in transcode.keys(): +# if 'samplerate' in globals['formats'][format]: +# samplerate = globals['formats'][format]['samplerate'] +# if samplerate not in samplerates: +# if input_samplerate != samplerate: +# samplerates.append(samplerate) +# for profile in transcode[format]: +# if 'video' in globals['profiles'][profile]: +# if input_resolution == "": +# raise SystemExit("format definition needs video but no video input given") +# resolution = globals['profiles'][profile]['video'] +# if resolution not in resolutions: +# if input_resolution != resolution: +# if globals['resolutions'][resolution]['rate'] != globals['resolutions'][input_resolution]['rate']: +# raise SystemExit("ERROR: video rate conversion is not yet supported!!!") +# resolutions.append(resolution) + +# for resolution in resolutions: +# if 'resize' not in worker: +# worker['resize'] = -1 +# else: +# worker['resize'] = 1 +# if input_type == 'av': +# feeder = '%s:%s' % (input_name, "video") +# elif input_type == 'vo': +# feeder = '%s' % (input_name) +# else: +# raise SystemExit("format definition needs video but no video input given") +# flow['input']['resize-%s' % resolution] = { +# 'type': 'video-resize', +# 'desc': "resize video to %sx%s" % (globals['resolutions'][resolution]['width'], globals['resolutions'][resolution]['height']), +# 'worker': 'resize', +# 'feeder': feeder, +# 'properties': { +# 'width': globals['resolutions'][resolution]['width'], +# 'height': globals['resolutions'][resolution]['height'], +# }, +# } + +# for samplerate in samplerates: +# if 'resample' not in worker: +# worker['resample'] = -1 +# else: +# worker['resample'] = 1 + +# if input_type == 'av': +# feeder = '%s:%s' % (input_name, "audio") +# elif input_type == 'ao': +# feeder = '%s' % (input_name) +# else: +# raise SystemExit("format definition needs audio but no audio input given") +# flow['input']['resample-%s' % samplerate] = { +# 'type': 'audio-resample', +# 'desc': "resample audio to %s Hz" % samplerate, +# 'worker': 'resample', +# 'feeder': feeder, +# 'properties': { +# 'samplerate': samplerate, +# }, +# } ### generate encoder and muxer components ####################### flow['encoder_video'] = {} flow['encoder_audio'] = {} flow['muxer'] = {} -for format in transcode.keys(): - for profile in transcode[format]: - video_encoder = 'none' - if 'video' in globals['formats'][format]: - encoder = globals['formats'][format]['video'] - resolution = globals['profiles'][profile]['video'] - bitrate = globals['bitrates'][encoder][resolution] - if resolution != input_resolution: - feeder = 'resize-%s' % resolution - else: - if input_type == 'av': - feeder = '%s:%s' % (input_name, "video") - elif input_type == 'vo': - feeder = '%s' % (input_name) - else: - raise SystemExit("format definition needs audio but no audio input given") - video_encoder = 'encode-%s-%s' % (encoder, resolution) - if video_encoder not in flow['encoder_video'].keys(): - worker_name = 'encoder-%s-%s' % (encoder, resolution) - if worker_name not in worker: - worker[worker_name] = -1 - else: - worker[worker_name] = 1 - flow['encoder_video'][video_encoder] = { - 'type': '%s-encode' % encoder, - 'desc': "%s encoder for %sx%s" % (encoder, globals['resolutions'][resolution]['width'], globals['resolutions'][resolution]['height']), - 'worker': worker_name, - 'feeder': feeder, - 'properties': { - 'bitrate': bitrate, - }, - } - - audio_encoder = 'none' - if 'audio' in globals['formats'][format]: - encoder = globals['formats'][format]['audio'] - bitrate = globals['profiles'][profile]['audio'] - if 'samplerate' in globals['formats'][format]: - samplerate = globals['formats'][format]['samplerate'] - else: - samplerate = input_samplerate - - if samplerate != input_samplerate: - feeder = 'resample-%s' % samplerate - else: - if input_type == 'av': - feeder = '%s:%s' % (input_name, "audio") - elif input_type == 'ao': - feeder = '%s' % (input_name) - else: - raise SystemExit("format definition needs audio but no audio input given") - audio_encoder = 'encode-%s-%i-%i' % (encoder, bitrate, samplerate) - if audio_encoder not in flow['encoder_audio']: - worker_name = 'encoder-%s-%s' % (encoder, bitrate) - if worker_name not in worker: - worker[worker_name] = -1 - else: - worker[worker_name] = 1 - flow['encoder_audio'][audio_encoder] = { - 'type': '%s-encode' % encoder, - 'desc': "%s encoder for %i kbit/s @ %i Hz" % (encoder, bitrate, samplerate), - 'worker': worker_name, - 'feeder': feeder, - 'properties': { - 'bitrate': bitrate, - }, - } - - muxer = globals['formats'][format]['muxer'] - worker_name = 'muxer-%s-%s' % (format, profile) - if worker_name not in worker: - worker[worker_name] = -1 - else: - worker[worker_name] = 1 - flow['muxer']['muxer-%s-%s' % (format, profile)] = { - 'type': '%s-mux' % muxer, - 'desc': "%s muxer profile %s" % (format, profile), - 'worker': worker_name, - 'feeder_audio': audio_encoder, - 'feeder_video': video_encoder, - 'properties': {}, - } +# for format in transcode.keys(): +# for profile in transcode[format]: +# video_encoder = 'none' +# if 'video' in globals['formats'][format]: +# encoder = globals['formats'][format]['video'] +# resolution = globals['profiles'][profile]['video'] +# bitrate = globals['bitrates'][encoder][resolution] +# if resolution != input_resolution: +# feeder = 'resize-%s' % resolution +# else: +# if input_type == 'av': +# feeder = '%s:%s' % (input_name, "video") +# elif input_type == 'vo': +# feeder = '%s' % (input_name) +# else: +# raise SystemExit("format definition needs audio but no audio input given") +# video_encoder = 'encode-%s-%s' % (encoder, resolution) +# if video_encoder not in flow['encoder_video'].keys(): +# worker_name = 'encoder-%s-%s' % (encoder, resolution) +# if worker_name not in worker: +# worker[worker_name] = -1 +# else: +# worker[worker_name] = 1 +# flow['encoder_video'][video_encoder] = { +# 'type': '%s-encode' % encoder, +# 'desc': "%s encoder for %sx%s" % (encoder, globals['resolutions'][resolution]['width'], globals['resolutions'][resolution]['height']), +# 'worker': worker_name, +# 'feeder': feeder, +# 'properties': { +# 'bitrate': bitrate, +# }, +# } + +# audio_encoder = 'none' +# if 'audio' in globals['formats'][format]: +# encoder = globals['formats'][format]['audio'] +# bitrate = globals['profiles'][profile]['audio'] +# if 'samplerate' in globals['formats'][format]: +# samplerate = globals['formats'][format]['samplerate'] +# else: +# samplerate = input_samplerate + +# if samplerate != input_samplerate: +# feeder = 'resample-%s' % samplerate +# else: +# if input_type == 'av': +# feeder = '%s:%s' % (input_name, "audio") +# elif input_type == 'ao': +# feeder = '%s' % (input_name) +# else: +# raise SystemExit("format definition needs audio but no audio input given") +# audio_encoder = 'encode-%s-%i-%i' % (encoder, bitrate, samplerate) +# if audio_encoder not in flow['encoder_audio']: +# worker_name = 'encoder-%s-%s' % (encoder, bitrate) +# if worker_name not in worker: +# worker[worker_name] = -1 +# else: +# worker[worker_name] = 1 +# flow['encoder_audio'][audio_encoder] = { +# 'type': '%s-encode' % encoder, +# 'desc': "%s encoder for %i kbit/s @ %i Hz" % (encoder, bitrate, samplerate), +# 'worker': worker_name, +# 'feeder': feeder, +# 'properties': { +# 'bitrate': bitrate, +# }, +# } + +# muxer = globals['formats'][format]['muxer'] +# worker_name = 'muxer-%s-%s' % (format, profile) +# if worker_name not in worker: +# worker[worker_name] = -1 +# else: +# worker[worker_name] = 1 +# flow['muxer']['muxer-%s-%s' % (format, profile)] = { +# 'type': '%s-mux' % muxer, +# 'desc': "%s muxer profile %s" % (format, profile), +# 'worker': worker_name, +# 'feeder_audio': audio_encoder, +# 'feeder_video': video_encoder, +# 'properties': {}, +# } ### generate streamer components ################################ flow['streamer'] = {} -for cluster in stream.keys(): - streamer_cnt = stream[cluster]['count'] - port = stream[cluster]['port'] - for idx in range(streamer_cnt): - stream_worker = '%s%i'%(cluster, idx+1) - for machine in globals['machines'].keys(): - if stream_worker in globals['machines'][machine]: - if machine in machines: - if 'porter' in machines[machine]: - if port in machines[machine]['porter']: - raise SystemExit("ERROR: porter cannot be created because machine '%s' already uses port %i" % (machine, port)) - else: - machines[machine]['porter'] = {} - else: - machines[machine] = { 'porter': {} } - - machines[machine]['porter'][port] = { - 'socket-path': "porter-%s"%(rand_string()), - 'username': rand_string(size=12), - 'password': rand_string(size=12), - } - - if stream_worker not in worker: - worker[stream_worker] = -1 - else: - worker[stream_worker] = 1 - atmosphere['porter-%s-%i'%(machine, port)] = { - 'type': "porter", - 'desc': "Porter for %s on port %i"%(machine, port), - 'worker': stream_worker, - 'properties': { - 'port': port, - 'socket-path': machines[machine]['porter'][port]['socket-path'], - 'username': machines[machine]['porter'][port]['username'], - 'password': machines[machine]['porter'][port]['password'], - }, - } - - for format in stream[cluster]['formats']: - for profile in transcode[format]: - feeder = 'muxer-%s-%s' % (format, profile) - name = '%s-%s%i-%s-%s' % (stream[cluster]['type'], cluster, idx+1, format, profile) - mount_point = '/%s-%s.%s' % (format, profile, globals['formats'][format]['muxer']) - if streamer_cnt > 1: - hostname = "%s.%s" % (stream[cluster]['hostname'] % (idx+1), globals['domain']) - if idx != 0: - hostname_next = "%s.%s" % (stream[cluster]['hostname'] % (idx), globals['domain']) - else: - hostname_next = "%s.%s" % (stream[cluster]['hostname'] % (streamer_cnt), globals['domain']) - else: - hostname = "%s.%s" % (stream[cluster]['hostname'], globals['domain']) - flow['streamer'][name] = { - 'type': "%s-stream" % stream[cluster]['type'], - 'desc': "%s streamer for %s-%s (part %i of %s cluster)" % (stream[cluster]['type'], format, profile, idx+1, cluster), - 'worker': stream_worker, - 'feeder': feeder, - 'rrd_clients' : "%s/%s_clients.rrd" % (globals['rrd-dir'], name), - 'rrd_bytes' : "%s/%s_bytes.rrd" % (globals['rrd-dir'], name), - 'properties': { - 'description': globals['description'], - 'type': 'slave', - 'porter-socket-path': machines[machine]['porter'][port]['socket-path'], - 'porter-username': machines[machine]['porter'][port]['username'], - 'porter-password': machines[machine]['porter'][port]['password'], - 'mount-point': mount_point, - 'hostname': hostname, - 'port': port, - } - } - for prop in stream[cluster]: - if prop == 'max-con': - flow['streamer'][name]['properties']['client-limit'] = stream[cluster][prop] - if streamer_cnt > 1: - flow['streamer'][name]['properties']['redirect-on-overflow'] = "http://%s:%i%s" % (hostname_next, port, mount_point) - if prop == 'max-bw': - flow['streamer'][name]['properties']['bandwidth-limit'] = stream[cluster][prop] - if streamer_cnt > 1: - flow['streamer'][name]['properties']['redirect-on-overflow'] = "http://%s:%i%s" % (hostname_next, port, mount_point) - if prop == 'burst-on-connect': - flow['streamer'][name]['properties']['burst-on-connect'] = 'true' - flow['streamer'][name]['properties']['burst-time'] = stream[cluster][prop] +# for cluster in stream.keys(): +# streamer_cnt = stream[cluster]['count'] +# port = stream[cluster]['port'] +# for idx in range(streamer_cnt): +# stream_worker = '%s%i'%(cluster, idx+1) +# for machine in globals['machines'].keys(): +# if stream_worker in globals['machines'][machine]: +# if machine in machines: +# if 'porter' in machines[machine]: +# if port in machines[machine]['porter']: +# raise SystemExit("ERROR: porter cannot be created because machine '%s' already uses port %i" % (machine, port)) +# else: +# machines[machine]['porter'] = {} +# else: +# machines[machine] = { 'porter': {} } + +# machines[machine]['porter'][port] = { +# 'socket-path': "porter-%s"%(rand_string()), +# 'username': rand_string(size=12), +# 'password': rand_string(size=12), +# } + +# if stream_worker not in worker: +# worker[stream_worker] = -1 +# else: +# worker[stream_worker] = 1 +# atmosphere['porter-%s-%i'%(machine, port)] = { +# 'type': "porter", +# 'desc': "Porter for %s on port %i"%(machine, port), +# 'worker': stream_worker, +# 'properties': { +# 'port': port, +# 'socket-path': machines[machine]['porter'][port]['socket-path'], +# 'username': machines[machine]['porter'][port]['username'], +# 'password': machines[machine]['porter'][port]['password'], +# }, +# } + +# for format in stream[cluster]['formats']: +# for profile in transcode[format]: +# feeder = 'muxer-%s-%s' % (format, profile) +# name = '%s-%s%i-%s-%s' % (stream[cluster]['type'], cluster, idx+1, format, profile) +# mount_point = '/%s-%s.%s' % (format, profile, globals['formats'][format]['muxer']) +# if streamer_cnt > 1: +# hostname = "%s.%s" % (stream[cluster]['hostname'] % (idx+1), globals['domain']) +# if idx != 0: +# hostname_next = "%s.%s" % (stream[cluster]['hostname'] % (idx), globals['domain']) +# else: +# hostname_next = "%s.%s" % (stream[cluster]['hostname'] % (streamer_cnt), globals['domain']) +# else: +# hostname = "%s.%s" % (stream[cluster]['hostname'], globals['domain']) +# flow['streamer'][name] = { +# 'type': "%s-stream" % stream[cluster]['type'], +# 'desc': "%s streamer for %s-%s (part %i of %s cluster)" % (stream[cluster]['type'], format, profile, idx+1, cluster), +# 'worker': stream_worker, +# 'feeder': feeder, +# 'rrd_clients' : "%s/%s_clients.rrd" % (globals['rrd-dir'], name), +# 'rrd_bytes' : "%s/%s_bytes.rrd" % (globals['rrd-dir'], name), +# 'properties': { +# 'description': globals['description'], +# 'type': 'slave', +# 'porter-socket-path': machines[machine]['porter'][port]['socket-path'], +# 'porter-username': machines[machine]['porter'][port]['username'], +# 'porter-password': machines[machine]['porter'][port]['password'], +# 'mount-point': mount_point, +# 'hostname': hostname, +# 'port': port, +# } +# } +# for prop in stream[cluster]: +# if prop == 'max-con': +# flow['streamer'][name]['properties']['client-limit'] = stream[cluster][prop] +# if streamer_cnt > 1: +# flow['streamer'][name]['properties']['redirect-on-overflow'] = "http://%s:%i%s" % (hostname_next, port, mount_point) +# if prop == 'max-bw': +# flow['streamer'][name]['properties']['bandwidth-limit'] = stream[cluster][prop] +# if streamer_cnt > 1: +# flow['streamer'][name]['properties']['redirect-on-overflow'] = "http://%s:%i%s" % (hostname_next, port, mount_point) +# if prop == 'burst-on-connect': +# flow['streamer'][name]['properties']['burst-on-connect'] = 'true' +# flow['streamer'][name]['properties']['burst-time'] = stream[cluster][prop] ### sanity checks, cont'd ####################################### -- cgit v1.2.3