@livepeer-frameworks/streamcrafter-core 0.0.2 → 0.1.0

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.
Files changed (43) hide show
  1. package/README.md +24 -1
  2. package/dist/cjs/IngestControllerV2-BSD6O8gz.cjs +5662 -0
  3. package/dist/cjs/IngestControllerV2-BSD6O8gz.cjs.map +1 -0
  4. package/dist/cjs/IngestControllerV2-DZFuxrNk.cjs +5768 -0
  5. package/dist/cjs/IngestControllerV2-DZFuxrNk.cjs.map +1 -0
  6. package/dist/cjs/IngestControllerV2-Mt6aX-DU.cjs +5768 -0
  7. package/dist/cjs/IngestControllerV2-Mt6aX-DU.cjs.map +1 -0
  8. package/dist/cjs/index.cjs +60 -5
  9. package/dist/cjs/index.cjs.map +1 -1
  10. package/dist/cjs/vanilla.cjs +1 -1
  11. package/dist/cjs/vanilla.cjs.map +1 -1
  12. package/dist/esm/IngestControllerV2-BaOxEiTq.js +5606 -0
  13. package/dist/esm/IngestControllerV2-BaOxEiTq.js.map +1 -0
  14. package/dist/esm/IngestControllerV2-DswB_ybx.js +5712 -0
  15. package/dist/esm/IngestControllerV2-DswB_ybx.js.map +1 -0
  16. package/dist/esm/IngestControllerV2-fiwB1xzE.js +5712 -0
  17. package/dist/esm/IngestControllerV2-fiwB1xzE.js.map +1 -0
  18. package/dist/esm/index.js +61 -6
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/vanilla.js +1 -1
  21. package/dist/esm/vanilla.js.map +1 -1
  22. package/dist/types/core/EncoderManager.d.ts +6 -0
  23. package/dist/types/core/IngestControllerV2.d.ts +7 -0
  24. package/dist/types/core/SceneManager.d.ts +6 -0
  25. package/dist/types/core/WhipClient.d.ts +1 -0
  26. package/dist/types/core/renderers/Canvas2DRenderer.d.ts +1 -0
  27. package/dist/types/core/renderers/WebGLRenderer.d.ts +1 -0
  28. package/dist/types/core/renderers/WebGPURenderer.d.ts +3 -0
  29. package/dist/types/core/renderers/index.d.ts +5 -0
  30. package/dist/types/types.d.ts +5 -0
  31. package/dist/workers/compositor.worker.js +92 -5
  32. package/dist/workers/compositor.worker.js.map +1 -1
  33. package/dist/workers/encoder.worker.js +2 -2
  34. package/dist/workers/encoder.worker.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/core/EncoderManager.ts +63 -1
  37. package/src/core/IngestControllerV2.ts +114 -98
  38. package/src/core/SceneManager.ts +16 -3
  39. package/src/core/WhipClient.ts +26 -0
  40. package/src/core/renderers/WebGPURenderer.ts +1 -1
  41. package/src/vanilla/StreamCrafterV2.ts +0 -1
  42. package/src/workers/compositor.worker.ts +1 -2
  43. package/src/workers/encoder.worker.ts +2 -2
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TypedEventEmitter } from './IngestControllerV2-BWfseZYs.js';
2
- export { A as AudioMixer, b as DEFAULT_AUDIO_SETTINGS, _ as DEFAULT_COMPOSITOR_CONFIG, $ as DEFAULT_LAYER_TRANSFORM, d as DEFAULT_RECONNECTION_CONFIG, a as DEFAULT_VIDEO_SETTINGS, D as DeviceManager, E as EncoderManager, I as IngestController, I as IngestControllerV2, P as LAYOUT_PRESETS, R as ReconnectionManager, w as SceneManager, S as ScreenCapture, x as TransitionEngine, W as WhipClient, Q as applyFullscreenLayout, J as applyLayout, U as applyPipLayout, V as applySideBySideLayout, t as buildMediaConstraints, z as createCutTransition, K as createDefaultLayoutConfig, y as createDefaultTransitionConfig, c as createEncoderConfig, B as createFadeTransition, X as createPipLayoutConfig, Y as createSideBySideLayoutConfig, C as createSlideTransition, e as detectCapabilities, q as getAudioConstraints, G as getAvailableEasingTypes, Z as getAvailableLayoutModes, M as getAvailablePresets, s as getAvailableProfiles, F as getAvailableTransitionTypes, v as getEncoderSettings, L as getLayoutPresets, N as getMinSourcesForLayout, l as getRecommendedPath, p as getSupportedAudioCodecs, o as getSupportedVideoCodecs, r as getVideoConstraints, n as isAudioCodecSupported, O as isLayoutAvailable, g as isMediaDevicesSupported, j as isRTCRtpScriptTransformSupported, h as isScreenCaptureSupported, m as isVideoCodecSupported, k as isWebCodecsEncodingPathSupported, i as isWebCodecsSupported, f as isWebRTCSupported, u as mergeWithCustomConstraints, H as validateTransitionConfig } from './IngestControllerV2-BWfseZYs.js';
1
+ import { T as TypedEventEmitter } from './IngestControllerV2-fiwB1xzE.js';
2
+ export { A as AudioMixer, b as DEFAULT_AUDIO_SETTINGS, _ as DEFAULT_COMPOSITOR_CONFIG, $ as DEFAULT_LAYER_TRANSFORM, d as DEFAULT_RECONNECTION_CONFIG, a as DEFAULT_VIDEO_SETTINGS, D as DeviceManager, E as EncoderManager, I as IngestController, I as IngestControllerV2, P as LAYOUT_PRESETS, R as ReconnectionManager, w as SceneManager, S as ScreenCapture, x as TransitionEngine, W as WhipClient, Q as applyFullscreenLayout, J as applyLayout, U as applyPipLayout, V as applySideBySideLayout, t as buildMediaConstraints, z as createCutTransition, K as createDefaultLayoutConfig, y as createDefaultTransitionConfig, c as createEncoderConfig, B as createFadeTransition, X as createPipLayoutConfig, Y as createSideBySideLayoutConfig, C as createSlideTransition, e as detectCapabilities, q as getAudioConstraints, G as getAvailableEasingTypes, Z as getAvailableLayoutModes, M as getAvailablePresets, s as getAvailableProfiles, F as getAvailableTransitionTypes, v as getEncoderSettings, L as getLayoutPresets, N as getMinSourcesForLayout, l as getRecommendedPath, p as getSupportedAudioCodecs, o as getSupportedVideoCodecs, r as getVideoConstraints, n as isAudioCodecSupported, O as isLayoutAvailable, g as isMediaDevicesSupported, j as isRTCRtpScriptTransformSupported, h as isScreenCaptureSupported, m as isVideoCodecSupported, k as isWebCodecsEncodingPathSupported, i as isWebCodecsSupported, f as isWebRTCSupported, u as mergeWithCustomConstraints, H as validateTransitionConfig } from './IngestControllerV2-fiwB1xzE.js';
3
3
 
