diff --git a/livestreams.py b/livestreams.py
index c89cd8265acbaf80b91d0a2f3c6972aa0a996568..346472021d5417783f6766484392fa3498d0ddc0 100644
--- a/livestreams.py
+++ b/livestreams.py
@@ -62,7 +62,7 @@ def restart_failed_live_transcode(id, type, data, state, status):
 	restart_job(id)
 
 @app.route('/internal/streaming')
-#@register_navbar('Streaming', icon='transfer')
+@register_navbar('Streaming', icon='broadcast-tower', iconlib='fa')
 @mod_required
 def streaming():
 	sources = query('SELECT * FROM live_sources WHERE NOT deleted')
@@ -152,3 +152,65 @@ def streamauth(server):
 		modify('UPDATE live_sources SET server = NULL, clientid = NULL, preview_key = NULL, last_active = ? WHERE server = ? AND clientid = ?', datetime.now(), server, request.values['clientid'])
 		return 'Ok', 200
 	return 'Bad request', 400
+
+def schedule_livestream(lecture_id):
+	def build_filter(l):
+		return ','.join(l) if l else None
+	server = 'rwth.video'
+	lecture = query('SELECT * FROM lectures WHERE id = ?', lecture_id)[0]
+	settings = json.loads(lecture['stream_settings'])
+	data = {'src1': {'afilter': [], 'vfilter': []}, 'src2': {'afilter': [], 'vfilter': []}, 'afilter': [], 'videoag_logo': int(bool(settings.get('video_showlogo'))), 'lecture_id': lecture['id']}
+	src1 = (query('SELECT * FROM live_sources WHERE NOT deleted AND id = ?', settings.get('source1')) or [{}])[0]
+	src2 = (query('SELECT * FROM live_sources WHERE NOT deleted AND id = ?', settings.get('source2')) or [{}])[0]
+	for idx, obj in zip([1,2], [src1, src2]):
+		if obj:
+			server = obj['server']
+			data['src%i'%idx]['url'] = 'rtmp://%s/src/%i'%(obj['server'], obj['id'])
+		mode = settings.get('source%i_audiomode'%idx)
+		leftvol = float(settings.get('source%i_leftvolume'%idx, 100))/100.0
+		rightvol = float(settings.get('source%i_rightvolume'%idx, 100))/100.0
+		if mode == 'mono':
+			data['src%i'%idx]['afilter'].append('pan=mono|c0=%f*c0+%f*c1'%(0.5*leftvol, 0.5*rightvol))
+		elif mode == 'stereo':
+			data['src%i'%idx]['afilter'].append('pan=stereo|c0=%f*c0|c1=%f*c1'%(leftvol, rightvol))
+		elif mode == 'unchanged':
+			pass
+		elif mode == 'off':
+			data['src%i'%idx]['afilter'].append('pan=mono|c0=0*c0')
+		else:
+			raise(Exception())
+	mode = settings.get('videomode')
+	if mode == '1':
+		data['vmix'] = 'streamselect=map=0'
+	elif mode == '2':
+		data['vmix'] = 'streamselect=map=1'
+	elif vmode == 'lecture4:3':
+		data['src1']['vfilter'].append('scale=1440:1080')
+		data['src2']['vfilter'].append('scale=1440:810,pad=1440:1080:0:135,crop=480:1080')
+		data['vmix'] = 'hstack'
+	elif vmode == 'lecture16:9':
+		data['src1']['vfilter'].append('scale=1440:810,pad=1440:1080:0:135')
+		data['src2']['vfilter'].append('scale=1440:810,pad=1440:1080:0:135,crop=480:1080')
+		data['vmix'] = 'hstack'
+	elif vmode == 'sidebyside':
+		data['src1']['vfilter'].append('scale=960:540')
+		data['src2']['vfilter'].append('scale=960:540')
+		data['vmix'] = 'hstack,pad=1920:1080:0:270'
+	if settings.get('audio_normalize'):
+		data['afilter'].append('loudnorm')
+	data['afilter'] = build_filter(data['afilter'])
+	data['src1']['afilter'] = build_filter(data['src1']['afilter'])
+	data['src1']['vfilter'] = build_filter(data['src1']['vfilter'])
+	data['src2']['afilter'] = build_filter(data['src2']['afilter'])
+	data['src2']['vfilter'] = build_filter(data['src2']['vfilter'])
+	data['destbase'] = 'rtmp://%s/hls/l_%i'%(server, lecture['id'])
+	job_id = schedule_job('complex_live_transcode', data, priority=10)
+	return job_id
+
+@app.route('/internal/streaming/start', methods=['POST'])
+@mod_required
+def start_stream():
+	lecture_id = int(request.values['lecture_id'])
+	course = (query('SELECT courses.* FROM courses JOIN lectures ON (courses.id = lectures.course_id) WHERE lectures.id = ?', lecture_id) or [None])[0]
+	schedule_livestream(lecture_id)
+	return redirect(url_for('course', handle=course['handle']))
diff --git a/static/smptebars.jpg b/static/smptebars.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2e0e5598fe39d82591d6b3c5f689b9cf6f9236bc
Binary files /dev/null and b/static/smptebars.jpg differ
diff --git a/templates/course.html b/templates/course.html
index c95340e31089a07f58df399f9179b2c8d5ff8c2d..b6677345af7cb1f8142fb7723d2aa871098e668a 100644
--- a/templates/course.html
+++ b/templates/course.html
@@ -160,12 +160,21 @@
 							<option value="{{ source.id }}">{{ source.name }}</option>
 							{% endfor %}
 						</select>
