diff --git a/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java b/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java
index af89aaf7eddc82a6f5165107b22dcf4d2195853a..d425a2da081883f9f91acf59f2c2e3a3f7b900e4 100644
--- a/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/LiveStreamCourseNode.java
@@ -97,7 +97,7 @@ public class LiveStreamCourseNode extends AbstractAccessableCourseNode {
 			LiveStreamSecurityCallback secCallback = LiveStreamSecurityCallbackFactory
 					.createSecurityCallback(userCourseEnv, this.getModuleConfiguration());
 			OLATResource courseOres = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseResource();
-			runCtrl = new LiveStreamRunController(ureq, wControl, this.getModuleConfiguration(), courseOres, secCallback, calendars);
+			runCtrl = new LiveStreamRunController(ureq, wControl, this, courseOres, secCallback, calendars);
 		}
 		Controller ctrl = TitledWrapperHelper.getWrapper(ureq, wControl, runCtrl, this, "o_livestream_icon");
 		return new NodeRunConstructionResult(ctrl);
diff --git a/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallback.java b/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallback.java
index f44ed7e63cfdaab24cb5eca363578675fe6efdc3..e1088254c90f98c2fa28bf4587c795278c2d1e06 100644
--- a/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallback.java
+++ b/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallback.java
@@ -29,6 +29,8 @@ public interface LiveStreamSecurityCallback {
 
 	boolean canViewStreams();
 
-	boolean canEditStreams();
+	boolean canViewStatistic();
 	
+	boolean canEditStreams();
+
 }
