@camstack/system 1.2.265 → 1.2.266

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2243,6 +2243,25 @@ async function startGridCompositorChild(ctx, plan, sources, onEnded) {
2243
2243
  };
2244
2244
  let encoderIn = null;
2245
2245
  let encoderOut = null;
2246
+ let draining = false;
2247
+ let tick = null;
2248
+ const compositor = new GridCompositor({
2249
+ plan: tilePlan,
2250
+ write: (frame) => {
2251
+ const sink = encoderIn;
2252
+ if (sink === null || draining || sink.destroyed) return false;
2253
+ const accepted = sink.write(frame);
2254
+ if (!accepted) draining = true;
2255
+ return accepted;
2256
+ }
2257
+ });
2258
+ const startTick = () => {
2259
+ if (tick !== null) return;
2260
+ tick = setInterval(() => {
2261
+ compositor.tick();
2262
+ }, Math.max(1, Math.round(1e3 / plan.fps)));
2263
+ tick.unref();
2264
+ };
2246
2265
  const encoder = new _camstack_types_node.FfmpegProcess({
2247
2266
  binaryPath: ctx.binaryPath,
2248
2267
  buildArgs: () => require_dist.buildFfmpegArgs(gridCanvasEncoderInvocation({
@@ -2266,34 +2285,26 @@ async function startGridCompositorChild(ctx, plan, sources, onEnded) {
2266
2285
  onChild: (child) => {
2267
2286
  encoderIn = child.stdin;
2268
2287
  if (child.stdout) encoderOut = child.stdout;
2288
+ child.stdin?.on("drain", () => {
2289
+ draining = false;
2290
+ });
2291
+ startTick();
2269
2292
  child.stderr?.on("data", () => {});
2270
2293
  child.stdin?.on("error", () => {});
2271
2294
  },
2272
2295
  onExit: (exit) => end(`encoder:${exit.classification}`)
2273
2296
  });
2274
- await encoder.start();
2297
+ try {
2298
+ await encoder.start();
2299
+ } catch (error) {
2300
+ if (tick !== null) clearInterval(tick);
2301
+ compositor.close();
2302
+ throw error;
2303
+ }
2275
2304
  if (encoderIn === null || encoderOut === null) {
2276
2305
  await encoder.stop();
2277
2306
  throw new Error("camera-grid: the canvas encoder exposed no stdin/stdout to compose into");
2278
2307
  }
2279
- let draining = false;
2280
- const sink = encoderIn;
2281
- sink.on("drain", () => {
2282
- draining = false;
2283
- });
2284
- const compositor = new GridCompositor({
2285
- plan: tilePlan,
2286
- write: (frame) => {
2287
- if (draining || sink.destroyed) return false;
2288
- const accepted = sink.write(frame);
2289
- if (!accepted) draining = true;
2290
- return accepted;
2291
- }
2292
- });
2293
- const tick = setInterval(() => {
2294
- compositor.tick();
2295
- }, Math.max(1, Math.round(1e3 / plan.fps)));
2296
- tick.unref();
2297
2308
  const urlByDeviceId = /* @__PURE__ */ new Map();
2298
2309
  for (const [index, deviceId] of plan.sourceDeviceIds.entries()) {
2299
2310
  const url = sources[index]?.url;
@@ -2333,7 +2344,7 @@ async function startGridCompositorChild(ctx, plan, sources, onEnded) {
2333
2344
  await decoder.start();
2334
2345
  };
2335
2346
  const stopAll = async () => {
2336
- clearInterval(tick);
2347
+ if (tick !== null) clearInterval(tick);
2337
2348
  compositor.close();
2338
2349
  await Promise.allSettled(decoders.map((d) => d.stop()));
2339
2350
  await encoder.stop();
@@ -2238,6 +2238,25 @@ async function startGridCompositorChild(ctx, plan, sources, onEnded) {
2238
2238
  };
2239
2239
  let encoderIn = null;
2240
2240
  let encoderOut = null;
2241
+ let draining = false;
2242
+ let tick = null;
2243
+ const compositor = new GridCompositor({
2244
+ plan: tilePlan,
2245
+ write: (frame) => {
2246
+ const sink = encoderIn;
2247
+ if (sink === null || draining || sink.destroyed) return false;
2248
+ const accepted = sink.write(frame);
2249
+ if (!accepted) draining = true;
2250
+ return accepted;
2251
+ }
2252
+ });
2253
+ const startTick = () => {
2254
+ if (tick !== null) return;
2255
+ tick = setInterval(() => {
2256
+ compositor.tick();
2257
+ }, Math.max(1, Math.round(1e3 / plan.fps)));
2258
+ tick.unref();
2259
+ };
2241
2260
  const encoder = new FfmpegProcess({
2242
2261
  binaryPath: ctx.binaryPath,
2243
2262
  buildArgs: () => buildFfmpegArgs(gridCanvasEncoderInvocation({
@@ -2261,34 +2280,26 @@ async function startGridCompositorChild(ctx, plan, sources, onEnded) {
2261
2280
  onChild: (child) => {
2262
2281
  encoderIn = child.stdin;
2263
2282
  if (child.stdout) encoderOut = child.stdout;
2283
+ child.stdin?.on("drain", () => {
2284
+ draining = false;
2285
+ });
2286
+ startTick();
2264
2287
  child.stderr?.on("data", () => {});
2265
2288
  child.stdin?.on("error", () => {});
2266
2289
  },
2267
2290
  onExit: (exit) => end(`encoder:${exit.classification}`)
2268
2291
  });
2269
- await encoder.start();
2292
+ try {
2293
+ await encoder.start();
2294
+ } catch (error) {
2295
+ if (tick !== null) clearInterval(tick);
2296
+ compositor.close();
2297
+ throw error;
2298
+ }
2270
2299
  if (encoderIn === null || encoderOut === null) {
2271
2300
  await encoder.stop();
2272
2301
  throw new Error("camera-grid: the canvas encoder exposed no stdin/stdout to compose into");
2273
2302
  }
2274
- let draining = false;
2275
- const sink = encoderIn;
2276
- sink.on("drain", () => {
2277
- draining = false;
2278
- });
2279
- const compositor = new GridCompositor({
2280
- plan: tilePlan,
2281
- write: (frame) => {
2282
- if (draining || sink.destroyed) return false;
2283
- const accepted = sink.write(frame);
2284
- if (!accepted) draining = true;
2285
- return accepted;
2286
- }
2287
- });
2288
- const tick = setInterval(() => {
2289
- compositor.tick();
2290
- }, Math.max(1, Math.round(1e3 / plan.fps)));
2291
- tick.unref();
2292
2303
  const urlByDeviceId = /* @__PURE__ */ new Map();
2293
2304
  for (const [index, deviceId] of plan.sourceDeviceIds.entries()) {
2294
2305
  const url = sources[index]?.url;
@@ -2328,7 +2339,7 @@ async function startGridCompositorChild(ctx, plan, sources, onEnded) {
2328
2339
  await decoder.start();
2329
2340
  };
2330
2341
  const stopAll = async () => {
2331
- clearInterval(tick);
2342
+ if (tick !== null) clearInterval(tick);
2332
2343
  compositor.close();
2333
2344
  await Promise.allSettled(decoders.map((d) => d.stop()));
2334
2345
  await encoder.stop();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.265",
3
+ "version": "1.2.266",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",