diff --git a/encoding.py b/encoding.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a233f6731b70f143e6f9b21718d937e675d4254
--- /dev/null
+++ b/encoding.py
@@ -0,0 +1,31 @@
+from server import *
+
+@job_handler('probe', 'probe-raw')
+def import_xmp_chapters(jobid, jobtype, data, state, status):
+	if 'lecture_id' not in data and data.get('import-chapters', False):
+		return
+	times = set()
+	# Only add new chapters, deleted chapters are taken into account here
+	for chapter in query('SELECT * FROM chapters WHERE lecture_id = ?', data['lecture_id']):
+		for offset in range(5):
+			times.add(chapter['time']-offset)
+			times.add(chapter['time']+offset)
+	for chapter in status.get('xmp_chapters', []):
+		if int(chapter['time']) in times:
+			continue
+		modify('INSERT INTO chapters (lecture_id, time, text, visible, time_created, time_updated) VALUES (?, ?, ?, 0, ?, ?)',
+				data['lecture_id'], int(chapter['time']), chapter['text'],
+				datetime.now(), datetime.now())
+
+@job_handler('probe', 'remux', 'transcode')
+def update_video_metadata(jobid, jobtype, data, state, status):
+	if 'video_id' not in data:
+		return
+	if jobtype not in ['remux', 'transcode']:
+		video = query('SELECT * FROM videos WHERE id = ?', data['video_id'])[0]
+		if video['hash'] and video['hash'] != status['hash']:
+			print('Hash mismatch for video', data['video_id'])
+			return
+	modify('UPDATE videos_data SET hash = ?, file_size = ? WHERE id = ?',
+			status['hash'], status['filesize'], data['video_id'])
+
diff --git a/server.py b/server.py
index e3f0acc17b3371b6040be5c8273cc9a742579b17..787442abad40226973f8b77d4b0ac96807aed5ff 100644
--- a/server.py
+++ b/server.py
@@ -470,6 +470,7 @@ if 'ICAL_URL' in config:
 	import meetings
 import l2pauth
 from jobs import job_handler, schedule_job
+import encoding
 import timetable
 import chapters
 import icalexport
diff --git a/sorter.py b/sorter.py
index c880ababdb2db21d260c610bd110ce80441d8ac1..88ea9f4ba1e735a8a07876f675f59dc7bb3c810c 100644
--- a/sorter.py
+++ b/sorter.py
@@ -34,6 +34,7 @@ def insert_video(lectureid,dbfilepath,filepath,fileformatid):
 		lectureid, dbfilepath, fileformatid, datetime.now(), datetime.now(), datetime.now(), -1, os.stat(filepath).st_size)
 	query('INSERT INTO sortlog (lecture_id,video_id,path,`when`) VALUES (?,?,?,?)', lectureid, video_id, dbfilepath, datetime.now())
 	schedule_thumbnail(lectureid)
+	schedule_job('probe', {'path': dbfilepath, 'lecture_id': lectureid, 'import-chapters': True})
 
 def schedule_thumbnail(lectureid, filePath=None):
 	videos = query('''