diff --git a/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallbackFactory.java b/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallbackFactory.java
index 583dbeb1bb345f503f4b4991d9ab62c5b059e576..0218a5421fa9ba85eba02d2b8f0cbd9b8a6be250 100644
--- a/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallbackFactory.java
+++ b/src/main/java/org/olat/course/nodes/livestream/LiveStreamSecurityCallbackFactory.java
@@ -34,15 +34,18 @@ public class LiveStreamSecurityCallbackFactory {
 	public static LiveStreamSecurityCallback createSecurityCallback(UserCourseEnvironment userCourseEnv,
 			ModuleConfiguration config) {
 		boolean canViewStreams = true;
+		boolean canViewStatistic = userCourseEnv.isAdmin() || userCourseEnv.isCoach();
 		boolean canEditStreams = 
 				userCourseEnv.isAdmin() 
 				|| (userCourseEnv.isCoach() && config.getBooleanSafe(LiveStreamCourseNode.CONFIG_COACH_CAN_EDIT));
-		return createSecurityCallback(canViewStreams, canEditStreams);
+		return createSecurityCallback(canViewStreams, canViewStatistic, canEditStreams);
 	}
 
-	public static LiveStreamSecurityCallback createSecurityCallback(boolean canViewStreams, boolean canEditStreams) {
+	public static LiveStreamSecurityCallback createSecurityCallback(boolean canViewStreams, boolean canViewStatistic,
+			boolean canEditStreams) {
 		LiveStreamSecurityCallbackImpl secCallback = new LiveStreamSecurityCallbackImpl();
 		secCallback.setCanViewStreams(canViewStreams);
+		secCallback.setCanViewStatistic(canViewStatistic);
 		secCallback.setCanEditStreams(canEditStreams);
 		return secCallback;
 	}
@@ -50,6 +53,7 @@ public class LiveStreamSecurityCallbackFactory {
 	private static class LiveStreamSecurityCallbackImpl implements LiveStreamSecurityCallback {
 		
 		private boolean canViewStreams;
+		private boolean canViewStatistic;
 		private boolean canEditStreams;
 
 		@Override
@@ -61,6 +65,15 @@ public class LiveStreamSecurityCallbackFactory {
 			this.canViewStreams = canViewStreams;
 		}
 		
+		@Override
+		public boolean canViewStatistic() {
+			return canViewStatistic;
+		}
+
+		private void setCanViewStatistic(boolean canViewStatistic) {
+			this.canViewStatistic = canViewStatistic;
+		}
+
 		@Override
 		public boolean canEditStreams() {
 			return canEditStreams;
diff --git a/src/main/java/org/olat/course/nodes/livestream/LiveStreamService.java b/src/main/java/org/olat/course/nodes/livestream/LiveStreamService.java
index e642a0eb71f691a395e37d7c07959eb56fd23eaa..6a534b4ea1bd7f3db37ac1ff25d9efcbdab073db 100644
--- a/src/main/java/org/olat/course/nodes/livestream/LiveStreamService.java
+++ b/src/main/java/org/olat/course/nodes/livestream/LiveStreamService.java
@@ -19,6 +19,7 @@
  */
 package org.olat.course.nodes.livestream;
 
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -36,7 +37,20 @@ public interface LiveStreamService {
 	
 	List<? extends LiveStreamEvent> getRunningEvents(CourseCalendars calendars, int bufferBeforeMin,
 			int bufferAfterMin);
+	
+	List<? extends LiveStreamEvent> getRunningAndPastEvents(CourseCalendars calendars, int bufferBeforeMin);
 
 	List<? extends LiveStreamEvent> getUpcomingEvents(CourseCalendars calendars, int bufferBeforeMin);
+	
+	/**
+	 * Get the number of unique viewers of the live stream event.
+	 * 
+	 * @param courseResId
+	 * @param courseNodeIdent
+	 * @param from
+	 * @param to
+	 * @return
+	 */
+	Long getViewers(String courseResId, String courseNodeIdent, Date from, Date to);
 
 }
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
index 5b7a52b92f5d4a1ea2b5aab3f4867366e4557bca..6dde2be5ca42f56d26c6b69f1b4e04f51e71e488 100644
--- a/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamServiceImpl.java
+++ b/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamServiceImpl.java
@@ -22,6 +22,7 @@ package org.olat.course.nodes.livestream.manager;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -54,6 +55,8 @@ public class LiveStreamServiceImpl implements LiveStreamService {
 	
 	@Autowired
 	private CalendarManager calendarManager;
+	@Autowired
+	private LiveStreamStatisticDAO statisticDao;
 
 	@Override
 	public ScheduledExecutorService getScheduler() {
@@ -81,6 +84,20 @@ public class LiveStreamServiceImpl implements LiveStreamService {
 		
 		return getLiveStreamEvents(calendars, from, to);
 	}
+
+	@Override
+	public List<? extends LiveStreamEvent> getRunningAndPastEvents(CourseCalendars calendars, int bufferBeforeMin) {
+		Date now = new Date();
+		
+		Date from = new GregorianCalendar(2000, 1, 1).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) {
@@ -147,4 +164,9 @@ public class LiveStreamServiceImpl implements LiveStreamService {
 		}
 		return liveStreamEvent;
 	}
+
+	@Override
+	public Long getViewers(String courseResId, String nodeIdent, Date from, Date to) {
+		return statisticDao.getViewers(courseResId, nodeIdent, from, to);
+	}
 }
diff --git a/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamStatisticDAO.java b/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamStatisticDAO.java
new file mode 100644
index 0000000000000000000000000000000000000000..52d933eb2f7395ba288531fa899f9fae09809645
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/livestream/manager/LiveStreamStatisticDAO.java
@@ -0,0 +1,62 @@
+/**
+ * <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.Date;
+import java.util.List;
+
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.commons.persistence.QueryBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 
+ * Initial date: 17 Dec 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@Component
+public class LiveStreamStatisticDAO {
+
+	@Autowired
+	private DB dbInstance;
+	
+	public Long getViewers(String courseResId, String nodeIdent, Date from, Date to) {
+		QueryBuilder sb = new QueryBuilder();
+		sb.append("select count(distinct log.userId)");
+		sb.append("  from loggingobject log");
+		sb.and().append("log.actionVerb = 'launch'");
+		sb.and().append("log.targetResType = 'livestream'");
+		sb.and().append("log.targetResId = :targetResId");
+		sb.and().append("log.parentResId = :parentResId");
+		sb.and().append("log.creationDate >= :from");
+		sb.and().append("log.creationDate <= :to");
+		
+		List<Long> counts = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Long.class)
+				.setParameter("targetResId", nodeIdent)
+				.setParameter("parentResId", courseResId)
+				.setParameter("from", from)
+				.setParameter("to", to)
+				.getResultList();
+		return !counts.isEmpty()? counts.get(0): null;
+	}
+}
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventDataModel.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventDataModel.java
index 9fe89373acbd37155d93f57e0ae9a12ee8969dcc..7b4daec2c73188122ca45c28595a1003d6f85200 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventDataModel.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventDataModel.java
@@ -53,6 +53,7 @@ public class LiveStreamEventDataModel extends DefaultFlexiTableDataModel<LiveStr
 			case subject: return row.getEvent().getSubject();
 			case description: return row.getEvent().getDescription();
 			case location: return row.getEvent().getLocation();
+			case viewers: return row.getViewers();
 			default: return null;
 		}
 	}
@@ -67,7 +68,8 @@ public class LiveStreamEventDataModel extends DefaultFlexiTableDataModel<LiveStr
 		begin("table.header.begin"),
 		end("table.header.end"),
 		location("table.header.location"),
-		description("table.header.description");
+		description("table.header.description"),
+		viewers("table.header.viewers");
 		
 		private final String i18nKey;
 		
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventRow.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventRow.java
index 8f293bdc9116c6e45adfb2cf964e440e5b79e996..b874d5587bfe06a0d07dc0a8176d3b209796e8bb 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventRow.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamEventRow.java
@@ -30,6 +30,7 @@ import org.olat.course.nodes.livestream.LiveStreamEvent;
 public class LiveStreamEventRow {
 	
 	private final LiveStreamEvent event;
+	private Long viewers;
 
 	public LiveStreamEventRow(LiveStreamEvent event) {
 		this.event = event;
@@ -39,4 +40,12 @@ public class LiveStreamEventRow {
 		return event;
 	}
 
+	public Long getViewers() {
+		return viewers;
+	}
+
+	public void setViewers(Long viewers) {
+		this.viewers = viewers;
+	}
+
 }
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamRunController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamRunController.java
index 50c5d5c50ee74340e13cc4acf88186443316bfcd..7c9e09b0d303bb06901ec67596d37d057f2790e8 100644
--- a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamRunController.java
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamRunController.java
@@ -32,6 +32,7 @@ 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.resource.OresHelper;
+import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.cal.CourseCalendars;
 import org.olat.course.nodes.livestream.LiveStreamSecurityCallback;
 import org.olat.modules.ModuleConfiguration;
@@ -46,24 +47,29 @@ import org.olat.resource.OLATResource;
 public class LiveStreamRunController extends BasicController {
 	
 	private static final String PLAY_RES_TYPE = "streams";
+	private static final String STATISTIC_RES_TYPE = "statistic";
 	private static final String EDIT_RES_TYPE = "edit";
 	
 	private VelocityContainer mainVC;
 	private SegmentViewComponent segmentView;
 	private Link streamsLink;
+	private Link statisticLink;
 	private Link editLink;
 	
 	private LiveStreamsController streamsCtrl;
+	private LiveStreamStatisticController statisticCtrl;
 	private WeeklyCalendarController editCtrl;
 	
 	private final ModuleConfiguration moduleConfiguration;
+	private final String courseNodeIdent;
 	private final OLATResource courseOres;
 	private final CourseCalendars calendars;
 
-	public LiveStreamRunController(UserRequest ureq, WindowControl wControl, ModuleConfiguration moduleConfiguration,
+	public LiveStreamRunController(UserRequest ureq, WindowControl wControl, CourseNode coureNode,
 			OLATResource courseOres, LiveStreamSecurityCallback secCallback, CourseCalendars calendars) {
 		super(ureq, wControl);
-		this.moduleConfiguration = moduleConfiguration;
+		this.moduleConfiguration = coureNode.getModuleConfiguration();
+		this.courseNodeIdent = coureNode.getIdent();
 		this.courseOres = courseOres;
 		this.calendars = calendars;
 		
@@ -74,6 +80,10 @@ public class LiveStreamRunController extends BasicController {
 			streamsLink = LinkFactory.createLink("run.streams", mainVC, this);
 			segmentView.addSegment(streamsLink, true);
 		}
+		if (secCallback.canViewStatistic()) {
+			statisticLink = LinkFactory.createLink("run.statistic", mainVC, this);
+			segmentView.addSegment(statisticLink, true);
+		}
 		if (secCallback.canEditStreams()) {
 			editLink = LinkFactory.createLink("run.edit.events", mainVC, this);
 			segmentView.addSegment(editLink, false);
@@ -95,6 +105,8 @@ public class LiveStreamRunController extends BasicController {
 				Component clickedLink = mainVC.getComponent(segmentCName);
 				if (clickedLink == streamsLink) {
 					doOpenStreams(ureq);
+				} else if (clickedLink == statisticLink){
+					doOpenStatistic(ureq);
 				} else if (clickedLink == editLink){
 					doOpenEdit(ureq);
 				}
@@ -115,6 +127,20 @@ public class LiveStreamRunController extends BasicController {
 		mainVC.put("segmentCmp", streamsCtrl.getInitialComponent());
 	}
 	
+	private void doOpenStatistic(UserRequest ureq) {
+		if (statisticCtrl == null) {
+			WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType(STATISTIC_RES_TYPE), null);
+			statisticCtrl = new LiveStreamStatisticController(ureq, swControl, courseOres, courseNodeIdent,
+					moduleConfiguration, calendars);
+			listenTo(statisticCtrl);
+		} else {
+			statisticCtrl.refreshData();
+			addToHistory(ureq, statisticCtrl);
+		}
+		segmentView.select(statisticLink);
+		mainVC.put("segmentCmp", statisticCtrl.getInitialComponent());
+	}
+	
 	private void doOpenEdit(UserRequest ureq) {
 		if (editCtrl == null) {
 			WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType(EDIT_RES_TYPE), null);
diff --git a/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamStatisticController.java b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamStatisticController.java
new file mode 100644
index 0000000000000000000000000000000000000000..86b4262278968108c4ff8d386af28e0f7f508b1f
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/livestream/ui/LiveStreamStatisticController.java
@@ -0,0 +1,124 @@
+/**
+ * <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.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+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.LiveStreamService;
+import org.olat.course.nodes.livestream.ui.LiveStreamEventDataModel.EventCols;
+import org.olat.modules.ModuleConfiguration;
+import org.olat.resource.OLATResource;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 17 Dec 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class LiveStreamStatisticController extends FormBasicController {
+
+	private FlexiTableElement tableEl;
+	private LiveStreamEventDataModel dataModel;
+	
+	private String courseResId;
+	private String courseNodeIdent;
+	private final CourseCalendars calendars;
+	private final int bufferBeforeMin;
+	
+	@Autowired
+	private LiveStreamService liveStreamService;
+
+	public LiveStreamStatisticController(UserRequest ureq, WindowControl wControl, OLATResource courseOres,
+			String courseNodeIdent, ModuleConfiguration moduleConfiguration, CourseCalendars calendars) {
+		super(ureq, wControl, LAYOUT_VERTICAL);
+		this.courseResId = courseOres.getResourceableId().toString();
+		this.courseNodeIdent = courseNodeIdent;
+		this.calendars = calendars;
+		
+		bufferBeforeMin = moduleConfiguration.getIntegerSafe(LiveStreamCourseNode.CONFIG_BUFFER_BEFORE_MIN, 0);
+		
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		setFormTitle("statistic.title");
+		
+		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(EventCols.subject));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(EventCols.begin));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(EventCols.end));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(EventCols.viewers));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(EventCols.location));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(EventCols.description));
+		
+		dataModel = new LiveStreamEventDataModel(columnsModel, getLocale());
+		tableEl = uifactory.addTableElement(getWindowControl(), "table", dataModel, 20, false, getTranslator(), formLayout);
+		tableEl.setAndLoadPersistedPreferences(ureq, "livestream-statistic");
+		tableEl.setEmtpyTableMessageKey("statistic.table.empty");
+		loadModel();
+	}
+	
+	void refreshData() {
+		loadModel();
+	}
+
+	private void loadModel() {
+		List<? extends LiveStreamEvent> upcomingEvents = liveStreamService.getRunningAndPastEvents(calendars,
+				bufferBeforeMin);
+		List<LiveStreamEventRow> rows = new ArrayList<>(upcomingEvents.size());
+		for (LiveStreamEvent liveStreamEvent : upcomingEvents) {
+			LiveStreamEventRow row = new LiveStreamEventRow(liveStreamEvent);
+			Long viewers = liveStreamService.getViewers(courseResId, courseNodeIdent, liveStreamEvent.getBegin(),
+					liveStreamEvent.getEnd());
+			row.setViewers(viewers);
+			rows.add(row);
+		}
+		Collections.sort(rows, (e1, e2) -> e1.getEvent().getBegin().compareTo(e2.getEvent().getBegin()));
+		dataModel.setObjects(rows);
+		tableEl.reset(false, false, true);
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+}
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 a63505df2ee05616236168c449d799fc3e979f82..bc2a803cfa8f8322d54f38d4b214a9e639dbe1a9 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
@@ -30,12 +30,16 @@ player.profile.both=Beide Streams anzeigen
 player.profile.stream1=Stream 1 anzeigen
 player.profile.stream2=Stream 2 anzeigen
 run.edit.events=Termine bearbeiten
+run.statistic=Statistik
 run.streams=Live Streams
+statistic.table.empty=Es wurden noch keine Livestreams ausgestrahlt.
+statistic.title=Ausgestrahle Livestreams
 table.empty=Es sind keine Livestreams anstehend.
 table.header.begin=$org.olat.commons.calendar\:cal.form.begin
 table.header.description=$org.olat.commons.calendar\:cal.form.description
 table.header.end=$org.olat.commons.calendar\:cal.form.end
 table.header.location=$org.olat.commons.calendar\:cal.form.location
 table.header.subject=$org.olat.commons.calendar\:cal.form.subject
+table.header.viewers=Zuschauer
 viewer.error.browser=Der Livestream kann in diesem Browser nicht angezeigt werden. Bitte verwenden Sie einen anderen Browser.
 viewer.no.stream=Aktuell wird kein Livestream ausgestrahlt.
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 dcccc5ff9fa344a5022005fcb2171e02a8cca979..a4e187294fb0f37b8552a6c62e5ab17e602de562 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
@@ -30,12 +30,16 @@ player.profile.both=Show both streams
 player.profile.stream1=Show stream 1
 player.profile.stream2=Show stream 2
 run.edit.events=Edit events
+run.statistic=Statistic
 run.streams=Livestreams
+statistic.table.empty=No live streams have been broadcast yet.
+statistic.title=Broadcast live streams
 table.empty=No upcoming live streams are available.
 table.header.begin=$org.olat.commons.calendar\:cal.form.begin
 table.header.description=$org.olat.commons.calendar\:cal.form.description
 table.header.end=$org.olat.commons.calendar\:cal.form.end
 table.header.location=$org.olat.commons.calendar\:cal.form.location
 table.header.subject=$org.olat.commons.calendar\:cal.form.subject
+table.header.viewers=Viewers
 viewer.error.browser=The livestream cannot be displayed in this browser. Please use a different browser.
 viewer.no.stream=Currently no live stream is broadcasted.
diff --git a/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql b/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql
index 5c46c36430a22890ae2bfd05a046f79497690818..caca9df4e8a7fa131724139cce39c41dc90b5bc4 100644
--- a/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql
+++ b/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql
@@ -15,4 +15,7 @@ create table o_gta_task_revision (
 alter table o_gta_task_revision add constraint task_rev_to_task_idx foreign key (fk_task) references o_gta_task (id);
 create index idx_task_rev_to_task_idx on o_gta_task_revision (fk_task);
 alter table o_gta_task_revision add constraint task_rev_to_ident_idx foreign key (fk_comment_author) references o_bs_identity (id);
-create index idx_task_rev_to_ident_idx on o_gta_task_revision (fk_comment_author);
\ No newline at end of file
+create index idx_task_rev_to_ident_idx on o_gta_task_revision (fk_comment_author);
+
+-- livestream
+create index idx_log_livestream_idx on o_loggingtable(targetresid, creationdate, parentresid, user_id) where actionverb = 'launch' and targetrestype = 'livestream';
diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql
index 82085e77bcd7c51e6c1f487ed0349ce0e733ec03..89ef00db7126f57b7b11c0069e38fa0445c2740b 100644
--- a/src/main/resources/database/postgresql/setupDatabase.sql
+++ b/src/main/resources/database/postgresql/setupDatabase.sql
@@ -4104,6 +4104,8 @@ create index log_ptarget_resid_idx on o_loggingtable(parentresid);
 create index log_gptarget_resid_idx on o_loggingtable(grandparentresid);
 create index log_ggptarget_resid_idx on o_loggingtable(greatgrandparentresid);
 create index log_creationdate_idx on o_loggingtable(creationdate);
+create index idx_log_livestream_idx on o_loggingtable(targetresid, creationdate, parentresid, user_id) where actionverb = 'launch' and targetrestype = 'livestream';
+
 
 
 insert into hibernate_unique_key values ( 0 );
diff --git a/src/test/java/org/olat/course/nodes/livestream/manager/LiveStreamStatisticDAOTest.java b/src/test/java/org/olat/course/nodes/livestream/manager/LiveStreamStatisticDAOTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce47808ec6d166fdbe8d69be77b26e5096a08640
--- /dev/null
+++ b/src/test/java/org/olat/course/nodes/livestream/manager/LiveStreamStatisticDAOTest.java
@@ -0,0 +1,89 @@
+/**
+ * <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 static org.assertj.core.api.Assertions.assertThat;
+import static org.olat.test.JunitTestHelper.random;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.junit.Test;
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.logging.activity.LoggingObject;
+import org.olat.test.OlatTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 17 Dec 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class LiveStreamStatisticDAOTest extends OlatTestCase {
+	
+	@Autowired
+	private LiveStreamStatisticDAO sut;
+	@Autowired
+	private DB dbInstance;
+	
+	@Test
+	public void shouldGetViewers() {
+		Long userKey1 = 132L;
+		Long userKey2 = 1324L;
+		Long userKeyOther = 13245L;
+		String courseResId = "courseResId";
+		String nodeIdent = "nodeIdent";
+		Date before = new GregorianCalendar(2010, 2, 8).getTime();
+		Date from = new GregorianCalendar(2010, 2, 9).getTime();
+		Date inside = new GregorianCalendar(2010, 2, 10).getTime();
+		Date to = new GregorianCalendar(2010, 2, 11).getTime();
+		Date after = new GregorianCalendar(2010, 2, 12).getTime();
+		createLoggingObject("launch", courseResId, "livestream", nodeIdent, userKey1, inside);
+		createLoggingObject("launch", courseResId, "livestream", nodeIdent, userKey1, inside);
+		createLoggingObject("launch", courseResId, "livestream", nodeIdent, userKey1, inside);
+		createLoggingObject("launch", courseResId, "livestream", nodeIdent, userKey2, inside);
+		// These log entries should have all wrong parameters. So userKeyOther should not be a viewer.
+		createLoggingObject("OTHER", courseResId, "livestream", nodeIdent, userKeyOther, inside);
+		createLoggingObject("launch", "OTHER", "livestream", nodeIdent, userKeyOther, inside);
+		createLoggingObject("launch", courseResId, "OTHER", nodeIdent, userKeyOther, inside);
+		createLoggingObject("launch", courseResId, "livestream", "OTHER", userKeyOther, inside);
+		createLoggingObject("launch", courseResId, "livestream", nodeIdent, userKeyOther, before);
+		createLoggingObject("launch", courseResId, "livestream", nodeIdent, userKeyOther, after);
+		dbInstance.commitAndCloseSession();
+		
+		Long viewers = sut.getViewers(courseResId, nodeIdent, from, to);
+		
+		assertThat(viewers).isEqualTo(2);
+	}
+
+	private void createLoggingObject(String actionVerb, String parentResId, String targetResType, String targetResId,
+			Long identityKey, Date creationDate) {
+		LoggingObject logObj = new LoggingObject(random(), identityKey, "r", actionVerb, "node");
+		logObj.setCreationDate(creationDate);
+		logObj.setParentResId(parentResId);
+		logObj.setTargetResType(targetResType);
+		logObj.setTargetResId(targetResId);
+		logObj.setResourceAdminAction(Boolean.TRUE);
+		dbInstance.saveObject(logObj);
+	}
+
+
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index e36fe09fe70cfc8027d7d6a003dedc909108e4b0..568b8972e06009dcfc13ea1f09b7bae5ddd4f791 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -179,6 +179,7 @@ import org.junit.runners.Suite;
 	org.olat.course.nodes.gta.manager.GTATaskRevisionDAOTest.class,
 	org.olat.course.nodes.gta.manager.GTAIdentityMarkDAOTest.class,
 	org.olat.course.nodes.gta.rule.GTAReminderRuleTest.class,
+	org.olat.course.nodes.livestream.manager.LiveStreamStatisticDAOTest.class,
 	org.olat.course.nodes.pf.manager.PFManagerTest.class,
 	org.olat.course.assessment.AssessmentManagerTest.class,
 	org.olat.course.assessment.manager.UserCourseInformationsManagerTest.class,