4
4
  /**
5
5
  * IngestClient - Resolves ingest endpoints via Gateway
@@ -328,6 +328,20 @@ class Canvas2DRenderer {
328
328
  this.lastRenderTime = performance.now() - startTime;
329
329
  this.updateStats();
330
330
  }
331
+ resize(config) {
332
+ this.config = config;
333
+ const ctx = this.canvas.getContext('2d', {
334
+ desynchronized: true,
335
+ alpha: false,
336
+ willReadFrequently: false,
337
+ });
338
+ if (!ctx) {
339
+ throw new Error('Failed to get 2D context from OffscreenCanvas');
340
+ }
341
+ this.ctx = ctx;
342
+ this.ctx.imageSmoothingEnabled = true;
343
+ this.ctx.imageSmoothingQuality = 'high';
344
+ }
331
345
  renderLayer(layer, frame) {
332
346
  const { x, y, width, height, opacity, rotation, borderRadius, crop } = layer.transform;
333
347
  const scalingMode = layer.scalingMode || 'letterbox';
@@ -894,6 +908,12 @@ class WebGLRenderer {
894
908
  this.lastRenderTime = performance.now() - startTime;
895
909
  this.updateStats();
896
910
  }
911
+ resize(config) {
912
+ this.config = config;
913
+ if (this.gl) {
914
+ this.gl.viewport(0, 0, config.width, config.height);
915
+ }
916
+ }
897
917
  updateTextures(frames) {
898
918
  const gl = this.gl;
899
919
  for (const [sourceId, frame] of frames) {
@@ -1339,9 +1359,11 @@ class WebGPURenderer {
1339
1359
  // Textures and bind groups per source
1340
1360
  this.textures = new Map();
1341
1361
  this.bindGroups = new Map();
1362
+ this.bindGroupTextures = new Map();
1342
1363
  this.uniformBuffers = new Map();
1343
1364
  // Sampler
1344
1365
  this.sampler = null;
1366
+ this.presentationFormat = null;
1345
1367
  // Stats tracking
1346
1368
  this.frameCount = 0;
1347
1369
  this.lastFrameTime = 0;
@@ -1368,6 +1390,7 @@ class WebGPURenderer {
1368
1390
  throw new Error('Failed to get WebGPU context');
1369
1391
  }
1370
1392
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
1393
+ this.presentationFormat = presentationFormat;
1371
1394
  this.context.configure({
1372
1395
  device: this.device,
1373
1396
  format: presentationFormat,
@@ -1526,6 +1549,16 @@ class WebGPURenderer {
1526
1549
  this.lastRenderTime = performance.now() - startTime;
1527
1550
  this.updateStats();
1528
1551
  }
1552
+ resize(config) {
1553
+ this.config = config;
1554
+ if (this.context && this.device && this.presentationFormat) {
1555
+ this.context.configure({
1556
+ device: this.device,
1557
+ format: this.presentationFormat,
1558
+ alphaMode: 'premultiplied',
1559
+ });
1560
+ }
1561
+ }
1529
1562
  updateTextures(frames) {
1530
1563
  if (!this.device)
1531
1564
  return;
@@ -1536,7 +1569,26 @@ class WebGPURenderer {
1536
1569
  // Create or recreate texture if size changed
1537
1570
  if (!texture || texture.width !== width || texture.height !== height) {
1538
1571
  if (texture) {
1539
- texture.destroy();
1572
+ const oldTexture = texture;
1573
+ // Defer destruction until GPU work is done to avoid validation errors.
1574
+ this.device.queue
1575
+ .onSubmittedWorkDone()
1576
+ .then(() => {
1577
+ try {
1578
+ oldTexture.destroy();
1579
+ }
1580
+ catch {
1581
+ // Ignore destroy errors
1582
+ }
1583
+ })
1584
+ .catch(() => {
1585
+ try {
1586
+ oldTexture.destroy();
1587
+ }
1588
+ catch {
1589
+ // Ignore destroy errors
1590
+ }
1591
+ });
1540
1592
  }
1541
1593
  texture = this.device.createTexture({
1542
1594
  size: { width, height },
@@ -1546,8 +1598,8 @@ class WebGPURenderer {
1546
1598
  GPUTextureUsage.RENDER_ATTACHMENT,
1547
1599
  });
1548
1600
  this.textures.set(sourceId, texture);
1549
- // Invalidate bind group since texture changed
1550
- this.bindGroups.delete(sourceId);
1601
+ // Bind groups are keyed by layer id; rebind when a layer requests this source.
1602
+ // We keep cached bind groups and replace them on demand in getOrCreateBindGroup.
1551
1603
  }
1552
1604
  // Copy frame to texture
1553
1605
  if (frame instanceof ImageBitmap) {
@@ -1565,8 +1617,9 @@ class WebGPURenderer {
1565
1617
  const texture = this.textures.get(layer.sourceId);
1566
1618
  if (!texture)
1567
1619
  return null;
1620
+ const cachedTexture = this.bindGroupTextures.get(layer.id);
1568
1621
  let bindGroup = this.bindGroups.get(layer.id);
1569
- if (!bindGroup) {
1622
+ if (!bindGroup || cachedTexture !== texture) {
1570
1623
  // Create uniform buffer for this layer
1571
1624
  let uniformBuffer = this.uniformBuffers.get(layer.id);
1572
1625
  if (!uniformBuffer) {
@@ -1585,6 +1638,7 @@ class WebGPURenderer {
1585
1638
  ],
1586
1639
  });
1587
1640
  this.bindGroups.set(layer.id, bindGroup);
1641
+ this.bindGroupTextures.set(layer.id, texture);
1588
1642
  }
1589
1643
  return bindGroup;
1590
1644
  }
@@ -1815,6 +1869,7 @@ class WebGPURenderer {
1815
1869
  this.indexBuffer?.destroy();
1816
1870
  // Clear bind groups (they reference destroyed resources)
1817
1871
  this.bindGroups.clear();
1872
+ this.bindGroupTextures.clear();
1818
1873
  // Device will be garbage collected
1819
1874
  this.device = null;
1820
1875
  this.context = null;