-						<img src="{{ config.VIDEOPREFIX }}/thumbnail/s_none.jpg" style="width: 100%; margin-bottom: 0.5em; margin-top: 0.5em"/>
-						<select name="source{{ snum }}_audiomode" class="form-control">
-							<option selected value="unchanged">Audio unverändert</option>
-							<option value="left">Nur linke Tonspur</option>
-							<option value="right">Nur rechte Tonspur</option>
-							<option value="mix">Monomix aller Tonspuren</option>
+						<img src="{{ url_for('static', filename='smptebars.jpg') }}" style="width: 100%; margin-bottom: 0.5em; margin-top: 0.5em"/>
+						<label>Lautstärke</label>
+						<div class="row">
+							<div class="col-xs-6">
+								<input type="range" name="source{{ snum }}_leftvolume" value="100">
+							</div>
+							<div class="col-xs-6">
+								<input type="range" name="source{{ snum }}_rightvolume" value="100">
+							</div>
+						</div>
+						<select name="source{{ snum }}_audiomode" class="form-control" style="margin-top: 0.5em">
+							<option value="mono" selected>Mono-Mix</option>
+							<option value="stereo">Stereo</option>
+							<option value="unchanged">Audio unverändert</option>
+							<option value="off">Kein Audio</option>
 						</select>
 					</div>
 					{% endfor %}
@@ -174,36 +183,27 @@
 						<select name="videomode" class="form-control">
 							<option value="1" selected>Nur Quelle 1</option>
 							<option value="2">Nur Quelle 2</option>
-							<option value="sidebyside">Side-by-Side (Quelle 1 groß, 1/3 von 2 daneben)</option>
+							<option value="lecture4:3">Quelle 1 (4:3) links, Ausschnitt von 2 rechts</option>
+							<option value="lecture16:9">Quelle 1 (16:9) links, Ausschnitt von 2 rechts</option>
+							<option value="sidebyside">Side-by-Side (Quelle 1 links, 2 rechts)</option>
 						</select>
 						<div class="checkbox"><label><input name="video_showlogo" type="checkbox" checked>Video AG-Logo einblenden</label></div>
 					</div>
-					<div class="col-xs-12" style="margin-top: 1em">
-						<label>Audio</label>
-						<select name="audiomode" class="form-control">
-							<option value="1" selected>Quelle 1</option>
-							<option value="2">Quelle 2</option>
-							<option value="splitstereo">Quelle 1 links, 2 rechts</option>
-							<option value="mix">Mix beider Quellen</option>
-						</select>
-						<div class="checkbox"><label><input name="audio_normalize" type="checkbox">Lautstärke normalisieren</label></div>
-					</div>
-					<div class="col-xs-12" style="margin-top: 1em">
-						<label>Ausgabeformat</label>
-						<select name="outputmode" class="form-control">
-							<option selected value="multi">1080p/720p/360p (Standard)</option>
-							<option value="720p">Nur 720p</option>
-						</select>
-					</div>
 					<div class="col-xs-12" style="margin-top: 1em">
 						<label>Weitere Einstellungen</label>
