Initial commit: Retribusi frontend dengan dashboard, event logs, dan settings
This commit is contained in:
22
proxy/package.json
Normal file
22
proxy/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "rtsp-websocket-proxy",
|
||||
"version": "1.0.0",
|
||||
"description": "RTSP to WebSocket proxy server for jsmpeg player",
|
||||
"main": "rtsp-websocket-proxy.js",
|
||||
"scripts": {
|
||||
"start": "node rtsp-websocket-proxy.js",
|
||||
"start:kerkof": "node rtsp-websocket-proxy.js rtsp://10.60.0.10:8554/cam1 8082"
|
||||
},
|
||||
"keywords": [
|
||||
"rtsp",
|
||||
"websocket",
|
||||
"proxy",
|
||||
"jsmpeg"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ws": "^8.14.2"
|
||||
}
|
||||
}
|
||||
|
||||
151
proxy/rtsp-websocket-proxy.js
Normal file
151
proxy/rtsp-websocket-proxy.js
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* RTSP to WebSocket Proxy Server
|
||||
* Convert RTSP stream ke WebSocket untuk jsmpeg player
|
||||
*
|
||||
* Usage:
|
||||
* node rtsp-websocket-proxy.js <rtsp_url> <ws_port>
|
||||
*
|
||||
* Example:
|
||||
* node rtsp-websocket-proxy.js rtsp://10.60.0.10:8554/cam1 8082
|
||||
*/
|
||||
|
||||
const WebSocket = require('ws');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
// Parse arguments
|
||||
const rtspUrl = process.argv[2] || 'rtsp://10.60.0.10:8554/cam1';
|
||||
const wsPort = parseInt(process.argv[3]) || 8082;
|
||||
|
||||
console.log('🚀 Starting RTSP to WebSocket Proxy');
|
||||
console.log('📹 RTSP URL:', rtspUrl);
|
||||
console.log('🔌 WebSocket Port:', wsPort);
|
||||
console.log('');
|
||||
|
||||
// Create WebSocket server
|
||||
const wss = new WebSocket.Server({
|
||||
port: wsPort,
|
||||
perMessageDeflate: false
|
||||
});
|
||||
|
||||
let ffmpegProcess = null;
|
||||
let clients = new Set();
|
||||
|
||||
wss.on('connection', (ws) => {
|
||||
console.log('✅ New WebSocket client connected');
|
||||
clients.add(ws);
|
||||
|
||||
// Start FFmpeg process jika belum ada
|
||||
if (!ffmpegProcess) {
|
||||
startFFmpeg();
|
||||
}
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('❌ WebSocket client disconnected');
|
||||
clients.delete(ws);
|
||||
|
||||
// Stop FFmpeg jika tidak ada client lagi
|
||||
if (clients.size === 0 && ffmpegProcess) {
|
||||
console.log('⏹️ No clients, stopping FFmpeg');
|
||||
stopFFmpeg();
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('error', (error) => {
|
||||
console.error('❌ WebSocket error:', error.message);
|
||||
});
|
||||
});
|
||||
|
||||
function startFFmpeg() {
|
||||
console.log('🎬 Starting FFmpeg process...');
|
||||
|
||||
// FFmpeg command untuk convert RTSP ke MPEG1 video stream
|
||||
// Format: MPEG1 video (untuk jsmpeg) dengan resolusi 800x600, bitrate 1000k
|
||||
const ffmpegArgs = [
|
||||
'-i', rtspUrl, // Input RTSP URL
|
||||
'-f', 'mpegts', // Output format: MPEG Transport Stream
|
||||
'-codec:v', 'mpeg1video', // Video codec: MPEG1 (untuk jsmpeg)
|
||||
'-s', '800x600', // Resolution
|
||||
'-b:v', '1000k', // Video bitrate
|
||||
'-bf', '0', // No B-frames
|
||||
'-codec:a', 'mp2', // Audio codec: MP2
|
||||
'-b:a', '128k', // Audio bitrate
|
||||
'-r', '25', // Frame rate: 25 fps
|
||||
'pipe:1' // Output to stdout
|
||||
];
|
||||
|
||||
ffmpegProcess = spawn('ffmpeg', ffmpegArgs, {
|
||||
stdio: ['ignore', 'pipe', 'pipe']
|
||||
});
|
||||
|
||||
ffmpegProcess.stdout.on('data', (data) => {
|
||||
// Broadcast ke semua connected clients
|
||||
clients.forEach(client => {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
client.send(data);
|
||||
} catch (error) {
|
||||
console.error('Error sending data to client:', error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ffmpegProcess.stderr.on('data', (data) => {
|
||||
// FFmpeg logs ke stderr, bisa di-ignore atau di-log untuk debugging
|
||||
const message = data.toString();
|
||||
if (message.includes('error') || message.includes('Error')) {
|
||||
console.error('FFmpeg error:', message);
|
||||
}
|
||||
});
|
||||
|
||||
ffmpegProcess.on('exit', (code, signal) => {
|
||||
console.log(`⚠️ FFmpeg process exited with code ${code}, signal ${signal}`);
|
||||
ffmpegProcess = null;
|
||||
|
||||
// Restart jika masih ada clients
|
||||
if (clients.size > 0) {
|
||||
console.log('🔄 Restarting FFmpeg...');
|
||||
setTimeout(() => startFFmpeg(), 2000);
|
||||
}
|
||||
});
|
||||
|
||||
ffmpegProcess.on('error', (error) => {
|
||||
console.error('❌ FFmpeg spawn error:', error.message);
|
||||
console.error('💡 Make sure FFmpeg is installed and available in PATH');
|
||||
ffmpegProcess = null;
|
||||
});
|
||||
|
||||
console.log('✅ FFmpeg process started');
|
||||
}
|
||||
|
||||
function stopFFmpeg() {
|
||||
if (ffmpegProcess) {
|
||||
console.log('⏹️ Stopping FFmpeg process...');
|
||||
ffmpegProcess.kill('SIGTERM');
|
||||
ffmpegProcess = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n🛑 Shutting down...');
|
||||
stopFFmpeg();
|
||||
wss.close(() => {
|
||||
console.log('✅ Server closed');
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('\n🛑 Shutting down...');
|
||||
stopFFmpeg();
|
||||
wss.close(() => {
|
||||
console.log('✅ Server closed');
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
console.log(`✅ WebSocket server listening on ws://0.0.0.0:${wsPort}`);
|
||||
console.log('💡 Connect from browser: ws://localhost:' + wsPort);
|
||||
console.log('💡 Press Ctrl+C to stop\n');
|
||||
|
||||
39
proxy/start-proxy.bat
Normal file
39
proxy/start-proxy.bat
Normal file
@@ -0,0 +1,39 @@
|
||||
@echo off
|
||||
echo ========================================
|
||||
echo RTSP to WebSocket Proxy Server
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
echo Checking Node.js...
|
||||
node --version >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Node.js not found!
|
||||
echo Please install Node.js from https://nodejs.org/
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Checking FFmpeg...
|
||||
ffmpeg -version >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo ERROR: FFmpeg not found!
|
||||
echo Please install FFmpeg and add to PATH
|
||||
echo Download from https://ffmpeg.org/download.html
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Starting proxy server...
|
||||
echo RTSP URL: rtsp://10.60.0.10:8554/cam1
|
||||
echo WebSocket Port: 8082
|
||||
echo.
|
||||
echo Press Ctrl+C to stop
|
||||
echo.
|
||||
|
||||
node rtsp-websocket-proxy.js rtsp://10.60.0.10:8554/cam1 8082
|
||||
|
||||
pause
|
||||
|
||||
Reference in New Issue
Block a user