wuhp commited on
Commit
51d5cd5
·
verified ·
1 Parent(s): 9f9fec7

Create server.ts

Browse files
Files changed (1) hide show
  1. server.ts +91 -0
server.ts ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from 'express';
2
+ import { createServer as createViteServer } from 'vite';
3
+ import { createProxyMiddleware } from 'http-proxy-middleware';
4
+ import path from 'path';
5
+ import crypto from 'crypto';
6
+ import { createRequire } from 'module';
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const NodeMediaServer = require('node-media-server');
10
+
11
+ async function startServer() {
12
+ const app = express();
13
+ const PORT = 3000;
14
+
15
+ // Start Node Media Server for RTMP Ingest (1935) and HTTP FLV (8123)
16
+ const nmsConfig = {
17
+ rtmp: {
18
+ port: 1935,
19
+ chunk_size: 60000,
20
+ gop_cache: true,
21
+ ping: 30,
22
+ ping_timeout: 60
23
+ },
24
+ http: {
25
+ port: 8123,
26
+ allow_origin: '*',
27
+ }
28
+ };
29
+
30
+ const nms = new NodeMediaServer(nmsConfig);
31
+ nms.run();
32
+
33
+ // Proxy HTTP FLV requests from port 3000 to port 8123 where NMS is listening
34
+ // This allows the frontend web player to access the stream using HTTP-FLV over port 3000
35
+ app.use('/live', createProxyMiddleware({
36
+ target: 'http://127.0.0.1:8123',
37
+ changeOrigin: true,
38
+ ws: true
39
+ }));
40
+ app.use('/api/streams', createProxyMiddleware({
41
+ target: 'http://127.0.0.1:8123',
42
+ changeOrigin: true
43
+ }));
44
+
45
+ // API Route to get connection info
46
+ app.get('/api/config', (req, res) => {
47
+ const appUrl = process.env.APP_URL || 'localhost';
48
+ let rtmpUrl = '';
49
+
50
+ // Determine the external URL. Note: AI Studio only exposes Port 3000 (HTTP).
51
+ // Testing RTMP from OBS externally requires running this code locally or using a TCP tunnel.
52
+ if (appUrl.startsWith('https://')) {
53
+ const hostname = new URL(appUrl).hostname;
54
+ rtmpUrl = `rtmp://${hostname}/live`;
55
+ } else {
56
+ rtmpUrl = `rtmp://${appUrl.split(':')[0]}/live`;
57
+ }
58
+
59
+ res.json({ rtmpUrl });
60
+ });
61
+
62
+ // Vite middleware for development
63
+ if (process.env.NODE_ENV !== 'production') {
64
+ const vite = await createViteServer({
65
+ server: { middlewareMode: true },
66
+ appType: 'spa',
67
+ });
68
+ app.use(vite.middlewares);
69
+ } else {
70
+ // production mode
71
+ const distPath = path.join(process.cwd(), 'dist');
72
+ app.use(express.static(distPath));
73
+ app.get('*', (req, res) => {
74
+ res.sendFile(path.join(distPath, 'index.html'));
75
+ });
76
+ }
77
+
78
+ const server = app.listen(PORT, '0.0.0.0', () => {
79
+ console.log(`Express server running on http://localhost:${PORT}`);
80
+ });
81
+
82
+ // Graceful shutdown to release ports
83
+ process.on('SIGTERM', () => {
84
+ console.log('SIGTERM received, shutting down...');
85
+ nms.stop();
86
+ server.close();
87
+ process.exit(0);
88
+ });
89
+ }
90
+
91
+ startServer();