diff --git a/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java b/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java
index 9c8f3f4295bd29ce8d08a1e0afcba84f74459c8d..af89aaf7eddc82a6f5165107b22dcf4d2195853a 100644
--- a/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java
@@ -65,6 +65,7 @@ public class LiveStreamCourseNode extends AbstractAccessableCourseNode {
 	public static final String CONFIG_BUFFER_BEFORE_MIN = "bufferBeforeMin";
 	public static final String CONFIG_BUFFER_AFTER_MIN = "bufferBeforeAfter";
 	public static final String CONFIG_COACH_CAN_EDIT = "coachCanEdit";
+	public static final String CONFIG_PLAYER_PROFILE = "playerProfile";
 
 	public LiveStreamCourseNode() {
 		super(TYPE);
@@ -130,6 +131,8 @@ public class LiveStreamCourseNode extends AbstractAccessableCourseNode {
 			config.setIntValue(CONFIG_BUFFER_BEFORE_MIN, liveStreamModule.getBufferBeforeMin());
 			config.setIntValue(CONFIG_BUFFER_AFTER_MIN, liveStreamModule.getBufferAfterMin());
 			config.setBooleanEntry(CONFIG_COACH_CAN_EDIT, liveStreamModule.isEditCoach());
+			// CONFIG_PLAYER_PROFILE has no default value, because previously the multi
+			// stream option has to be enabled and the default value has to be selected.
 		}
 		config.setConfigurationVersion(CURRENT_VERSION);
 	}
diff --git a/src/main/java/org/olat/course/nodes/livestream/LiveStreamModule.java b/src/main/java/org/olat/course/nodes/livestream/LiveStreamModule.java
index cf91567e79608746dab92000dd8acb9ee1d4d1e6..2d4c701c7abca5dbbe8afdd3ceaa82c5346ad804 100644
--- a/src/main/java/org/olat/course/nodes/livestream/LiveStreamModule.java
+++ b/src/main/java/org/olat/course/nodes/livestream/LiveStreamModule.java
@@ -37,13 +37,17 @@ import org.springframework.stereotype.Service;
 public class LiveStreamModule extends AbstractSpringModule implements ConfigOnOff {
 
 	public static final String LIVE_STREAM_ENABLED = "live.stream.enabled";
+	public static final String LIVE_STREAM_MULTI_STREAM_ENABLED = "live.stream.multi.stream.enabled";
 	public static final String LIVE_STREAM_URL_SEPARATOR = "live.stream.url.separator";
 	public static final String LIVE_STREAM_BUFFER_BEFORE_MIN = "live.stream.buffer.before.min";
 	public static final String LIVE_STREAM_BUFFER_AFTER_MIN = "live.stream.buffer.after.min";
 	public static final String LIVE_STREAM_EDIT_COACH = "live.stream.edit.coach";
+	public static final String LIVE_STREAM_PLAYER_PROFILE = "live.stream.player.profile";
 
 	@Value("${live.stream.enabled:false}")
 	private boolean enabled;
+	@Value("${live.stream.multi.stream.enabled:false}")
+	private boolean multiStreamEnabled;
 	@Value("${live.stream.url.separator:,}")
 	private String urlSeparator;
 	@Value("${live.stream.buffer.before.min:5}")
@@ -52,6 +56,8 @@ public class LiveStreamModule extends AbstractSpringModule implements ConfigOnOf
 	private int bufferAfterMin;
 	@Value("${live.stream.edit.coach:false}")
 	private boolean editCoach;
+	@Value("${live.stream.player.profile:both}")
+	private String playerProfile;
 	
 	@Autowired
 	public LiveStreamModule(CoordinatorManager coordinatorManager) {
@@ -65,6 +71,11 @@ public class LiveStreamModule extends AbstractSpringModule implements ConfigOnOf
 			enabled = "true".equals(enabledObj);
 		}
 		
+		String multiStreamEnabledObj = getStringPropertyValue(LIVE_STREAM_MULTI_STREAM_ENABLED, true);
+		if(StringHelper.containsNonWhitespace(multiStreamEnabledObj)) {
+			multiStreamEnabled = "true".equals(multiStreamEnabledObj);
+		}
+		
 		String urlSeparatorObj = getStringPropertyValue(LIVE_STREAM_URL_SEPARATOR, true);
 		if(StringHelper.containsNonWhitespace(urlSeparatorObj)) {
 			urlSeparator = urlSeparatorObj;
@@ -84,6 +95,11 @@ public class LiveStreamModule extends AbstractSpringModule implements ConfigOnOf
 		if(StringHelper.containsNonWhitespace(editCoachObj)) {
 			editCoach = "true".equals(editCoachObj);
 		}
+		
+		String playerProfileObj = getStringPropertyValue(LIVE_STREAM_PLAYER_PROFILE, true);
+		if(StringHelper.containsNonWhitespace(playerProfileObj)) {
+			playerProfile = playerProfileObj;
+		}
 	}
 	
 	@Override
@@ -101,6 +117,15 @@ public class LiveStreamModule extends AbstractSpringModule implements ConfigOnOf
 		setStringProperty(LIVE_STREAM_ENABLED, Boolean.toString(enabled), true);
 	}
 
+	public boolean isMultiStreamEnabled() {
+		return multiStreamEnabled;
+	}
+
+	public void setMultiStreamEnabled(boolean multiStreamEnabled) {
+		this.multiStreamEnabled = multiStreamEnabled;
+		setStringProperty(LIVE_STREAM_MULTI_STREAM_ENABLED, Boolean.toString(multiStreamEnabled), true);
+	}
+
 	public String getUrlSeparator() {
 		return urlSeparator;
 	}
@@ -137,4 +162,13 @@ public class LiveStreamModule extends AbstractSpringModule implements ConfigOnOf
 		setStringProperty(LIVE_STREAM_EDIT_COACH, Boolean.toString(editCoach), true);
 	}
 
