diff --git a/common/src/async-queue.ts b/common/src/async-queue.ts
index 463566e55a..2485099f51 100644
--- a/common/src/async-queue.ts
+++ b/common/src/async-queue.ts
@@ -5,6 +5,7 @@ class EndError extends Error {
 
 export function createAsyncQueue<T>() {
     let ended: Error | undefined;
+    const endDeferred = new Deferred<void>();
     const waiting: Deferred<T>[] = [];
     const queued: { item: T, dequeued?: Deferred<void> }[] = [];
 
@@ -75,7 +76,8 @@ export function createAsyncQueue<T>() {
         if (ended)
             return false;
         // catch to prevent unhandled rejection.
-        ended = e || new EndError()
+        ended = e || new EndError();
+        endDeferred.resolve();
         while (waiting.length) {
             waiting.shift().reject(ended);
         }
@@ -124,6 +126,7 @@ export function createAsyncQueue<T>() {
         get ended() {
             return ended;
         },
+        endPromise: endDeferred.promise,
         take,
         clear() {
             return clear();
diff --git a/server/src/media-helpers.ts b/server/src/media-helpers.ts
index 52de7b6cc9..3147a19978 100644
--- a/server/src/media-helpers.ts
+++ b/server/src/media-helpers.ts
@@ -1,5 +1,6 @@
 import { ChildProcess } from "child_process";
 import process from 'process';
+import { sleep } from "./sleep";
 
 const filtered = [
     'decode_slice_header error',
@@ -7,17 +8,22 @@ const filtered = [
     'non-existing PPS',
 ];
 
-export function safeKillFFmpeg(cp: ChildProcess) {
+export async function safeKillFFmpeg(cp: ChildProcess) {
     if (!cp)
         return;
-    // this will allow ffmpeg to send rtsp TEARDOWN etc
-    try {
-        cp.stdin.on('error', () => {});
-        cp.stdin.write('q\n');
-    }
-    catch (e) {
-    }
-    setTimeout(() => {
+    if (cp.exitCode != null)
+        return;
+    await new Promise(async resolve => {
+        cp.on('exit', resolve);
+        // this will allow ffmpeg to send rtsp TEARDOWN etc
+        try {
+            cp.stdin.on('error', () => { });
+            cp.stdin.write('q\n');
+        }
+        catch (e) {
+        }
+
+        await sleep(2000);
         for (const f of cp.stdio) {
             try {
                 f?.destroy();
@@ -25,11 +31,9 @@ export function safeKillFFmpeg(cp: ChildProcess) {
             catch (e) {
             }
         }
-        cp.kill();
-        setTimeout(() => {
-            cp.kill('SIGKILL');
-        }, 2000);
-    }, 2000);
+        await sleep(2000);
+        cp.kill('SIGKILL');
+    });
 }
 
 export function ffmpegLogInitialOutput(console: Console, cp: ChildProcess, forever?: boolean, storage?: Storage) {