-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.js
112 lines (93 loc) · 2.8 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const WebSocketServer = require("ws").Server;
const child_process = require("child_process");
const url = require("url");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = createServer((req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on port ${port}`);
});
const wss = new WebSocketServer({
server: server,
});
wss.on("connection", (ws, req) => {
console.log("Socket connected");
const queryString = url.parse(req.url).search;
const params = new URLSearchParams(queryString);
const key = params.get("key");
const rtmpUrl = `rtmps://global-live.mux.com/app/${key}`;
const ffmpeg = child_process.spawn("ffmpeg", [
"-i",
"-",
// video codec config: low latency, adaptive bitrate
"-c:v",
"libx264",
"-preset",
"veryfast",
"-tune",
"zerolatency",
// audio codec config: sampling frequency (11025, 22050, 44100), bitrate 64 kbits
"-c:a",
"aac",
"-strict",
"-2",
"-ar",
"44100",
"-b:a",
"64k",
//force to overwrite
"-y",
// used for audio sync
"-use_wallclock_as_timestamps",
"1",
"-async",
"1",
//'-filter_complex', 'aresample=44100', // resample audio to 44100Hz, needed if input is not 44100
//'-strict', 'experimental',
"-bufsize",
"1000",
"-f",
"flv",
rtmpUrl,
]);
// Kill the WebSocket connection if ffmpeg dies.
ffmpeg.on("close", (code, signal) => {
console.log(
"FFmpeg child process closed, code " + code + ", signal " + signal
);
ws.terminate();
});
// Handle STDIN pipe errors by logging to the console.
// These errors most commonly occur when FFmpeg closes and there is still
// data to write.f If left unhandled, the server will crash.
ffmpeg.stdin.on("error", (e) => {
console.log("FFmpeg STDIN Error", e);
});
// FFmpeg outputs all of its messages to STDERR. Let's log them to the console.
ffmpeg.stderr.on("data", (data) => {
ws.send("ffmpeg got some data");
console.log("FFmpeg STDERR:", data.toString());
});
ws.on("message", (msg) => {
if (Buffer.isBuffer(msg)) {
console.log("Sent video data");
ffmpeg.stdin.write(msg);
} else {
console.log(msg);
}
});
ws.on("close", (e) => {
console.log("Websocket closed");
ffmpeg.kill("SIGINT");
});
});
});