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) {