diff --git a/server.py b/server.py
index 9edddf0ac8134e14e156fee238273177999050b5..718633bc7d1f3ce368eb440bbe0989a7d6d5458d 100644
--- a/server.py
+++ b/server.py
@@ -396,6 +396,16 @@ def suggest_chapter(lectureid):
 		return redirect(request.values['ref'])
 	return 'OK',  200
 
+@app.route('/chapters/<int:lectureid>')
+def chapters(lectureid):
+	chapters = query("SELECT * FROM chapters WHERE lecture_id = ? and visible ORDER BY time DESC", lectureid)
+	last = None
+	for c in chapters:
+		c['start'] = c['time']
+		c['end'] = last['start'] if last else 9999
+		last = c
+	return Response(render_template('chapters.srt',chapters=chapters), 200, {'Content-Type':'text/vtt'})
+
 @app.route('/sitemap.xml')
 def sitemap():
 	pages=[]
diff --git a/templates/chapters.srt b/templates/chapters.srt
new file mode 100644
index 0000000000000000000000000000000000000000..bfb463281ac0903e02ca7a0f899031bd89dfa44b
--- /dev/null
+++ b/templates/chapters.srt
@@ -0,0 +1,11 @@
+{% macro vtttime(time) %}{{ '%02d:%02d:%02d.000'|format( time//3600, (time//60)%60, time%60) }}{% endmacro %}
+WEBVTT
+
+
+{% for c in chapters|sort(attribute='start') %}
+{{ loop.index }}
+{# time format is 'minutes:seconds.ms' we expect full seconds #}
+{{ vtttime(c['start']) }} --> {{ vtttime(c['end']) }}
+{{ c['text'] }}
+
+{% endfor %}
diff --git a/templates/macros.html b/templates/macros.html
index 38aca6b73d868bc645e6fdf34842b5ed18dbc3e9..35e5291e786b9073d932aeed8a2ba9417b4c2ae2 100644
--- a/templates/macros.html
+++ b/templates/macros.html
@@ -49,6 +49,7 @@
 	{% for v in videos|sort(attribute='player_prio', reverse=True) %}
 		<source type="video/mp4" src="{{ config.VIDEOPREFIX }}/{{ v.path }}" title="{{ v.format_description }}"/>
 	{% endfor %}
+	<track srclang="en" kind="chapters" src="{{ url_for('chapters',lectureid=lecture.id) }}" />
 </video>
 <script>
 		$(function($)