diff --git a/api/api_specification.json b/api/api_specification.json
index 5dd606c02d7c1a9c883648d909661f4ae9ec3abd..5790d4b0d46d09990889a6f4cb3d9b49af25a2f3 100644
--- a/api/api_specification.json
+++ b/api/api_specification.json
@@ -1078,6 +1078,15 @@
         "": {
           "fields": {
             "": {
+              "is_automatic_media_process_scheduler_enabled": {
+                "config_directly_modifiable": false,
+                "id": "is_automatic_media_process_scheduler_enabled",
+                "notes": "",
+                "object_variant": null,
+                "only_mod": false,
+                "optional": false,
+                "type": "boolean"
+              },
               "job_context": {
                 "config_directly_modifiable": false,
                 "id": "job_context",
@@ -1114,6 +1123,15 @@
                 "optional": false,
                 "type": "media_process"
               },
+              "process_sha256": {
+                "config_directly_modifiable": false,
+                "id": "process_sha256",
+                "notes": "SHA256 of the current process for this lecture",
+                "object_variant": null,
+                "only_mod": false,
+                "optional": false,
+                "type": "string"
+              },
               "publish_media": {
                 "config_directly_modifiable": false,
                 "id": "publish_media",
@@ -1168,10 +1186,19 @@
         "": {
           "fields": {
             "": {
-              "scheduled": {
+              "job_id": {
                 "config_directly_modifiable": false,
-                "id": "scheduled",
-                "notes": "If false, another scheduler is probably still queued/running",
+                "id": "job_id",
+                "notes": "The id of an already running scheduler job or the newly scheduled job",
+                "object_variant": null,
+                "only_mod": false,
+                "optional": false,
+                "type": "int"
+              },
+              "scheduled_new": {
+                "config_directly_modifiable": false,
+                "id": "scheduled_new",
+                "notes": "If false, the scheduler job already existed",
                 "object_variant": null,
                 "only_mod": false,
                 "optional": false,
@@ -2927,6 +2954,15 @@
             "optional": false,
             "type": "string"
           },
+          "crf": {
+            "config_directly_modifiable": false,
+            "id": "crf",
+            "notes": "",
+            "object_variant": null,
+            "only_mod": false,
+            "optional": true,
+            "type": "int"
+          },
           "framerate": {
             "config_directly_modifiable": false,
             "id": "framerate",
@@ -3490,6 +3526,15 @@
           }
         },
         "rescale_video": {
+          "crf": {
+            "config_directly_modifiable": false,
+            "id": "crf",
+            "notes": "",
+            "object_variant": "rescale_video",
+            "only_mod": false,
+            "optional": true,
+            "type": "int"
+          },
           "input_id": {
             "config_directly_modifiable": false,
             "id": "input_id",
diff --git a/api/api_specification.md b/api/api_specification.md
index f6433b828c84bab383d988df9d4c945d156d2834..28e8aeb5d1d82b95ecbb4530e32f834644fb0877 100644
--- a/api/api_specification.md
+++ b/api/api_specification.md
@@ -866,6 +866,11 @@ This may only be used by a moderator.
     <th>Notes</th>
 </thead>
 <tbody>
+    <tr>
+        <td>is_automatic_media_process_scheduler_enabled</td>
+        <td>boolean</td>
+        <td></td>
+    </tr>
     <tr>
         <td>job_context</td>
         <td>job{}</td>
@@ -886,6 +891,11 @@ This may only be used by a moderator.
         <td>media_process</td>
         <td>The current process for this lecture</td>
     </tr>
+    <tr>
+        <td>process_sha256</td>
+        <td>string</td>
+        <td>SHA256 of the current process for this lecture</td>
+    </tr>
     <tr>
         <td>publish_media</td>
         <td>publish_medium{}</td>
@@ -923,9 +933,14 @@ This may only be used by a moderator and requires the CSRF Token.
 </thead>
 <tbody>
     <tr>
-        <td>scheduled</td>
+        <td>job_id</td>
+        <td>int</td>
+        <td>The id of an already running scheduler job or the newly scheduled job</td>
+    </tr>
+    <tr>
+        <td>scheduled_new</td>
         <td>boolean</td>
-        <td>If false, another scheduler is probably still queued/running</td>
+        <td>If false, the scheduler job already existed</td>
     </tr>
 </tbody>
 </table>
@@ -2172,6 +2187,11 @@ Additionally, the following objects may appear as the type of some field:
         <td>string</td>
         <td>Possible values: <code>h264</code>, <code>vp9</code>, <code>av1</code>, <code>opus</code>, <code>flac</code>, <code>aac</code></td>
     </tr>
+    <tr>
+        <td>crf</td>
+        <td>?int</td>
+        <td></td>
+    </tr>
     <tr>
         <td>framerate</td>
         <td>?int</td>
@@ -2545,7 +2565,12 @@ Additionally, the following objects may appear as the type of some field:
         <td></td>
     </tr>
     <tr>
-        <td rowspan="3"><code>rescale_video</code></td>
+        <td rowspan="4"><code>rescale_video</code></td>
+        <td>crf</td>
+        <td>?int</td>
+        <td></td>
+    </tr>
+    <tr>
         <td>input_id</td>
         <td>string</td>
         <td>Must match <code>[a-zA-Z0-9_]{1,100}</code></td>
@@ -3188,6 +3213,18 @@ Possible `error_code`:
 
 ## Changelog
 
+### v0.83
+
+* Updated `GET /lecture/{lecture_id}/media_process_overview`
+  * Added `is_automatic_media_process_scheduler_enabled` field
+  * Added `process_sha256` field
+* Updated `POST /lecture/{lecture_id}/run_media_process_scheduler`
+  * Changed response to same format as run_source_file_sorter
+* Updated `ffmpeg_filter_graph_output_stream`
+  * Added `crf` field
+* Updated `media_process_target_producer`
+  * Added `crf` field for type `rescale_video`
+
 ### v0.82
 
 * Changed `publish_medium`
diff --git a/api/api_specification_template.md b/api/api_specification_template.md
index 03f847cae26fd486c562576fb1daf96f6772a0c4..36b13efed48bba55f952d2c0f709a09929505920 100644
--- a/api/api_specification_template.md
+++ b/api/api_specification_template.md
@@ -139,6 +139,18 @@ Possible `error_code`:
 
 ## Changelog
 
+### v0.83
+
+* Updated `GET /lecture/{lecture_id}/media_process_overview`
+  * Added `is_automatic_media_process_scheduler_enabled` field
+  * Added `process_sha256` field
+* Updated `POST /lecture/{lecture_id}/run_media_process_scheduler`
+  * Changed response to same format as run_source_file_sorter
+* Updated `ffmpeg_filter_graph_output_stream`
+  * Added `crf` field
+* Updated `media_process_target_producer`
+  * Added `crf` field for type `rescale_video`
+
 ### v0.82
 
 * Changed `publish_medium`
diff --git a/api/config/db_test_data.sql b/api/config/db_test_data.sql
index 06f4b8a27f1c5b7919edad4dc43ceac6c0a062d9..c3c942cd766565fd786a0546f3b5cb5d4c3f468d 100644
--- a/api/config/db_test_data.sql
+++ b/api/config/db_test_data.sql
@@ -33,28 +33,28 @@ INSERT INTO "user" (id,handle,display_name,full_name,email,last_login,enable_mai
 SELECT setval('user_id_seq', 1000);
 
 
-INSERT INTO course (id,handle,full_name,short_name,semester,organizer,topic,description,show_chapters_on_course,authentication_information,listed,internal_comment,allow_download,allow_embed,media_process,disable_automatic_media_process_scheduler,deleted,visible,view_perm_type,view_perm_rwth_auth,view_perm_fsmpi_auth,view_perm_moodle_course_ids,view_perm_passwords) VALUES
-     (2,'07ws-buk','Berechenbarkeit und Komplexität','BuK','2007ws','Prof. Vöcking','Informatik','Seite zur Veranstaltung...',false,'',true,'',true,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}',true,false,true,'authentication'::view_permissions_type,true,true,'{}','{}'),
-     (3,'07ws-diskrete','Diskrete Strukturen','Diskrete','2007ws','Prof. Hiß','Informatik','Von dieser Vorlesungsreihe fehlen die ersten zwei Monate. Wenn wir die Gelegenheit bekommen, filmen wir gerne nochmal.',false,'',true,'',true,false,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}',true,false,true,'private'::view_permissions_type,false,false,'{}','{}'),
-     (13,'09ss-fosap','Formale Systeme, Automaten, Prozesse','FoSAP','2009ss','Prof. Rossmanith','Informatik','Seite des Lehrstuhls ...',false,'',true,'',true,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}',true,false,false,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (62,'11ws-infin','Investition und Finanzierung','InFin','2011ws','Prof. Breuer','BWL','Seite im Campus ...',false,'',false,'',false,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}',true,false,true,'authentication'::view_permissions_type,false,false,'{1}','{}'),
-     (1,'del','Something deleted','S','2007ws','','','Seite zur Veranstaltung...',false,'',true,'',true,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}',true,true,true,'inherit'::view_permissions_type,false,false,'{}','{}');
+INSERT INTO course (id,handle,full_name,short_name,semester,organizer,topic,description,show_chapters_on_course,authentication_information,listed,internal_comment,allow_download,allow_embed,media_process,automatic_media_process_scheduler_state,deleted,visible,view_perm_type,view_perm_rwth_auth,view_perm_fsmpi_auth,view_perm_moodle_course_ids,view_perm_passwords) VALUES
+     (2,'07ws-buk','Berechenbarkeit und Komplexität','BuK','2007ws','Prof. Vöcking','Informatik','Seite zur Veranstaltung...',false,'',true,'',true,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}','inherit'::automatic_media_process_scheduler_state,false,true,'authentication'::view_permissions_type,true,true,'{}','{}'),
+     (3,'07ws-diskrete','Diskrete Strukturen','Diskrete','2007ws','Prof. Hiß','Informatik','Von dieser Vorlesungsreihe fehlen die ersten zwei Monate. Wenn wir die Gelegenheit bekommen, filmen wir gerne nochmal.',false,'',true,'',true,false,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}','inherit'::automatic_media_process_scheduler_state,false,true,'private'::view_permissions_type,false,false,'{}','{}'),
+     (13,'09ss-fosap','Formale Systeme, Automaten, Prozesse','FoSAP','2009ss','Prof. Rossmanith','Informatik','Seite des Lehrstuhls ...',false,'',true,'',true,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}','inherit'::automatic_media_process_scheduler_state,false,false,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (62,'11ws-infin','Investition und Finanzierung','InFin','2011ws','Prof. Breuer','BWL','Seite im Campus ...',false,'',false,'',false,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}','inherit'::automatic_media_process_scheduler_state,false,true,'authentication'::view_permissions_type,false,false,'{1}','{}'),
+     (1,'del','Something deleted','S','2007ws','','','Seite zur Veranstaltung...',false,'',true,'',true,true,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video"}, {"type" : "sample_thumbnail", "input_id" : "video", "timestamp_percent" : 20, "output_id" : "thumbnail"}], "publish_target_ids" : ["video", "thumbnail"], "publish_wait_for_full_process" : true}','inherit'::automatic_media_process_scheduler_state,true,true,'inherit'::view_permissions_type,false,false,'{}','{}');
 SELECT setval('course_id_seq', 1000);
 
 
-INSERT INTO lecture (id,course_id,title,speaker,"location","time",duration,description,no_recording,livestream_planned,internal_comment,publish_time,media_duration_sec,media_process,disable_automatic_media_process_scheduler,current_media_process_error,deleted,visible,view_perm_type,view_perm_rwth_auth,view_perm_fsmpi_auth,view_perm_moodle_course_ids,view_perm_passwords) VALUES
-     (1,2,'Einführung zur Berechenbarkeit','','','2007-10-19 12:00:00',0,'',false,false,'',NULL,NULL,NULL,false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (2,2,'Einführung zur Berechenbarkeit','','','2007-10-23 08:30:00',0,'',false,false,'',NULL,NULL,NULL,false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (26,3,'Hamiltonkreis, Eulertour, Eulerweg','','','2007-12-18 13:30:00',0,'',false,false,'',NULL,NULL,NULL,false,NULL,false,false,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (29,3,'Modulare Arithmetik: Gruppe, Ring, Körper, abelsche Gruppe, Untergruppe, Einheitengruppe. Restklassenringe, Primzahl.','','','2008-01-17 08:15:00',0,'',false,false,'',NULL,NULL,NULL,false,NULL,false,true,'authentication'::view_permissions_type,false,false,'{}','{"t": "t"}'),
-     (185,13,'Organisatorisches, Motivation, Künstliche Pflanzen, Alphabete, Wörter, Sprachen','','','2009-04-16 10:00:00',90,'Sorry für den schlechten Ton',false,false,'',NULL,NULL,NULL,false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (187,13,'Reguläre Ausdrücke, Endliche Automaten','','','2009-04-23 10:00:00',90,'',false,false,'',NULL,NULL,NULL,false,NULL,true,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (1187,62,'','','Aula','2011-10-17 18:30:00',90,'noch kein Titel',false,false,'',NULL,NULL,NULL,false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (1188,62,'','','Aula','2050-10-24 18:30:00',90,'noch kein Titel',false,false,'',NULL,NULL,NULL,false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (3,2,'Einführung zur Berechenbarkeit','','','2007-10-26 12:00:00',0,'',false,false,'',NULL,5243,NULL,false,NULL,false,true,'public'::view_permissions_type,false,false,'{}','{}'),
-     (25,3,'Graphentheorie: Grundbegriffe, Datenstrukturen, Algorithmus für Breitensuche','','','2007-12-11 13:30:00',0,'',false,false,'','2007-12-12 19:12:04',5420,NULL,false,NULL,false,true,'public'::view_permissions_type,false,false,'{}','{}'),
-     (1186,62,'Einführung, I. Grundlagen','','Aula','2011-10-10 18:30:00',90,'',false,false,'','2011-10-17 14:33:45',5001,NULL,false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
-     (186,13,'Alphabete, Wörter, Sprachen, Reguläre Ausdrücke','','','2009-04-21 08:15:00',45,'',false,false,'','2009-05-18 03:13:20',5431,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video_1080"}, {"type" : "sample_thumbnail", "input_id" : "video_1080", "timestamp_percent" : 20, "output_id" : "thumbnail"}, {"type": "rescale_video", "input_id": "video_1080", "target_vertical_resolution": 720, "output_id": "video_720"}, {"type": "downscale_video", "input_id": "video_480", "target_vertical_resolution": 480, "output_id": "video_480"}], "publish_target_ids" : ["video_1080", "video_720", "video_480", "thumbnail"], "publish_wait_for_full_process" : true}',false,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}');
+INSERT INTO lecture (id,course_id,title,speaker,"location","time",duration,description,no_recording,livestream_planned,internal_comment,publish_time,media_duration_sec,media_process,automatic_media_process_scheduler_state,current_media_process_error,deleted,visible,view_perm_type,view_perm_rwth_auth,view_perm_fsmpi_auth,view_perm_moodle_course_ids,view_perm_passwords) VALUES
+     (1,2,'Einführung zur Berechenbarkeit','','','2007-10-19 12:00:00',0,'',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (2,2,'Einführung zur Berechenbarkeit','','','2007-10-23 08:30:00',0,'',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (26,3,'Hamiltonkreis, Eulertour, Eulerweg','','','2007-12-18 13:30:00',0,'',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,false,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (29,3,'Modulare Arithmetik: Gruppe, Ring, Körper, abelsche Gruppe, Untergruppe, Einheitengruppe. Restklassenringe, Primzahl.','','','2008-01-17 08:15:00',0,'',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'authentication'::view_permissions_type,false,false,'{}','{"t": "t"}'),
+     (185,13,'Organisatorisches, Motivation, Künstliche Pflanzen, Alphabete, Wörter, Sprachen','','','2009-04-16 10:00:00',90,'Sorry für den schlechten Ton',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (187,13,'Reguläre Ausdrücke, Endliche Automaten','','','2009-04-23 10:00:00',90,'',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,true,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (1187,62,'','','Aula','2011-10-17 18:30:00',90,'noch kein Titel',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (1188,62,'','','Aula','2050-10-24 18:30:00',90,'noch kein Titel',false,false,'',NULL,NULL,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (3,2,'Einführung zur Berechenbarkeit','','','2007-10-26 12:00:00',0,'',false,false,'',NULL,5243,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'public'::view_permissions_type,false,false,'{}','{}'),
+     (25,3,'Graphentheorie: Grundbegriffe, Datenstrukturen, Algorithmus für Breitensuche','','','2007-12-11 13:30:00',0,'',false,false,'','2007-12-12 19:12:04',5420,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'public'::view_permissions_type,false,false,'{}','{}'),
+     (1186,62,'Einführung, I. Grundlagen','','Aula','2011-10-10 18:30:00',90,'',false,false,'','2011-10-17 14:33:45',5001,NULL,'inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}'),
+     (186,13,'Alphabete, Wörter, Sprachen, Reguläre Ausdrücke','','','2009-04-21 08:15:00',45,'',false,false,'','2009-05-18 03:13:20',5431,'{"producers" : [{"type" : "source_file", "tag" : "", "output_id" : "video_1080"}, {"type" : "sample_thumbnail", "input_id" : "video_1080", "timestamp_percent" : 20, "output_id" : "thumbnail"}, {"type": "rescale_video", "input_id": "video_1080", "target_vertical_resolution": 720, "output_id": "video_720"}, {"type": "downscale_video", "input_id": "video_480", "target_vertical_resolution": 480, "output_id": "video_480"}], "publish_target_ids" : ["video_1080", "video_720", "video_480", "thumbnail"], "publish_wait_for_full_process" : true}','inherit'::automatic_media_process_scheduler_state,NULL,false,true,'inherit'::view_permissions_type,false,false,'{}','{}');
 SELECT setval('lecture_id_seq', 1000);
 
 
diff --git a/api/migration.sql b/api/migration.sql
index 629a69dd73533aaf7754007c23f318a39e7c2c13..8eacea3e2db626e1824e2f989cf275ace492e089 100644
--- a/api/migration.sql
+++ b/api/migration.sql
@@ -137,7 +137,7 @@ FROM old_data.announcements
 INSERT INTO data.course (id, deleted, visible, handle, full_name, short_name, semester, organizer, topic, description,
     show_chapters_on_course, authentication_information, listed, internal_comment, allow_download, allow_embed, media_process,
     view_perm_type, view_perm_rwth_auth, view_perm_fsmpi_auth, view_perm_moodle_course_ids, view_perm_passwords,
-    disable_automatic_media_process_scheduler)
+    automatic_media_process_scheduler_state)
 SELECT
     id, deleted, visible, handle, title, short,
     CASE
@@ -178,7 +178,7 @@ SELECT
         'publish_wait_for_full_process', True
     ),
     'inherit', False, False, NULL, NULL,  -- view_perm (done below)
-    True  -- disable_automatic_media_process_scheduler
+    'disabled'::automatic_media_process_scheduler_state
 FROM old_data.courses_data
 ;
 
@@ -218,7 +218,7 @@ INSERT INTO data.lecture (id, deleted, visible, course_id, title, speaker, locat
     no_recording, livestream_planned, internal_comment,
     publish_time,
     view_perm_type, view_perm_rwth_auth, view_perm_fsmpi_auth, view_perm_moodle_course_ids, view_perm_passwords,
-    disable_automatic_media_process_scheduler)
+    automatic_media_process_scheduler_state)
 SELECT id, deleted, visible, course_id, title, speaker, place, "time", duration, comment,
     norecording, live, internal,
     (
@@ -233,7 +233,7 @@ SELECT id, deleted, visible, course_id, title, speaker, place, "time", duration,
         WHERE vid.lecture_id = old_lec.id AND vid.visible AND NOT vid.deleted
     ),  -- publish_time
     'inherit', False, False, NULL, NULL,  -- view_perm (filled below)
-    False  -- disable_automatic_media_process_scheduler (Already disabled by course)
+    'inherit'::automatic_media_process_scheduler_state -- Disabled in course
 FROM old_data.lectures_data AS old_lec
 WHERE course_id <> 0 -- These are empty
 ;
@@ -565,9 +565,9 @@ DO $$
             IF use_custom_process THEN
                 SELECT custom_process_producers || jsonb_build_object(
                     'type', 'sample_thumbnail',
-                    'source_id', thumbnail_producer_input_id,
+                    'input_id', thumbnail_producer_input_id,
                     'timestamp_percent', 20,
-                    'output_id', process_target_id
+                    'output_id', 'thumbnail'
                 ) INTO custom_process_producers;
                 SELECT custom_process_publish_target_ids || jsonb_build_array('thumbnail') INTO custom_process_publish_target_ids;
 
diff --git a/api/src/api/routes/media_process.py b/api/src/api/routes/media_process.py
index 0ad1ba541017ac1f3c93e4ebbc56fa8d39e3fcc0..c51f8fb1ca614c2eb4134d46dde046b99da5df3d 100644
--- a/api/src/api/routes/media_process.py
+++ b/api/src/api/routes/media_process.py
@@ -92,7 +92,7 @@ def api_route_run_source_file_sorter():
     def trans(session: SessionDb):
         scheduled_new = False
         sorter_job = session.scalar(
-            Job.select(api_user_ac(), [])
+            Job.sudo_select()
             .where(Job.type == "source_file_sorter")
             .where(Job.state.in_([JobState.READY, JobState.SPAWNING, JobState.RUNNING]))
             .order_by(Job.creation_time.desc())
@@ -135,7 +135,9 @@ def api_route_get_media_process_templates():
            response_description=f"Note that for the jobs there is a maximum recursion depth of {API_RELATIONSHIP_LOADING_MAXIMUM_RECURSION_DEPTH}",
            response_objects=[
                ("process", "media_process", "The current process for this lecture"),
+               ("process_sha256", "string", "SHA256 of the current process for this lecture"),
                ("status", "string", "String with some information about the process (e.g. error messages)"),
+               ("is_automatic_media_process_scheduler_enabled", "boolean"),
                ("sorter_files", "sorter_file{}", "Key is id"),
                ("medium_files", "medium_file{}", "Key is id"),
                ("medium_metadata", "medium_metadata{}", "Key is id"),
@@ -189,7 +191,9 @@ def api_route_get_lecture_media_process_overview(lecture_id: int):
         )
     return {
         "status": lecture.current_media_process_error,
+        "is_automatic_media_process_scheduler_enabled": lecture.is_automatic_media_process_scheduler_enabled,
         "process": lecture.effective_media_process_obj.to_json(),
+        "process_sha256": lecture.effective_media_process_obj.sha256(),
         "sorter_files": sorter_file_context,
         "medium_files": medium_file_context,
         "medium_metadata": medium_metadata_context,
@@ -200,30 +204,36 @@ def api_route_get_lecture_media_process_overview(lecture_id: int):
 
 @api_route("/lecture/<int:lecture_id>/run_media_process_scheduler", "POST",
            response_objects=[
-               ("scheduled", "boolean", "If false, another scheduler is probably still queued/running"),
+               ("scheduled_new", "boolean", "If false, the scheduler job already existed"),
+               ("job_id", "int", "The id of an already running scheduler job or the newly scheduled job"),
            ])
 @api_moderator_route(require_csrf_token=True)
 def api_route_run_media_process_scheduler(lecture_id: int):
     def trans(session: SessionDb):
-        if session.scalar(
+        scheduled_new = False
+        scheduler_job = session.scalar(
             Job.sudo_select()
             .where(Job.type == "media_process_scheduler")
-            .where(Job.state.in_([JobState.READY, JobState.SPAWNING, JobState.RUNNING]))
             .where(Job.input_data["lecture_id"].astext.cast(sql.Integer) == lecture_id)
-            .with_only_columns(sql.func.count())
-        ) > 0:
-            return False
-        session.add(Job(
-            type="media_process_scheduler",
-            input_data={
-                "lecture_id": lecture_id,
-                "manually_triggered": True
-            },
-            cause_user_id=get_user_id()
-        ))
-        return True
+            .where(Job.state.in_([JobState.READY, JobState.SPAWNING, JobState.RUNNING]))
+            .order_by(Job.creation_time.desc())
+            .limit(1)
+        )
+        if scheduler_job is None:
+            scheduler_job = Job(
+                type="media_process_scheduler",
+                input_data={
+                    "lecture_id": lecture_id,
+                    "manually_triggered": True
+                },
+                cause_user_id=get_user_id()
+            )
+            session.add(scheduler_job)
+            session.flush()  # Ensure ID present
+            scheduled_new = True
+        return {
+            "scheduled_new": scheduled_new,
+            "job_id": scheduler_job.id,
+        }
     
-    return {
-        "scheduled": database.execute_write_transaction_and_commit(trans)
-    }
-
+    return database.execute_write_transaction_and_commit(trans)
diff --git a/common_py/src/videoag_common/objects/course.py b/common_py/src/videoag_common/objects/course.py
index 72a3af04602d8dc1dbb59e8be6c7d6615b3659c3..1f9303a074bab976dbcb267b375177941fa2fb1b 100644
--- a/common_py/src/videoag_common/objects/course.py
+++ b/common_py/src/videoag_common/objects/course.py
@@ -6,6 +6,7 @@ from videoag_common.api_object import *
 from videoag_common.media_process import *
 from videoag_common.miscellaneous import *
 from .view_permissions import ViewPermissions, ApiViewPermissionsObject, DEFAULT_VIEW_PERMISSIONS
+from ..miscellaneous.json import CJsonException
 
 if TYPE_CHECKING:  # pragma: no cover
     # Can't actually import due to circular dependency
@@ -69,6 +70,15 @@ responsible_table = sql.Table(
 )
 
 
+class AutomaticMediaProcessSchedulerState(JsonSerializableEnum):
+    ENABLED = "enabled"
+    DISABLED = "disabled"
+    INHERIT = "inherit"
+
+
+AUTOMATIC_MEDIA_PROCESS_SCHEDULER_STATE = create_enum_type(AutomaticMediaProcessSchedulerState)
+
+
 class Lecture(DeletableApiObject, VisibilityApiObject, ApiViewPermissionsObject, Base):
     __api_class__ = ApiObjectClass(
         parent_relationship_config_ids=["course"]
@@ -171,11 +181,10 @@ class Lecture(DeletableApiObject, VisibilityApiObject, ApiViewPermissionsObject,
             include_in_config=True
         )
     )
-    disable_automatic_media_process_scheduler: Mapped[bool] = api_mapped(
-        mapped_column(nullable=False, default=False),
-        ApiBooleanField(
+    automatic_media_process_scheduler_state: Mapped[AutomaticMediaProcessSchedulerState] = api_mapped(
+        mapped_column(AUTOMATIC_MEDIA_PROCESS_SCHEDULER_STATE, nullable=False, default=AutomaticMediaProcessSchedulerState.ENABLED),
+        ApiEnumField(
             include_in_config=True,
-            # Course also has this field. Processor only works automatically if both fields are False
         )
     )
     current_media_process_error: Mapped[str] = mapped_column(nullable=True)
@@ -239,9 +248,25 @@ class Lecture(DeletableApiObject, VisibilityApiObject, ApiViewPermissionsObject,
     
     @property
     def effective_media_process_obj(self) -> MediaProcess:
-        if self.media_process is not None:
-            return MediaProcess.from_json(CJsonValue(self.media_process).as_object())
-        return MediaProcess.from_json(CJsonValue(self.course.media_process).as_object())
+        try:
+            if self.media_process is not None:
+                return MediaProcess.from_json(CJsonValue(self.media_process).as_object())
+            print(f"Course {self.course.id}. Py ID Self: {self}, Py ID Course: {self.course}")
+            print(self.course.media_process)
+            res = MediaProcess.from_json(CJsonValue(self.course.media_process).as_object())
+            print(self.course.media_process)
+            return res
+        except CJsonException as e:
+            raise Exception("Invalid media process in database") from e
+    
+    @property
+    def is_automatic_media_process_scheduler_enabled(self) -> bool:
+        state = self.automatic_media_process_scheduler_state
+        if state == AutomaticMediaProcessSchedulerState.INHERIT:
+            state = self.course.automatic_media_process_scheduler_state
+            if state == AutomaticMediaProcessSchedulerState.INHERIT:
+                state = AutomaticMediaProcessSchedulerState.ENABLED
+        return state == AutomaticMediaProcessSchedulerState.ENABLED
     
     @api_include_in_data(
         data_if=lambda lec, args: args.include_media,
@@ -377,11 +402,10 @@ class Course(DeletableApiObject, VisibilityApiObject, ApiViewPermissionsObject,
             include_in_config=True
         )
     )
-    disable_automatic_media_process_scheduler: Mapped[bool] = api_mapped(
-        mapped_column(nullable=False, default=False),
-        ApiBooleanField(
+    automatic_media_process_scheduler_state: Mapped[AutomaticMediaProcessSchedulerState] = api_mapped(
+        mapped_column(AUTOMATIC_MEDIA_PROCESS_SCHEDULER_STATE, nullable=False, default=AutomaticMediaProcessSchedulerState.ENABLED),
+        ApiEnumField(
             include_in_config=True,
-            # Lecture also has this field. Processor only works automatically if both fields are False
         )
     )
     
diff --git a/job_controller/jobs/media_process_scheduler/job.py b/job_controller/jobs/media_process_scheduler/job.py
index 2ba51840cedae2fb47d8cb66caba2c7aa13aee40..a7fa1f8c8e992e7ed6e1cfc7a49793d74a7116d7 100644
--- a/job_controller/jobs/media_process_scheduler/job.py
+++ b/job_controller/jobs/media_process_scheduler/job.py
@@ -56,9 +56,7 @@ class ProcessScheduler:
         if self._lecture is None:
             raise Exception(f"Unknown lecture with id {self._lecture_id}")
         
-        if not self._manually_triggered \
-                and (self._lecture.disable_automatic_media_process_scheduler
-                     or self._lecture.course.disable_automatic_media_process_scheduler):
+        if not self._manually_triggered and not self._lecture.is_automatic_media_process_scheduler_enabled:
             logger.info("Skipping because automatic scheduler is disabled")
             return
         
diff --git a/job_controller/jobs/media_process_scheduler/metadata.json b/job_controller/jobs/media_process_scheduler/metadata.json
index 452581f25e4f39864ccb4cb8ab26da5b93a846e7..d2be677be3c6dfef0fb50e59b0a467e3ced57f23 100644
--- a/job_controller/jobs/media_process_scheduler/metadata.json
+++ b/job_controller/jobs/media_process_scheduler/metadata.json
@@ -8,12 +8,13 @@
             "condition": [
                 "&",
                     ["object_type", "=", "lecture"],
-                    "|", "|", "|", "|",
+                    "|", "|", "|", "|", "|",
                         ["field_id", "=", "title"],
                         ["field_id", "=", "speaker"],
                         ["field_id", "=", "time"],
                         ["field_id", "=", "location"],
-                        ["field_id", "=", "media_process"]
+                        ["field_id", "=", "media_process"],
+                        ["field_id", "=", "automatic_media_process_scheduler_state"]
             ],
             "job_data": {
                 "lecture_id": "${object_id}"
@@ -25,9 +26,10 @@
                 "&", "&",
                     ["object_type", "=", "lecture"],
                     ["parent_object_type", "=", "course"],
-                    "|",
+                    "|", "|",
                         ["field_id", "=", "full_name"],
-                        ["field_id", "=", "media_process"]
+                        ["field_id", "=", "media_process"],
+                        ["field_id", "=", "automatic_media_process_scheduler_state"]
             ],
             "job_data": {
                 "lecture_id": "${object_id}"