MCPcopy
hub / github.com/cpaczek/skylight / spawnProc

Method spawnProc

tracker/src/video/mse.ts:99–137  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

97 }
98
99 private spawnProc(): void {
100 if (this.proc || this.stopped) return;
101 this.generation++;
102 // Fresh stream epoch: clients must rejoin at the new init segment.
103 this.initSegment = null;
104 this.codec = null;
105 this.buffer = Buffer.alloc(0);
106 for (const c of this.clients) c.awaitingFragment = true;
107
108 const args = [
109 "-hide_banner", "-loglevel", "error",
110 "-rtsp_transport", "tcp",
111 "-i", this.url,
112 "-c:v", "copy", "-an",
113 "-f", "mp4",
114 "-movflags", "frag_keyframe+empty_moov+default_base_moof",
115 "pipe:1",
116 ];
117 const proc = spawn("ffmpeg", args, { stdio: ["ignore", "pipe", "pipe"] });
118 this.proc = proc;
119 this.lastError = undefined;
120 console.log(`[mse] ffmpeg -c copy <- ${this.url}`);
121
122 proc.stdout!.on("data", (chunk: Buffer) => this.onData(chunk));
123 let stderrTail = "";
124 proc.stderr!.on("data", (c: Buffer) => {
125 stderrTail = (stderrTail + c.toString()).slice(-400);
126 });
127 proc.on("exit", (code) => {
128 // A killed/superseded process must not clobber its replacement or
129 // schedule a duplicate respawn.
130 if (this.proc !== proc) return;
131 this.proc = null;
132 if (this.stopped) return;
133 this.lastError = `ffmpeg exited (${code}): ${stderrTail.trim().split("\n").pop() ?? ""}`;
134 console.error(`[mse] ${this.lastError}`);
135 this.restartTimer = setTimeout(() => this.spawnProc(), 3000);
136 });
137 }
138
139 private kill(): void {
140 this.proc?.kill("SIGKILL");

Callers 2

setUrlMethod · 0.95
startMethod · 0.95

Calls 2

onDataMethod · 0.95
errorMethod · 0.80

Tested by

no test coverage detected