@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/README.md +1 -0
- package/dist/index.cjs +35 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 {
|