feat: add ffmpeg music player
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
70
src/media/musicPlayer.ts
Normal file
70
src/media/musicPlayer.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { spawn as nodeSpawn } from "node:child_process";
|
||||
import type { ChildProcessWithoutNullStreams } from "node:child_process";
|
||||
import { discordPlayer } from "../player";
|
||||
import type {
|
||||
DiscordAudioPlayer,
|
||||
MusicPlayback,
|
||||
MusicPlayer,
|
||||
ResolvedMediaSource,
|
||||
} from "./mediaTypes";
|
||||
|
||||
export interface MusicPlayerDependencies {
|
||||
spawn?: typeof nodeSpawn;
|
||||
discordPlayer?: DiscordAudioPlayer;
|
||||
}
|
||||
|
||||
export function createMusicPlayer(
|
||||
dependencies: MusicPlayerDependencies = {},
|
||||
): MusicPlayer {
|
||||
const spawn = dependencies.spawn ?? nodeSpawn;
|
||||
const audioPlayer = dependencies.discordPlayer ?? discordPlayer;
|
||||
|
||||
return {
|
||||
play(source: ResolvedMediaSource): MusicPlayback {
|
||||
const proc = spawn("ffmpeg", buildFfmpegArgs(source.source), {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
}) as unknown as ChildProcessWithoutNullStreams;
|
||||
|
||||
audioPlayer.playStream(proc.stdout);
|
||||
|
||||
const done = new Promise<void>((resolve, reject) => {
|
||||
proc.on("error", reject);
|
||||
proc.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
reject(new Error(`ffmpeg exited with code ${code}`));
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
done,
|
||||
stop() {
|
||||
proc.kill("SIGTERM");
|
||||
audioPlayer.stop();
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function buildFfmpegArgs(source: string): string[] {
|
||||
return [
|
||||
"-hide_banner",
|
||||
"-loglevel",
|
||||
"warning",
|
||||
"-i",
|
||||
source,
|
||||
"-vn",
|
||||
"-acodec",
|
||||
"libopus",
|
||||
"-ar",
|
||||
"48000",
|
||||
"-ac",
|
||||
"2",
|
||||
"-f",
|
||||
"ogg",
|
||||
"pipe:1",
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user