mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-01 20:42:50 +08:00
feat: bundle FFmpeg via ffmpeg-static for one-click deployment
Users no longer need to install FFmpeg separately — it is now bundled as an npm dependency (ffmpeg-static). player.ts resolves the bundled binary automatically and falls back to system PATH. start.bat and a new setup.bat script handle dependency installation and project building. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
00231db0cb
commit
61d9bbe0b7
5 files changed
+1034
-18
No files matched your search
Generated
+897
File diff suppressed because it is too large.
Load diff
@@ -15,9 +15,16 @@
|
||||
"dependencies": {
|
||||
"@discordjs/opus": "^0.10.0",
|
||||
"@honeybbq/teamspeak-client": "^0.1.0",
|
||||
"@koa/router": "^15.4.0",
|
||||
"@sansenjian/qq-music-api": "^2.2.9",
|
||||
"axios": "^1.14.0",
|
||||
"better-sqlite3": "^12.8.0",
|
||||
"chalk": "^5.6.2",
|
||||
"express": "^5.2.1",
|
||||
"ffmpeg-static": "^5.3.0",
|
||||
"koa": "^3.2.0",
|
||||
"koa-bodyparser": "^4.4.1",
|
||||
"koa-static": "^5.0.0",
|
||||
"NeteaseCloudMusicApi": "^4.30.0",
|
||||
"pino": "^10.3.1",
|
||||
"ts3-nodejs-library": "^3.5.1",
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
@echo off
|
||||
title TSMusicBot Setup
|
||||
echo ============================================
|
||||
echo TSMusicBot - First-Time Setup (Windows)
|
||||
echo ============================================
|
||||
echo.
|
||||
|
||||
:: Resolve project root (one level up from scripts/)
|
||||
cd /d "%~dp0.."
|
||||
|
||||
:: ---- Step 1: Check / install Node.js ----
|
||||
where node >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo Node.js not found. Attempting automatic installation...
|
||||
echo.
|
||||
|
||||
:: Try winget first (available on Windows 10 1709+ and Windows 11)
|
||||
where winget >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
echo Installing Node.js via winget...
|
||||
winget install OpenJS.NodeJS.LTS --accept-source-agreements --accept-package-agreements
|
||||
if %errorlevel% neq 0 (
|
||||
echo winget installation failed. Please install Node.js manually from https://nodejs.org
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
:: Refresh PATH so node is available in this session
|
||||
call refreshenv >nul 2>&1
|
||||
:: If refreshenv is not available, ask user to restart
|
||||
where node >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo.
|
||||
echo Node.js was installed but is not yet available in this terminal.
|
||||
echo Please close this window and run setup.bat again.
|
||||
pause
|
||||
exit /b 0
|
||||
)
|
||||
) else (
|
||||
echo winget is not available on this system.
|
||||
echo Please install Node.js 20 LTS manually from https://nodejs.org
|
||||
echo After installing, close this window and run setup.bat again.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
) else (
|
||||
echo [OK] Node.js found.
|
||||
node --version
|
||||
)
|
||||
echo.
|
||||
|
||||
:: ---- Step 2: Install npm dependencies ----
|
||||
echo Installing dependencies (this may take a few minutes)...
|
||||
call npm install
|
||||
if %errorlevel% neq 0 (
|
||||
echo.
|
||||
echo npm install failed. Check the error messages above.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo [OK] Dependencies installed.
|
||||
echo.
|
||||
|
||||
:: ---- Step 3: Build the project ----
|
||||
echo Building TypeScript project...
|
||||
call npx tsc
|
||||
if %errorlevel% neq 0 (
|
||||
echo.
|
||||
echo Build failed. Check the error messages above.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo [OK] Build succeeded.
|
||||
echo.
|
||||
|
||||
:: ---- Step 4: Create default config if missing ----
|
||||
if not exist "config.json" (
|
||||
echo Creating default config.json...
|
||||
echo Please edit config.json with your TeamSpeak server details before starting the bot.
|
||||
) else (
|
||||
echo [OK] config.json already exists.
|
||||
)
|
||||
echo.
|
||||
|
||||
:: ---- Done ----
|
||||
echo ============================================
|
||||
echo Setup complete!
|
||||
echo ============================================
|
||||
echo.
|
||||
echo To start the bot, run: scripts\start.bat
|
||||
echo.
|
||||
pause
|
||||
+25
-17
@@ -6,34 +6,42 @@ echo.
|
||||
:: Check if node is available
|
||||
where node >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo Node.js is not installed. Please install Node.js 20 LTS from https://nodejs.org
|
||||
echo Node.js is not installed.
|
||||
echo Run scripts\setup.bat for automatic installation, or install Node.js 20+ from https://nodejs.org
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: Check if ffmpeg is available
|
||||
where ffmpeg >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo FFmpeg not found in PATH. Checking local directory...
|
||||
if exist "%~dp0ffmpeg\ffmpeg.exe" (
|
||||
set PATH=%~dp0ffmpeg;%PATH%
|
||||
echo Using bundled FFmpeg.
|
||||
) else (
|
||||
echo FFmpeg is required. Please install FFmpeg or place it in the ffmpeg\ directory.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
:: Resolve project root (one level up from scripts/)
|
||||
cd /d "%~dp0.."
|
||||
|
||||
:: Install dependencies if needed
|
||||
if not exist "%~dp0node_modules" (
|
||||
if not exist "node_modules" (
|
||||
echo Installing dependencies...
|
||||
cd /d "%~dp0"
|
||||
call npm install --production
|
||||
if %errorlevel% neq 0 (
|
||||
echo Failed to install dependencies.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
:: Build if dist/ doesn't exist
|
||||
if not exist "dist" (
|
||||
echo Building project...
|
||||
call npx tsc
|
||||
if %errorlevel% neq 0 (
|
||||
echo Build failed.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
:: FFmpeg is bundled via ffmpeg-static — no PATH check needed.
|
||||
echo FFmpeg is bundled via node_modules (ffmpeg-static).
|
||||
echo.
|
||||
|
||||
:: Start the application
|
||||
cd /d "%~dp0"
|
||||
node dist/index.js
|
||||
|
||||
pause
|
||||
+14
-1
@@ -1,8 +1,19 @@
|
||||
import { spawn, type ChildProcess } from "node:child_process";
|
||||
import { EventEmitter } from "node:events";
|
||||
import { createRequire } from "node:module";
|
||||
import { createOpusEncoder, PCM_FRAME_BYTES, type Encoder } from "./encoder.js";
|
||||
import type { Logger } from "../logger.js";
|
||||
|
||||
// ffmpeg-static is a CJS module that exports the path to the bundled ffmpeg binary.
|
||||
const require = createRequire(import.meta.url);
|
||||
const ffmpegPath: string | null = require("ffmpeg-static");
|
||||
|
||||
/** Resolve ffmpeg binary: prefer bundled ffmpeg-static, fall back to system PATH. */
|
||||
function getFfmpegCommand(): string {
|
||||
if (ffmpegPath) return ffmpegPath;
|
||||
return "ffmpeg"; // fallback to system-installed ffmpeg
|
||||
}
|
||||
|
||||
export interface PlayerEvents {
|
||||
frame: (opusFrame: Buffer) => void;
|
||||
trackEnd: () => void;
|
||||
@@ -57,7 +68,9 @@ export class AudioPlayer extends EventEmitter {
|
||||
"-",
|
||||
);
|
||||
|
||||
this.ffmpeg = spawn("ffmpeg", args, { stdio: ["ignore", "pipe", "pipe"] });
|
||||
const ffmpegBin = getFfmpegCommand();
|
||||
this.logger.debug({ ffmpeg: ffmpegBin }, "Using ffmpeg binary");
|
||||
this.ffmpeg = spawn(ffmpegBin, args, { stdio: ["ignore", "pipe", "pipe"] });
|
||||
|
||||
this.ffmpeg.stderr!.on("data", () => {});
|
||||
|
||||
|
||||
Reference in new issue
Block a user