@furious.luke/argus-js 0.5.1 → 0.5.2

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.
package/dist/index.d.cts CHANGED
@@ -189,6 +189,16 @@ interface PublisherOptions {
189
189
  gatewayHandshakeTimeoutMs?: number;
190
190
  /** Deadline after the initial offer for WebRTC to reach connected. Defaults to 30 seconds. */
191
191
  peerConnectionTimeoutMs?: number;
192
+ /**
193
+ * Preferred video codecs, most-preferred first, as RTP MIME types (e.g.
194
+ * `"video/VP9"`, `"video/VP8"`, `"video/H264"`). Each published video track's
195
+ * transceiver offers these codecs ahead of the rest, so the browser sends the
196
+ * first one the media server also accepts. Codecs the browser supports but that
197
+ * are not listed keep their default order behind the preferred ones, so
198
+ * negotiation still falls back cleanly. Defaults to `["video/VP9"]`. Pass an
199
+ * empty array to leave the browser's native codec order untouched.
200
+ */
201
+ preferredVideoCodecs?: string[];
192
202
  /** How long to retry a dropped signaling connection to the selected gateway. Defaults to 20 seconds. */
193
203
  signalingReconnectTimeoutMs?: number;
194
204
  /** Callbacks for lifecycle events. */
@@ -447,6 +457,20 @@ declare class Publisher {
447
457
  * the server's outbound speech sender on the dedicated speech transceiver.
448
458
  */
449
459
  private addMicrophoneTrack;
460
+ /**
461
+ * Reorders the codecs a video sender offers so the browser prefers the
462
+ * configured codecs (VP9 by default). This is what actually controls the wire
463
+ * format: the browser is the offerer and sends its own top-of-offer codec, and
464
+ * the media server (Pion) answers by mirroring the offer's codec order — so the
465
+ * server's own registration order has no say. Floating VP9 to the front of the
466
+ * offer is therefore the lever. Codecs not in the preference keep their native
467
+ * order behind it, so anything VP9 can't satisfy still negotiates.
468
+ *
469
+ * Best-effort: browsers lacking `getCapabilities`/`setCodecPreferences` (older
470
+ * Safari) keep their default order, and any failure is swallowed — codec
471
+ * preference is an optimization, never a requirement for publishing.
472
+ */
473
+ private preferVideoCodecs;
450
474
  /** Registers one physical video track under its logical type and source stream. */
451
475
  private registerTrack;
452
476
  /** The live video tracks currently published under the given type. */
package/dist/index.d.ts CHANGED
@@ -189,6 +189,16 @@ interface PublisherOptions {
189
189
  gatewayHandshakeTimeoutMs?: number;
190
190
  /** Deadline after the initial offer for WebRTC to reach connected. Defaults to 30 seconds. */
191
191
  peerConnectionTimeoutMs?: number;
192
+ /**
193
+ * Preferred video codecs, most-preferred first, as RTP MIME types (e.g.
194
+ * `"video/VP9"`, `"video/VP8"`, `"video/H264"`). Each published video track's
195
+ * transceiver offers these codecs ahead of the rest, so the browser sends the
196
+ * first one the media server also accepts. Codecs the browser supports but that
197
+ * are not listed keep their default order behind the preferred ones, so
198
+ * negotiation still falls back cleanly. Defaults to `["video/VP9"]`. Pass an
199
+ * empty array to leave the browser's native codec order untouched.
200
+ */
201
+ preferredVideoCodecs?: string[];
192
202
  /** How long to retry a dropped signaling connection to the selected gateway. Defaults to 20 seconds. */
193
203
  signalingReconnectTimeoutMs?: number;
194
204
  /** Callbacks for lifecycle events. */
@@ -447,6 +457,20 @@ declare class Publisher {
447
457
  * the server's outbound speech sender on the dedicated speech transceiver.
448
458
  */
449
459
  private addMicrophoneTrack;
460
+ /**
461
+ * Reorders the codecs a video sender offers so the browser prefers the
462
+ * configured codecs (VP9 by default). This is what actually controls the wire
463
+ * format: the browser is the offerer and sends its own top-of-offer codec, and
464
+ * the media server (Pion) answers by mirroring the offer's codec order — so the
465
+ * server's own registration order has no say. Floating VP9 to the front of the
466
+ * offer is therefore the lever. Codecs not in the preference keep their native
467
+ * order behind it, so anything VP9 can't satisfy still negotiates.
468
+ *
469
+ * Best-effort: browsers lacking `getCapabilities`/`setCodecPreferences` (older
470
+ * Safari) keep their default order, and any failure is swallowed — codec
471
+ * preference is an optimization, never a requirement for publishing.
472
+ */
473
+ private preferVideoCodecs;
450
474
  /** Registers one physical video track under its logical type and source stream. */
451
475
  private registerTrack;
452
476
  /** The live video tracks currently published under the given type. */
package/dist/index.js CHANGED
@@ -341,6 +341,7 @@ var Publisher = class {
341
341
  };
342
342
  if (initialTrack) {
343
343
  const sender = initialTrack.type === "audio" ? this.addMicrophoneTrack(pc, initialTrack.track, initialTrack.stream) : pc.addTrack(initialTrack.track, initialTrack.stream);
344
+ if (initialTrack.type !== "audio") this.preferVideoCodecs(pc, sender);
344
345
  this.typeSenders.set(
345
346
  initialTrack.type,
346
347
  sender
@@ -1551,6 +1552,39 @@ var Publisher = class {
1551
1552
  this.microphoneTransceiver = transceiver;
1552
1553
  return transceiver.sender;
1553
1554
  }
1555
+ /**
1556
+ * Reorders the codecs a video sender offers so the browser prefers the
1557
+ * configured codecs (VP9 by default). This is what actually controls the wire
1558
+ * format: the browser is the offerer and sends its own top-of-offer codec, and
1559
+ * the media server (Pion) answers by mirroring the offer's codec order — so the
1560
+ * server's own registration order has no say. Floating VP9 to the front of the
1561
+ * offer is therefore the lever. Codecs not in the preference keep their native
1562
+ * order behind it, so anything VP9 can't satisfy still negotiates.
1563
+ *
1564
+ * Best-effort: browsers lacking `getCapabilities`/`setCodecPreferences` (older
1565
+ * Safari) keep their default order, and any failure is swallowed — codec
1566
+ * preference is an optimization, never a requirement for publishing.
1567
+ */
1568
+ preferVideoCodecs(pc, sender) {
1569
+ const preferred = this.opts.preferredVideoCodecs ?? ["video/VP9"];
1570
+ if (preferred.length === 0) return;
1571
+ if (sender.track && sender.track.kind !== "video") return;
1572
+ if (typeof RTCRtpSender === "undefined" || typeof RTCRtpSender.getCapabilities !== "function") return;
1573
+ if (typeof pc.getTransceivers !== "function") return;
1574
+ const caps = RTCRtpSender.getCapabilities("video");
1575
+ if (!caps?.codecs) return;
1576
+ const transceiver = pc.getTransceivers().find((t) => t.sender === sender);
1577
+ if (!transceiver || typeof transceiver.setCodecPreferences !== "function") return;
1578
+ const rank = (mimeType) => {
1579
+ const idx = preferred.findIndex((p) => p.toLowerCase() === mimeType.toLowerCase());
1580
+ return idx === -1 ? preferred.length : idx;
1581
+ };
1582
+ const ordered = caps.codecs.map((codec, index) => ({ codec, index })).sort((a, b) => rank(a.codec.mimeType) - rank(b.codec.mimeType) || a.index - b.index).map((entry) => entry.codec);
1583
+ try {
1584
+ transceiver.setCodecPreferences(ordered);
1585
+ } catch {
1586
+ }
1587
+ }
1554
1588
  /** Registers one physical video track under its logical type and source stream. */
1555
1589
  registerTrack(track, stream, type) {
1556
1590
  this.published.set(track, type);
@@ -1624,6 +1658,7 @@ var Publisher = class {
1624
1658
  throw new SenderRestoreError(`inactive ${type} sender still has a track`);
1625
1659
  }
1626
1660
  addedSender = pc.addTrack(track, stream);
1661
+ this.preferVideoCodecs(pc, addedSender);
1627
1662
  this.typeSenders.set(type, addedSender);
1628
1663
  }
1629
1664
  return {