-						<div class="checkbox"><label><input name="autostart" type="checkbox" checked>Automatisch starten</label></div>
+						<div style="margin-top: -1em;">
+							<div class="checkbox"><label><input name="audio_normalize" type="checkbox">Lautstärke normalisieren</label></div>
+						</div>
 					</div>
 				</div>
 				</form>
 			</div>
 			<div class="modal-footer">
+				<form class="form-inline" method="post" action="{{ url_for('start_stream') }}">
+				<input type="hidden" id="editstream-lectureid" name="lecture_id" value="">
+				<button type="submit" id="editstream-start" class="btn btn-danger">Speichern und starten</button>
 				<button type="button" id="editstream-submit" class="btn btn-primary">Speichern</button>
+				</form>
 			</div>
 		</div>
 	</div>
@@ -212,7 +212,10 @@
 <script>
 function editstream_update() {
 	$('#editstream .source-select').each(function () {
-		$(this).siblings('img').prop('src', '{{ config.VIDEOPREFIX }}/thumbnail/s_'+$(this).val()+'.jpg');
+		if ($(this).val())
+			$(this).siblings('img').prop('src', '{{ config.VIDEOPREFIX }}/thumbnail/s_'+$(this).val()+'.jpg');
+		else
+			$(this).siblings('img').prop('src', {{ url_for('static', filename='smptebars.jpg')|tojson }});
 	});
 };
 function editstream_dump() {
@@ -223,6 +226,9 @@ function editstream_dump() {
 	$("#editstream select[name!='']").each(function () {
 		res[$(this).attr('name')] = $(this).val();
 	});
+	$("#editstream input[type='range'][name!='']").each(function () {
+		res[$(this).attr('name')] = $(this).val();
+	});
 	return res;
 };
 function editstream_load(obj) {
@@ -234,15 +240,24 @@ function editstream_load(obj) {
 		if ($(this).attr('name') in obj)
 			$(this).val(obj[$(this).attr('name')]);
 	});
+	$("#editstream input[type='range'][name!='']").each(function () {
+		if ($(this).attr('name') in obj)
+			$(this).val(obj[$(this).attr('name')]);
+	});
 };
 $('#editstream .source-select').on('change', editstream_update);
 $('#editstream-submit').on('click', function () {
 	moderator.api.set($('#editstream').data('currentpath'), JSON.stringify(editstream_dump()), true);
 	$('#editstream').modal('hide');
 });
+$('#editstream-start').on('click', function () {
+	moderator.api.set($('#editstream').data('currentpath'), JSON.stringify(editstream_dump()), true);
+	return true;
+});
 $('#editstream').on('show.bs.modal', function (event) {
 	var button = $(event.relatedTarget);
 	$('#editstream').data('currentpath', button.data('path'));
+	$('#editstream-lectureid').val(button.data('lectureid'));
 	$("#editstream-form")[0].reset();
 	if (button.data('value'))
 		editstream_load(button.data('value'));
diff --git a/templates/macros.html b/templates/macros.html
index 107cef430aa06216e1389efc8131b5e05dd20db6..f0de863e4ee9192180f095daf86de0532b253884 100644
--- a/templates/macros.html
+++ b/templates/macros.html
@@ -262,7 +262,7 @@ $('#embedcodebtn').popover(
 						</li>
 						{% if ismod() %}
 						<li class="pull-right">
-							<button class="btn btn-default" data-toggle="modal" data-target="#editstream" data-path="{{ 'lectures.%i.stream_settings'%lecture.id }}" data-value='{{ lecture.stream_settings|e }}'>
+							<button class="btn btn-default" data-toggle="modal" data-target="#editstream" data-lectureid="{{ lecture.id }}" data-path="{{ 'lectures.%i.stream_settings'%lecture.id }}" data-value='{{ lecture.stream_settings|e }}'>
 								<span class="fas fa-broadcast-tower"></span>
 							</button>
 						</li>