aethex.live/media-server.js
2026-02-27 22:12:19 -07:00

122 lines
3.6 KiB
JavaScript

/**
* AeThex LIVE - RTMP Media Server
*
* This receives RTMP streams from OBS and converts to HLS for playback.
*
* OBS Settings:
* Server: rtmp://localhost:1935/live
* Stream Key: anything (e.g., "stream" or a random key)
*
* HLS Playback URL:
* http://localhost:8000/live/{streamKey}/index.m3u8
*/
const NodeMediaServer = require('node-media-server');
const path = require('path');
const fs = require('fs');
// Create media directory if it doesn't exist
const mediaDir = path.join(__dirname, 'media');
if (!fs.existsSync(mediaDir)) {
fs.mkdirSync(mediaDir, { recursive: true });
}
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
mediaroot: mediaDir,
allow_origin: '*',
api: true
},
trans: {
ffmpeg: process.env.FFMPEG_PATH || 'ffmpeg',
tasks: [
{
app: 'live',
hls: true,
hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
hlsKeep: false, // Don't keep old segments
dash: false,
}
]
}
};
const nms = new NodeMediaServer(config);
nms.on('preConnect', (id, args) => {
console.log('[NodeEvent on preConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('postConnect', (id, args) => {
console.log('[NodeEvent on postConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('doneConnect', (id, args) => {
console.log('[NodeEvent on doneConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('prePublish', (id, StreamPath, args) => {
console.log('[NodeEvent on prePublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
console.log('');
console.log('='.repeat(60));
console.log('🎥 STREAM STARTED!');
console.log('='.repeat(60));
console.log(`HLS URL: http://localhost:8000${StreamPath}/index.m3u8`);
console.log('');
console.log('Add this to your .env.local:');
console.log(`NEXT_PUBLIC_STREAM_URL=http://localhost:8000${StreamPath}/index.m3u8`);
console.log('='.repeat(60));
console.log('');
});
nms.on('postPublish', (id, StreamPath, args) => {
console.log('[NodeEvent on postPublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('donePublish', (id, StreamPath, args) => {
console.log('[NodeEvent on donePublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
console.log('');
console.log('⏹️ Stream ended');
console.log('');
});
nms.on('prePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on prePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('postPlay', (id, StreamPath, args) => {
console.log('[NodeEvent on postPlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('donePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on donePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
console.log('');
console.log('='.repeat(60));
console.log('🚀 AeThex LIVE - Media Server Starting');
console.log('='.repeat(60));
console.log('');
console.log('RTMP Server: rtmp://localhost:1935/live');
console.log('HTTP Server: http://localhost:8000');
console.log('');
console.log('OBS Settings:');
console.log(' Service: Custom');
console.log(' Server: rtmp://localhost:1935/live');
console.log(' Stream Key: stream (or any key you want)');
console.log('');
console.log('After you start streaming, your HLS URL will be:');
console.log(' http://localhost:8000/live/stream/index.m3u8');
console.log('');
console.log('='.repeat(60));
console.log('');
nms.run();