+	public String getPlayerProfile() {
+		return playerProfile;
+	}
+
+	public void setPlayerProfile(String playerProfile) {
+		this.playerProfile = playerProfile;
+		setStringProperty(LIVE_STREAM_PLAYER_PROFILE, playerProfile, true);
+	}
+
 }
diff --git a/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamServiceImpl.java b/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b7a52b92f5d4a1ea2b5aab3f4867366e4557bca
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamServiceImpl.java
@@ -0,0 +1,150 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.course.nodes.livestream.manager;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.olat.commons.calendar.CalendarManager;
+import org.olat.commons.calendar.CalendarUtils;
+import org.olat.commons.calendar.model.KalendarEvent;
+import org.olat.commons.calendar.ui.components.KalendarRenderWrapper;
+import org.olat.course.nodes.cal.CourseCalendars;
+import org.olat.course.nodes.livestream.LiveStreamEvent;
+import org.olat.course.nodes.livestream.LiveStreamService;
+import org.olat.course.nodes.livestream.model.LiveStreamEventImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * 
+ * Initial date: 28 May 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class LiveStreamServiceImpl implements LiveStreamService {
+	
+	private ScheduledExecutorService scheduler;
+	
+	@Autowired
+	private CalendarManager calendarManager;
+
+	@Override
+	public ScheduledExecutorService getScheduler() {
+		if (scheduler == null) {
+			ThreadFactory threadFactory = new CustomizableThreadFactory("oo-livestream-");
+			scheduler = Executors.newScheduledThreadPool(1, threadFactory);
+		}
+		return scheduler;
+	}
+
+	@Override
+	public List<? extends LiveStreamEvent> getRunningEvents(CourseCalendars calendars, int bufferBeforeMin,
+			int bufferAfterMin) {
+		Date now = new Date();
+		
+		Calendar cFrom = Calendar.getInstance();
+		cFrom.setTime(now);
+		cFrom.add(Calendar.MINUTE, -bufferAfterMin);
+		Date from = cFrom.getTime();
+		
+		Calendar cTo = Calendar.getInstance();
+		cTo.setTime(now);
+		cTo.add(Calendar.MINUTE, bufferBeforeMin);
+		Date to = cTo.getTime();
+		
+		return getLiveStreamEvents(calendars, from, to);
+	}
+	
+	@Override
+	public List<? extends LiveStreamEvent> getUpcomingEvents(CourseCalendars calendars, int bufferBeforeMin) {
+		Date now = new Date();
+		Calendar cFrom = Calendar.getInstance();
+		cFrom.setTime(now);
+		cFrom.add(Calendar.MINUTE, bufferBeforeMin);
+		Date from = cFrom.getTime();
+		Calendar cTo = Calendar.getInstance();
+		cTo.setTime(now);
+		cTo.add(Calendar.YEAR, 10);
+		Date to = cTo.getTime();
+		
+		return getLiveStreamEvents(calendars, from, to).stream()
+				.filter(notStartedFilter(from))
+				.collect(Collectors.toList());
+	}
+
+	private Predicate<LiveStreamEvent> notStartedFilter(Date from) {
+		return (LiveStreamEvent e) -> {
+			return !e.getBegin().before(from);
+			};
+	}
+
+	private List<? extends LiveStreamEvent> getLiveStreamEvents(CourseCalendars calendars, Date from, Date to) {
+		List<LiveStreamEvent> liveStreamEvents = new ArrayList<>();
+		for (KalendarRenderWrapper cal : calendars.getCalendars()) {
+			if(cal != null) {
+				boolean privateEventsVisible = cal.isPrivateEventsVisible();
+				List<KalendarEvent> events = calendarManager.getEvents(cal.getKalendar(), from, to, privateEventsVisible);
+				for(KalendarEvent event:events) {
+					if(!privateEventsVisible && event.getClassification() == KalendarEvent.CLASS_PRIVATE) {
+						continue;
+					}
+					
+					if (isLiveStream(event)) {
+						boolean timeOnly = !privateEventsVisible && event.getClassification() == KalendarEvent.CLASS_X_FREEBUSY;
+						LiveStreamEventImpl liveStreamEvent = toLiveStreamEvent(event, timeOnly);
+						liveStreamEvents.add(liveStreamEvent);
+					};
+				}
+			}
+		}
+		
+		return liveStreamEvents;
+	}
+	
+	private boolean isLiveStream(KalendarEvent event) {
+		return event.getLiveStreamUrl() != null;
+	}
+
+	private LiveStreamEventImpl toLiveStreamEvent(KalendarEvent event, boolean timeOnly) {
+		LiveStreamEventImpl liveStreamEvent = new LiveStreamEventImpl();
+		liveStreamEvent.setId(event.getID());
+		liveStreamEvent.setAllDayEvent(event.isAllDayEvent());
+		liveStreamEvent.setBegin(event.getBegin());
+		Date end = CalendarUtils.endOf(event);
+		liveStreamEvent.setEnd(end);
+		liveStreamEvent.setLiveStreamUrl(event.getLiveStreamUrl());
+		if (!timeOnly) {
+			liveStreamEvent.setSubject(event.getSubject());
+			liveStreamEvent.setDescription(event.getDescription());
+			liveStreamEvent.setLocation(event.getLocation());
+		}
+		return liveStreamEvent;
+	}
+}
diff --git a/src/main/java/org/olat/course/nodes/livestream/paella/PaellaMapper.java b/src/main/java/org/olat/course/nodes/livestream/paella/PaellaMapper.java
index 2593b785fa199c2e83b6a1a63cd2c8a02f3f091b..ba11b49eca69f2b758d713b938835aeb9f8d4822 100644
--- a/src/main/java/org/olat/course/nodes/livestream/paella/PaellaMapper.java
+++ b/src/main/java/org/olat/course/nodes/livestream/paella/PaellaMapper.java
@@ -49,9 +49,11 @@ public class PaellaMapper implements Mapper {
 	private final ObjectMapper mapper = new ObjectMapper();
 	
 	private final Streams streams;
+	private final PlayerProfile playerProfile;
 	
-	public PaellaMapper(Streams streams) {
+	public PaellaMapper(Streams streams, PlayerProfile playerProfile) {
 		this.streams = streams;
+		this.playerProfile = playerProfile;
 	}
 
 	@Override
@@ -210,18 +212,9 @@ public class PaellaMapper implements Mapper {
 		sb.append("      'es.upv.paella.translecture.captionsPlugin': {'enabled':true},");
 		sb.append("      'es.upv.paella.trimmingPlayerPlugin': {'enabled':true},");
 		sb.append("      'es.upv.paella.windowTitlePlugin': {'enabled': true},");
-		sb.append("      'es.upv.paella.singleStreamProfilePlugin': {");
-		sb.append("          'enabled': true,");
-		sb.append("          'videoSets': [");
-		sb.append("            { 'icon':'professor_icon.svg', 'id':'professor', 'content':['stream1']},");
-		sb.append("            { 'icon':'slide_icon.svg', 'id':'slide', 'content':['stream2']}");
-		sb.append("          ]");
-		sb.append("      },");
-		sb.append("      'es.upv.paella.dualStreamProfilePlugin': { 'enabled':true,");
-		sb.append("        'videoSets': [");
-		sb.append("          { 'icon':'slide_professor_icon.svg', 'id':'slide_over_professor', 'content':['stream1','stream2'] }");
-		sb.append("        ]");
-		sb.append("      }");
+		playerProfile.appendPlayerConfig(sb);
+		// The last plugin must not have a comma at the and of the configs.
+		sb.append("      'es.upv.paella.windowTitlePlugin': {'enabled': true}");
 		sb.append("    }");
 		sb.append("  },");
 		sb.append("  'defaultProfile':'presenter_presentation',");
diff --git a/src/main/java/org/olat/course/nodes/livestream/paella/PlayerProfile.java b/src/main/java/org/olat/course/nodes/livestream/paella/PlayerProfile.java
new file mode 100644
index 0000000000000000000000000000000000000000..707fed01afbbb6b58474079943e2459d5ea4e62c
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/livestream/paella/PlayerProfile.java
@@ -0,0 +1,84 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.course.nodes.livestream.paella;
+
+import org.olat.core.gui.render.StringOutput;
+
+/**
+ * 
+ * Initial date: 17 Dec 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public enum PlayerProfile {
+	
+	both("player.profile.both") {
+		@Override
+		public void appendPlayerConfig(StringOutput sb) {
+			sb.append("      'es.upv.paella.singleStreamProfilePlugin': {");
+			sb.append("          'enabled': true,");
+			sb.append("          'videoSets': [");
+			sb.append("            { 'icon':'professor_icon.svg', 'id':'professor', 'content':['stream1']},");
+			sb.append("            { 'icon':'slide_icon.svg', 'id':'slide', 'content':['stream2']}");
+			sb.append("          ]");
+			sb.append("      },");
+			sb.append("      'es.upv.paella.dualStreamProfilePlugin': { 'enabled':true,");
+			sb.append("        'videoSets': [");
+			sb.append("          { 'icon':'slide_professor_icon.svg', 'id':'slide_over_professor', 'content':['stream1','stream2'] }");
+			sb.append("        ]");
+			sb.append("      },");
+		}
+	},
+	stream1("player.profile.stream1") {
+		@Override
+		public void appendPlayerConfig(StringOutput sb) {
+			sb.append("      'es.upv.paella.singleStreamProfilePlugin': {");
+			sb.append("          'enabled': true,");
+			sb.append("          'videoSets': [");
+			sb.append("            { 'icon':'professor_icon.svg', 'id':'professor', 'content':['stream1']}");
+			sb.append("          ]");
+			sb.append("      },");
+		}
+	},
+	stream2("player.profile.stream2") {
+		@Override
+		public void appendPlayerConfig(StringOutput sb) {
+			sb.append("      'es.upv.paella.singleStreamProfilePlugin': {");
+			sb.append("          'enabled': true,");
+			sb.append("          'videoSets': [");
+			sb.append("            { 'icon':'slide_icon.svg', 'id':'slide', 'content':['stream2']}");
+			sb.append("          ]");
+			sb.append("      },");
+		}
+	};
+	
+	private final String i18nKey;
+
+	private PlayerProfile(String i18nKey) {
+		this.i18nKey = i18nKey;
+	}
+
+	public String getI18nKey() {
+		return i18nKey;
+	}
+
+	public abstract void appendPlayerConfig(StringOutput sb);
+
+}
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamAdminController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamAdminController.java
index 3542060814b45dbdc6102fd00b2a16b7c0bb00c7..906d7470b2281257f09f3a745edb0820fd3dfdcc 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamAdminController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamAdminController.java
@@ -19,21 +19,29 @@
  */
 package org.olat.course.nodes.livestream.ui;
 
+import static org.olat.core.gui.components.util.KeyValues.entry;
 import static org.olat.core.gui.translator.TranslatorHelper.translateAll;
 import static org.olat.course.nodes.livestream.ui.LiveStreamUIFactory.validateInteger;
 import static org.olat.course.nodes.livestream.ui.LiveStreamUIFactory.validateMandatory;
 
 import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.util.KeyValues;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.course.nodes.livestream.LiveStreamModule;
+import org.olat.course.nodes.livestream.paella.PlayerProfile;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import edu.emory.mathcs.backport.java.util.Arrays;
+
 /**
  * 
  * Initial date: 5 Jun 2019<br>
@@ -45,17 +53,18 @@ public class LiveStreamAdminController extends FormBasicController {
 	private static final String[] ENABLED_KEYS = new String[]{"on"};
 	
 	private MultipleSelectionElement enabledEl;
+	private MultipleSelectionElement multiStreamEnabledEl;
 	private TextElement urlSeparatorEl;
 	private TextElement bufferBeforeMinEl;
 	private TextElement bufferAfterMinEl;
 	private MultipleSelectionElement coachCanEditEl;
+	private SingleSelection playerProfileEl;
 	
 	@Autowired
 	private LiveStreamModule liveStreamModule;
 
 	public LiveStreamAdminController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl, LAYOUT_BAREBONE);
-		
 		initForm(ureq);
 	}
 
@@ -70,6 +79,11 @@ public class LiveStreamAdminController extends FormBasicController {
 				translateAll(getTranslator(), ENABLED_KEYS));
 		enabledEl.select(ENABLED_KEYS[0], liveStreamModule.isEnabled());
 		
+		multiStreamEnabledEl = uifactory.addCheckboxesHorizontal("admin.multi.stream.enabled", generalCont,
+				ENABLED_KEYS, translateAll(getTranslator(), ENABLED_KEYS));
+		multiStreamEnabledEl.addActionListener(FormEvent.ONCHANGE);
+		multiStreamEnabledEl.select(ENABLED_KEYS[0], liveStreamModule.isMultiStreamEnabled());
+		
 		urlSeparatorEl = uifactory.addTextElement("admin.url.separator", 10, liveStreamModule.getUrlSeparator(), generalCont);
 		urlSeparatorEl.setMandatory(true);
 		urlSeparatorEl.setHelpTextKey("admin.url.separator.help", null);
@@ -95,10 +109,37 @@ public class LiveStreamAdminController extends FormBasicController {
 		boolean coachCanEdit = liveStreamModule.isEditCoach();
 		coachCanEditEl.select(ENABLED_KEYS[0], coachCanEdit);
 		
+		KeyValues playerProfileKV = new KeyValues();
+		for (PlayerProfile playerProfile : PlayerProfile.values()) {
+			playerProfileKV.add(entry(playerProfile.name(), translate(playerProfile.getI18nKey())));
+		}
+		playerProfileEl = uifactory.addDropdownSingleselect("admin.player.profile", defaultValuesCont, playerProfileKV.keys(),
+				playerProfileKV.values());
+		String playerProfile = liveStreamModule.getPlayerProfile();
+		if (Arrays.asList(playerProfileEl.getKeys()).contains(playerProfile)) {
+			playerProfileEl.select(playerProfile, true);
+		}
+
 		FormLayoutContainer buttonsCont = FormLayoutContainer.createDefaultFormLayout("buttons", getTranslator());
 		buttonsCont.setRootForm(mainForm);
 		formLayout.add("buttons", buttonsCont);
 		uifactory.addFormSubmitButton("save", buttonsCont);
+		
+		updateUI();
+	}
+
+	private void updateUI() {
+		boolean multiStream = multiStreamEnabledEl.isAtLeastSelected(1);
+		urlSeparatorEl.setVisible(multiStream);
+		playerProfileEl.setVisible(multiStream);
+	}
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if (source == multiStreamEnabledEl) {
+			updateUI();
+		}
+		super.formInnerEvent(ureq, source, event);
 	}
 
 	@Override
@@ -117,8 +158,13 @@ public class LiveStreamAdminController extends FormBasicController {
 		boolean enabled = enabledEl.isAtLeastSelected(1);
 		liveStreamModule.setEnabled(enabled);
 		
-		String urlSeparator = urlSeparatorEl.getValue();
-		liveStreamModule.setUrlSeparator(urlSeparator);
+		boolean multiStreamEnabled = multiStreamEnabledEl.isAtLeastSelected(1);
+		liveStreamModule.setMultiStreamEnabled(multiStreamEnabled);
+		
+		if (urlSeparatorEl.isVisible()) {
+			String urlSeparator = urlSeparatorEl.getValue();
+			liveStreamModule.setUrlSeparator(urlSeparator);
+		}
 		
 		int bufferBeforeMin = Integer.parseInt(bufferBeforeMinEl.getValue());
 		liveStreamModule.setBufferBeforeMin(bufferBeforeMin);
@@ -128,6 +174,11 @@ public class LiveStreamAdminController extends FormBasicController {
 		
 		boolean coachCanEdit = coachCanEditEl.isAtLeastSelected(1);
 		liveStreamModule.setEditCoach(coachCanEdit);
+		
+		if (playerProfileEl.isVisible()) {
+			String playerProfile = playerProfileEl.getSelectedKey();
+			liveStreamModule.setPlayerProfile(playerProfile);
+		}
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamConfigController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamConfigController.java
index 0c417d030d96809987b9a8ef8d2d0e758cc69015..638740ebdd5876d0e7957ff1403443cef9e22366 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamConfigController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamConfigController.java
@@ -19,19 +19,27 @@
  */
 package org.olat.course.nodes.livestream.ui;
 
+import static org.olat.core.gui.components.util.KeyValues.entry;
 import static org.olat.core.gui.translator.TranslatorHelper.translateAll;
 import static org.olat.course.nodes.livestream.ui.LiveStreamUIFactory.validateInteger;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.util.KeyValues;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.course.nodes.LiveStreamCourseNode;
+import org.olat.course.nodes.livestream.LiveStreamModule;
+import org.olat.course.nodes.livestream.paella.PlayerProfile;
 import org.olat.modules.ModuleConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
 
 /**
  * 
@@ -48,6 +56,10 @@ public class LiveStreamConfigController extends FormBasicController {
 	private TextElement bufferBeforeMinEl;
 	private TextElement bufferAfterMinEl;
 	private MultipleSelectionElement coachCanEditEl;
+	private SingleSelection playerProfileEl;
+	
+	@Autowired
+	private LiveStreamModule liveStreamModule;
 
 	public LiveStreamConfigController(UserRequest ureq, WindowControl wControl, ModuleConfiguration moduleConfiguration) {
 		super(ureq, wControl);
@@ -73,6 +85,20 @@ public class LiveStreamConfigController extends FormBasicController {
 		boolean coachCanEdit = config.getBooleanSafe(LiveStreamCourseNode.CONFIG_COACH_CAN_EDIT);
 		coachCanEditEl.select(ENABLED_KEYS[0], coachCanEdit);
 		
+		if (liveStreamModule.isMultiStreamEnabled()) {
+			KeyValues playerProfileKV = new KeyValues();
+			for (PlayerProfile playerProfile : PlayerProfile.values()) {
+				playerProfileKV.add(entry(playerProfile.name(), translate(playerProfile.getI18nKey())));
+			}
+			playerProfileEl = uifactory.addDropdownSingleselect("config.player.profile", formLayout, playerProfileKV.keys(),
+					playerProfileKV.values());
+			String playerProfile = config.getStringValue(LiveStreamCourseNode.CONFIG_PLAYER_PROFILE,
+					liveStreamModule.getPlayerProfile());
+			if (Arrays.asList(playerProfileEl.getKeys()).contains(playerProfile)) {
+				playerProfileEl.select(playerProfile, true);
+			}
+		}
+		
 		uifactory.addFormSubmitButton("save", formLayout);
 	}
 
@@ -101,6 +127,11 @@ public class LiveStreamConfigController extends FormBasicController {
 		boolean coachCanEdit = coachCanEditEl.isAtLeastSelected(1);
 		config.setBooleanEntry(LiveStreamCourseNode.CONFIG_COACH_CAN_EDIT, coachCanEdit);
 		
+		if (playerProfileEl != null) {
+			String playerProfile = playerProfileEl.getSelectedKey();
+			config.setStringValue(LiveStreamCourseNode.CONFIG_PLAYER_PROFILE, playerProfile);
+		}
+		
 		return config;
 	}
 
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamVideoController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamVideoController.java
index 9ea0d462e783d06b0c9b9b24cac7d4f5625afaf1..04743bf6211c1dfc645c95a72f7b4b6c892382e2 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamVideoController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamVideoController.java
@@ -36,6 +36,7 @@ import org.olat.core.util.UserSession;
 import org.olat.course.nodes.livestream.LiveStreamEvent;
 import org.olat.course.nodes.livestream.paella.PaellaFactory;
 import org.olat.course.nodes.livestream.paella.PaellaMapper;
+import org.olat.course.nodes.livestream.paella.PlayerProfile;
 import org.olat.course.nodes.livestream.paella.Streams;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -49,14 +50,16 @@ public class LiveStreamVideoController extends BasicController {
 
 	private final VelocityContainer mainVC;
 	
+	private final PlayerProfile playerProfile;
 	private final List<MapperKey> mappers = new ArrayList<>();
 	private String url;
 	
 	@Autowired
 	private MapperService mapperService;
 
-	protected LiveStreamVideoController(UserRequest ureq, WindowControl wControl) {
+	protected LiveStreamVideoController(UserRequest ureq, WindowControl wControl, PlayerProfile playerProfile) {
 		super(ureq, wControl);
+		this.playerProfile = playerProfile;
 		mainVC = createVelocityContainer("video");
 		updateUI(ureq.getUserSession());
 		putInitialPanel(mainVC);
@@ -74,7 +77,7 @@ public class LiveStreamVideoController extends BasicController {
 		if (StringHelper.containsNonWhitespace(url)) {
 			mainVC.contextPut("id", CodeHelper.getRAMUniqueID());
 			Streams streams = PaellaFactory.createStreams(url);
-			PaellaMapper paellaMapper = new PaellaMapper(streams);
+			PaellaMapper paellaMapper = new PaellaMapper(streams, playerProfile);
 			MapperKey mapperKey = mapperService.register(usess, paellaMapper);
 			mappers.add(mapperKey);
 			String baseURI = mapperKey.getUrl();
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewerController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewerController.java
index ee2b34e63faee8ed6f4b54bc10afb79b091610fd..1beb2df9bfc7e195771ff19e17d128a844525cba 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewerController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewerController.java
@@ -27,6 +27,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.util.UserSession;
 import org.olat.course.nodes.livestream.LiveStreamEvent;
+import org.olat.course.nodes.livestream.paella.PlayerProfile;
 
 /**
  * 
@@ -40,12 +41,12 @@ public class LiveStreamViewerController extends BasicController {
 	private final LiveStreamVideoController videoCtrl;
 	private final LiveStreamMetadataController metadataCtrl;
 
-	public LiveStreamViewerController(UserRequest ureq, WindowControl wControl) {
+	public LiveStreamViewerController(UserRequest ureq, WindowControl wControl, PlayerProfile playerProfile) {
 		super(ureq, wControl);
 		
 		mainVC = createVelocityContainer("viewer");
 		
-		videoCtrl = new LiveStreamVideoController(ureq, wControl);
+		videoCtrl = new LiveStreamVideoController(ureq, wControl, playerProfile);
 		listenTo(videoCtrl);
 		mainVC.put("video", videoCtrl.getInitialComponent());
 		metadataCtrl = new LiveStreamMetadataController(ureq, wControl);
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewersController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewersController.java
index 63caafe9036f92d3e944739f7e7cd7ff9ba533b4..366558f124aec1f870bbdc6c9313a76e883313ab 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewersController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamViewersController.java
@@ -30,11 +30,14 @@ import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.UserSession;
 import org.olat.course.nodes.LiveStreamCourseNode;
 import org.olat.course.nodes.cal.CourseCalendars;
 import org.olat.course.nodes.livestream.LiveStreamEvent;
+import org.olat.course.nodes.livestream.LiveStreamModule;
 import org.olat.course.nodes.livestream.LiveStreamService;
+import org.olat.course.nodes.livestream.paella.PlayerProfile;
 import org.olat.modules.ModuleConfiguration;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -66,6 +69,8 @@ public class LiveStreamViewersController extends BasicController {
 	private final List<DisplayWrapper> displayWrappers;
 	private Boolean noLiveStream;
 	
+	@Autowired
+	private LiveStreamModule liveStreamModule;
 	@Autowired
 	private LiveStreamService liveStreamService;
 	
@@ -76,56 +81,57 @@ public class LiveStreamViewersController extends BasicController {
 		
 		bufferBeforeMin = moduleConfiguration.getIntegerSafe(LiveStreamCourseNode.CONFIG_BUFFER_BEFORE_MIN, 0);
 		bufferAfterMin = moduleConfiguration.getIntegerSafe(LiveStreamCourseNode.CONFIG_BUFFER_AFTER_MIN, 0);
+		PlayerProfile playerProfile = getPlayerProfile(moduleConfiguration);
 		
 		mainVC = createVelocityContainer("viewers");
 		
 		displayWrappers = new ArrayList<>();
-		displayCtrl0 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl0 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl0);
 		mainVC.put("display0", displayCtrl0.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl0));
 		
-		displayCtrl1 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl1 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl1);
 		mainVC.put("display1", displayCtrl1.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl1));
 		
-		displayCtrl2 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl2 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl2);
 		mainVC.put("display2", displayCtrl2.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl2));
 		
-		displayCtrl3 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl3 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl3);
 		mainVC.put("display3", displayCtrl3.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl3));
 		
-		displayCtrl4 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl4 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl4);
 		mainVC.put("display4", displayCtrl4.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl4));
 		
-		displayCtrl5 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl5 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl5);
 		mainVC.put("display5", displayCtrl5.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl5));
 		
-		displayCtrl6 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl6 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl6);
 		mainVC.put("display6", displayCtrl6.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl6));
 		
-		displayCtrl7 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl7 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl7);
 		mainVC.put("display7", displayCtrl7.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl7));
 		
-		displayCtrl8 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl8 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl8);
 		mainVC.put("display8", displayCtrl8.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl8));
 		
-		displayCtrl9 = new LiveStreamViewerController(ureq, wControl);
+		displayCtrl9 = new LiveStreamViewerController(ureq, wControl, playerProfile);
 		listenTo(displayCtrl9);
 		mainVC.put("display9", displayCtrl9.getInitialComponent());
 		displayWrappers.add(new DisplayWrapper(displayCtrl9));
@@ -135,6 +141,20 @@ public class LiveStreamViewersController extends BasicController {
 		putInitialPanel(mainVC);
 	}
 	
+	private PlayerProfile getPlayerProfile(ModuleConfiguration moduleConfiguration) {
+		PlayerProfile playerProfile = PlayerProfile.stream1;
+		
+		if (liveStreamModule.isMultiStreamEnabled()) {
+			String nodePlayerProfile = moduleConfiguration.getStringValue(LiveStreamCourseNode.CONFIG_PLAYER_PROFILE);
+			if (StringHelper.containsNonWhitespace(nodePlayerProfile)) {
+				playerProfile = PlayerProfile.valueOf(nodePlayerProfile);
+			} else {
+				playerProfile = PlayerProfile.valueOf(liveStreamModule.getPlayerProfile());
+			}
+		}
+		return playerProfile;
+	}
+	
 	void refresh(UserSession usess) {
 		List<? extends LiveStreamEvent> events = liveStreamService.getRunningEvents(calendars, bufferBeforeMin, bufferAfterMin);
 		putNoLiveStreamToMainVC(events);
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamsController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamsController.java
index 8cf2a14417244382c9910645e5fcb42d6f99e36a..f620fc3e9cb2d099f42456caf047e4446a6f8164 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamsController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamsController.java
@@ -61,7 +61,7 @@ public class LiveStreamsController extends BasicController {
 			CourseCalendars calendars) {
 		super(ureq, wControl);
 		mainVC = createVelocityContainer("streams");
-
+		
 		viewersCtrl = new LiveStreamViewersController(ureq, wControl, moduleConfiguration, calendars);
 		listenTo(viewersCtrl);
 		mainVC.put("viewers", viewersCtrl.getInitialComponent());
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_de.properties
index 58b6369b9b15bf3830f8bfe7547e72ac9dbe1cf4..a63505df2ee05616236168c449d799fc3e979f82 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_de.properties
@@ -7,12 +7,15 @@ admin.general.title=$:\admin.menu.title
 admin.menu.title=Livestream
 admin.menu.title.alt=$:\admin.menu.title
 admin.module.enabled=Kursbaustein
+admin.multi.stream.enabled=Multistream
+admin.player.profile=Stream
 admin.url.separator=URL Trennzeichen
 admin.url.separator.help=Trennzeichen, um mehrere URLs eines einzelnen Termins zu trennen.
 condition.accessibility.title=Zugang
 config.buffer.before.min=Vorlaufzeit (in Minuten)
 config.buffer.after.min=Nachlaufzeit (in Minuten)
 config.coach.edit=Betreuer darf Termine bearbeiten
+config.player.profile=$\:admin.player.profile
 form.error.wrong.int=Falsches Zahlenformat. Beispiele\: 2, 10, 144
 link.text=Video Livestream
 list.title=Anstehende Livestreams
@@ -23,6 +26,9 @@ peekview.open.live=Livestream anzeigen
 peekview.open.upcoming=Alle anzeigen
 peekview.title.live=Jetzt live: {0}
 peekview.title.upcoming=Demn\u00E4chst: {0}
+player.profile.both=Beide Streams anzeigen
+player.profile.stream1=Stream 1 anzeigen
+player.profile.stream2=Stream 2 anzeigen
 run.edit.events=Termine bearbeiten
 run.streams=Live Streams
 table.empty=Es sind keine Livestreams anstehend.
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_en.properties
index e1560ff39bb91a517b904f7b2f2fd4389d31d2f3..dcccc5ff9fa344a5022005fcb2171e02a8cca979 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/_i18n/LocalStrings_en.properties
@@ -7,12 +7,15 @@ admin.general.title=$:\admin.menu.title
 admin.menu.title=Live stream
 admin.menu.title.alt=$:\admin.menu.title
 admin.module.enabled=Course element
+admin.multi.stream.enabled=Multi stream
+admin.player.profile=Stream
 admin.url.separator=URL separator
 admin.url.separator.help=Char / String to separate multiple URLs of a single event.
 condition.accessibility.title=Access
 config.buffer.before.min=Buffer time before start (in minutes)
 config.buffer.after.min=Buffer time after end (in minutes)
 config.coach.edit=Coach is allowed to edit
+config.player.profile=$\:admin.player.profile
 form.error.wrong.int=Wrong numeral format. Examples\: 2, 10, 144
 link.text=Video live stream
 list.title=Upcoming live streams
@@ -23,6 +26,9 @@ peekview.open.live=Show live stream
 peekview.open.upcoming=Show all
 peekview.title.live=Live: {0}
 peekview.title.upcoming=Upcoming: {0}
+player.profile.both=Show both streams
+player.profile.stream1=Show stream 1
+player.profile.stream2=Show stream 2
 run.edit.events=Edit events
 run.streams=Livestreams
 table.empty=No upcoming live streams are available.
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index 73b483d66f1632121a4df033d456ae996e468fcc..10610f39f9ebfc87e2f582b72c845c40fb601eaf 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -1656,6 +1656,8 @@ youtube.api.key=
 # Options for the live stream course node
 ###############################################################################
 live.stream.enabled=false
+# Enable multiple streams pre event. Actually two streams are supported.
+live.stream.multi.stream.enabled=false
 # Char / String to separate multiple urls of a single event
 live.stream.url.separator=,
 # Buffer time to switch from the announcement page to the live stream (in minutes)
@@ -1663,4 +1665,6 @@ live.stream.url.separator=,
 live.stream.buffer.before.min=5
 live.stream.buffer.after.min=5
 live.stream.edit.coach=false
-
+# Profile to control witch stream is visible for the watchers.
+live.stream.player.profile=both
+live.stream.player.profile.values=both,stream1,stream2