Files
selfphoneng/apps/api/test/audio.ts
T
iamdoubz 17db68a8c5 sounds: upload, convert, play, rename, delete with references
/api/sounds (admin) takes the raw file, converts it with ffmpeg in one
pass to <id>.wav (8 kHz) and <id>.g722 (HD for G.722 calls) in SOUNDS_DIR,
measures it with ffprobe, and stores it as custom/<id>. Delete answers 409
with what still plays it (IVR greeting/invalid sound, announcements, the
recording notice). Sounds & music page: drop or pick a file (name
suggested from the file name), play, rename, delete. MOH classes stay in
M8. The web client and greetings share one raw-upload helper; the
api test audio helpers moved to test/audio.ts.

e2e m6-t1: drag-and-drop upload in the browser, Asterisk plays
custom/<id>, rename, delete refused while in use, then deleted.

Task: M6-T1
2026-10-18 10:13:58 -05:00

25 lines
736 B
TypeScript

// SPDX-License-Identifier: AGPL-3.0-or-later
// Audio test helpers.
import { spawnSync } from 'node:child_process';
export const hasFfmpeg = spawnSync('ffmpeg', ['-version']).status === 0;
/** 8 kHz mono 16-bit silence as a wav file. */
export function silenceWav(seconds = 1) {
const data = Buffer.alloc(8000 * 2 * seconds);
const h = Buffer.alloc(44);
h.write('RIFF', 0);
h.writeUInt32LE(36 + data.length, 4);
h.write('WAVEfmt ', 8);
h.writeUInt32LE(16, 16);
h.writeUInt16LE(1, 20);
h.writeUInt16LE(1, 22);
h.writeUInt32LE(8000, 24);
h.writeUInt32LE(16000, 28);
h.writeUInt16LE(2, 32);
h.writeUInt16LE(16, 34);
h.write('data', 36);
h.writeUInt32LE(data.length, 40);
return Buffer.concat([h, data]);
}