diff --git a/src/bot/radio.js b/src/bot/radio.js index 59026bb..9614939 100644 --- a/src/bot/radio.js +++ b/src/bot/radio.js @@ -177,8 +177,14 @@ export async function titelHolen(url, { timeoutMs = 8000, bloecke = 3 } = {}) { * ihn sonst endgültig beenden. Bei einer Rohrleitung wäre dieselbe Option * sinnlos — es gibt nichts, wohin sich neu verbinden liesse. * + * `netz` entscheidet ausserdem, ob stdin offen ist, und das ist keine + * Feinheit: bei `-i pipe:0` MUSS stdin eine Rohrleitung sein. Stand hier + * `ignore` (wie es bis zum 28.08.2026 der Fall war), zeigt `pipe:0` auf + * /dev/null — ffmpeg meldet dann „Invalid data found when processing input", + * und `ff.stdin` ist `null`, woran der Aufbau der Kette vorher zerbrach. + * * @param {string} eingabe Adresse oder `pipe:0` - * @param {{netz: boolean}} opts + * @param {{netz: boolean}} opts netz=true: ffmpeg holt selbst; false: es liest aus stdin */ function wandler(eingabe, { netz }) { const ff = spawn(FFMPEG, [ @@ -195,7 +201,8 @@ function wandler(eingabe, { netz }) { '-f', 's16le', '-acodec', 'pcm_s16le', '-ar', '48000', '-ac', '2', 'pipe:1', - ], { stdio: ['ignore', 'pipe', 'pipe'] }); + // Kein stdin bei einer Adresse, eine Rohrleitung bei `pipe:0`. + ], { stdio: [netz ? 'ignore' : 'pipe', 'pipe', 'pipe'] }); // Ohne Zuhörer auf stderr läuft die Pipe voll und ffmpeg bleibt stehen ff.stderr.on('data', (d) => { const text = d.toString().trim(); @@ -223,6 +230,17 @@ function tonquelle(quelle) { } const yt = tonstrom(quelle.titel.url); const ff = wandler('pipe:0', { netz: false }); + // Startet ein Prozess nicht, sind seine Rohrenden `null`. Ohne diese + // Prüfung wirft schon das Anhängen der Fehlerbehandlung einen + // TypeError — und der reisst die ganze Interaktion mit, statt dass + // jemand „kein Ton" zu sehen bekommt. + if (!yt.stdout || !ff.stdin) { + yt.kill('SIGKILL'); + ff.kill('SIGKILL'); + throw new Error('Tonkette liess sich nicht aufbauen — ' + + `yt-dlp: ${yt.stdout ? 'ok' : 'kein Ausgang'}, ` + + `ffmpeg: ${ff.stdin ? 'ok' : 'kein Eingang'}.`); + } yt.stdout.on('error', () => {}); ff.stdin.on('error', () => {}); yt.stdout.pipe(ff.stdin); diff --git a/src/web/api.js b/src/web/api.js index 48f7d99..f01799b 100644 --- a/src/web/api.js +++ b/src/web/api.js @@ -28,7 +28,7 @@ import { createService, updateService, listServices, deleteService, savePage, getPage, listPages, listPublishedPages, deletePage, lsState, lsModSizes, setLsModSize, - listStations, createStation, updateStation, deleteStation, + listStations, getStation, createStation, updateStation, deleteStation, queueList, queueRemove, queueClear, queueReorder, queueVor, queueStand, setRadioState, clearRadioState, radioState, } from '../db.js';