moqtail 0.8.1 → 0.9.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.
package/dist/index.cjs CHANGED
@@ -1,11 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var Heap = require('heap-js');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var Heap__default = /*#__PURE__*/_interopDefault(Heap);
8
-
9
3
  var __defProp = Object.defineProperty;
10
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
11
5
  var __esm = (fn, res) => function __init() {
@@ -4540,6 +4534,219 @@ init_byte_buffer();
4540
4534
  init_error();
4541
4535
  init_constant2();
4542
4536
 
4537
+ // src/model/catalog/cmsf.ts
4538
+ function isString(v) {
4539
+ return typeof v === "string";
4540
+ }
4541
+ function isNumber(v) {
4542
+ return typeof v === "number";
4543
+ }
4544
+ function isStringArray(v) {
4545
+ return Array.isArray(v) && v.every((item) => isString(item));
4546
+ }
4547
+ function isValidPackaging(v) {
4548
+ return v === "cmaf" || v === "chunk-per-object" || v === "timeline";
4549
+ }
4550
+ function isValidRole(v) {
4551
+ return v === "video" || v === "audio" || v === "timeline";
4552
+ }
4553
+ function isValidBase64(str) {
4554
+ try {
4555
+ return btoa(atob(str)) === str;
4556
+ } catch {
4557
+ return false;
4558
+ }
4559
+ }
4560
+ function validateTrack(track) {
4561
+ if (typeof track !== "object" || track === null) {
4562
+ throw new Error("Track must be an object");
4563
+ }
4564
+ const t = track;
4565
+ if (!isString(t["name"])) {
4566
+ throw new Error("Track.name must be a string");
4567
+ }
4568
+ if (!isValidPackaging(t["packaging"])) {
4569
+ throw new Error("Track.packaging must be 'cmaf', 'chunk-per-object', or 'timeline'");
4570
+ }
4571
+ if (!isValidRole(t["role"])) {
4572
+ throw new Error("Track.role must be 'video', 'audio', or 'timeline'");
4573
+ }
4574
+ const name = t["name"];
4575
+ const packaging = t["packaging"];
4576
+ const role = t["role"];
4577
+ let codec;
4578
+ if (t["codec"] !== void 0) {
4579
+ if (!isString(t["codec"])) {
4580
+ throw new Error("Track.codec must be a string");
4581
+ }
4582
+ codec = t["codec"];
4583
+ }
4584
+ let depends;
4585
+ if (t["depends"] !== void 0) {
4586
+ if (!isStringArray(t["depends"])) {
4587
+ throw new Error("Track.depends must be an array of strings");
4588
+ }
4589
+ depends = t["depends"];
4590
+ }
4591
+ let mimeType;
4592
+ if (t["mimeType"] !== void 0) {
4593
+ if (!isString(t["mimeType"])) {
4594
+ throw new Error("Track.mimeType must be a string");
4595
+ }
4596
+ mimeType = t["mimeType"];
4597
+ }
4598
+ let width;
4599
+ if (t["width"] !== void 0) {
4600
+ if (!isNumber(t["width"])) {
4601
+ throw new Error("Track.width must be a number");
4602
+ }
4603
+ width = t["width"];
4604
+ }
4605
+ let height;
4606
+ if (t["height"] !== void 0) {
4607
+ if (!isNumber(t["height"])) {
4608
+ throw new Error("Track.height must be a number");
4609
+ }
4610
+ height = t["height"];
4611
+ }
4612
+ let timescale;
4613
+ if (t["timescale"] !== void 0) {
4614
+ if (!isNumber(t["timescale"])) {
4615
+ throw new Error("Track.timescale must be a number");
4616
+ }
4617
+ timescale = t["timescale"];
4618
+ }
4619
+ let bitrate;
4620
+ if (t["bitrate"] !== void 0) {
4621
+ if (!isNumber(t["bitrate"])) {
4622
+ throw new Error("Track.bitrate must be a number");
4623
+ }
4624
+ bitrate = t["bitrate"];
4625
+ }
4626
+ let initData;
4627
+ if (t["initData"] !== void 0) {
4628
+ if (!isString(t["initData"])) {
4629
+ throw new Error("Track.initData must be a string");
4630
+ }
4631
+ if (!isValidBase64(t["initData"])) {
4632
+ throw new Error("Track.initData must be a valid base64 string");
4633
+ }
4634
+ initData = t["initData"];
4635
+ }
4636
+ if (packaging === "cmaf" && (!codec || codec.length === 0)) {
4637
+ throw new Error("codec is required when packaging is 'cmaf'");
4638
+ }
4639
+ if (packaging === "timeline" && mimeType !== "text/csv") {
4640
+ throw new Error("mimeType must be 'text/csv' when packaging is 'timeline'");
4641
+ }
4642
+ if (packaging === "timeline" && (!depends || depends.length === 0)) {
4643
+ throw new Error("At least one dependee must be present when packaging is 'timeline'");
4644
+ }
4645
+ const result = {
4646
+ name,
4647
+ packaging,
4648
+ role
4649
+ };
4650
+ if (codec !== void 0) result.codec = codec;
4651
+ if (depends !== void 0) result.depends = depends;
4652
+ if (mimeType !== void 0) result.mimeType = mimeType;
4653
+ if (width !== void 0) result.width = width;
4654
+ if (height !== void 0) result.height = height;
4655
+ if (timescale !== void 0) result.timescale = timescale;
4656
+ if (bitrate !== void 0) result.bitrate = bitrate;
4657
+ if (initData !== void 0) result.initData = initData;
4658
+ return result;
4659
+ }
4660
+ function validateCMSF(obj) {
4661
+ if (typeof obj !== "object" || obj === null) {
4662
+ throw new Error("CMSF must be an object");
4663
+ }
4664
+ const o = obj;
4665
+ if (!isNumber(o["version"])) {
4666
+ throw new Error("CMSF.version must be a number");
4667
+ }
4668
+ if (!Array.isArray(o["tracks"])) {
4669
+ throw new Error("CMSF.tracks must be an array");
4670
+ }
4671
+ const version = o["version"];
4672
+ const tracksArray = o["tracks"];
4673
+ const tracks = tracksArray.map(validateTrack);
4674
+ return {
4675
+ version,
4676
+ tracks
4677
+ };
4678
+ }
4679
+ var CMSFCatalog = class _CMSFCatalog {
4680
+ #catalog;
4681
+ constructor(catalog) {
4682
+ this.#catalog = catalog;
4683
+ }
4684
+ static from(payload) {
4685
+ const decoder = new TextDecoder();
4686
+ const json = decoder.decode(payload);
4687
+ const catalog = validateCMSF(JSON.parse(json));
4688
+ return new _CMSFCatalog(catalog);
4689
+ }
4690
+ getByTrackName(trackName) {
4691
+ return this.#catalog.tracks.find((track) => track.name === this.extractTrackName(trackName));
4692
+ }
4693
+ getTracks(role) {
4694
+ if (role) return this.#catalog.tracks.filter((track) => track.role === role);
4695
+ return this.#catalog.tracks;
4696
+ }
4697
+ getVideo(index = 0) {
4698
+ const videos = this.#catalog.tracks.filter((track) => track.role === "video");
4699
+ if (index < 0 || index >= videos.length) return void 0;
4700
+ return videos[index];
4701
+ }
4702
+ getAudio(index = 0) {
4703
+ const audios = this.#catalog.tracks.filter((track) => track.role === "audio");
4704
+ if (index < 0 || index >= audios.length) return void 0;
4705
+ return audios[index];
4706
+ }
4707
+ getTimeline(index = 0) {
4708
+ const timelines = this.#catalog.tracks.filter((track) => track.role === "timeline");
4709
+ if (index < 0 || index >= timelines.length) return void 0;
4710
+ return timelines[index];
4711
+ }
4712
+ getCodecString(trackName) {
4713
+ const track = this.#catalog.tracks.find((track2) => track2.name === this.extractTrackName(trackName));
4714
+ if (!track) return void 0;
4715
+ if (!track.codec) throw new Error(`Track ${trackName} does not have a codec`);
4716
+ return track.codec;
4717
+ }
4718
+ getRole(trackName) {
4719
+ const track = this.#catalog.tracks.find((track2) => track2.name === this.extractTrackName(trackName));
4720
+ if (!track) return void 0;
4721
+ return track.role;
4722
+ }
4723
+ getPackaging(trackName) {
4724
+ const track = this.#catalog.tracks.find((track2) => track2.name === this.extractTrackName(trackName));
4725
+ if (!track) return void 0;
4726
+ return track.packaging;
4727
+ }
4728
+ isCMAF(trackName) {
4729
+ const packaging = this.getPackaging(trackName);
4730
+ return packaging === "cmaf" || packaging === "chunk-per-object";
4731
+ }
4732
+ getTimescale(trackName) {
4733
+ const track = this.#catalog.tracks.find((track2) => track2.name === this.extractTrackName(trackName));
4734
+ return track?.timescale;
4735
+ }
4736
+ getInitData(trackName) {
4737
+ const track = this.#catalog.tracks.find((track2) => track2.name === this.extractTrackName(trackName));
4738
+ if (!track) return void 0;
4739
+ if (!track.initData) throw new Error(`Track ${trackName} does not have initData`);
4740
+ return new Uint8Array(
4741
+ atob(track.initData).split("").map((c) => c.charCodeAt(0))
4742
+ );
4743
+ }
4744
+ extractTrackName(input) {
4745
+ const parts = input.split("/");
4746
+ return parts[parts.length - 1];
4747
+ }
4748
+ };
4749
+
4543
4750
  // src/model/control/switch.ts
4544
4751
  init_byte_buffer();
4545
4752
  init_pair();
@@ -6177,13 +6384,13 @@ var handlerSubscribeNamespaceOk = async (_client, _msg) => {
6177
6384
  };
6178
6385
 
6179
6386
  // src/client/handler/publish_done.ts
6180
- init_error2();
6181
6387
  var handlerPublishDone = async (client, msg) => {
6388
+ if (client.onPeerPublishDone) {
6389
+ client.onPeerPublishDone(msg);
6390
+ }
6182
6391
  const request = client.requests.get(msg.requestId);
6183
6392
  if (request instanceof SubscribeRequest) {
6184
6393
  request.expectedStreams = msg.streamCount;
6185
- } else {
6186
- throw new exports.ProtocolViolationError("handlerPublishDone", "No publish request was found with the given request id");
6187
6394
  }
6188
6395
  };
6189
6396
 
@@ -6273,17 +6480,6 @@ var handlerPublish = async (client, msg) => {
6273
6480
  if (client.onPeerPublish) {
6274
6481
  client.onPeerPublish(msg, stream);
6275
6482
  }
6276
- const publishOk = new PublishOk(
6277
- msg.requestId,
6278
- 1,
6279
- 255,
6280
- 1 /* Ascending */,
6281
- 2 /* LatestObject */,
6282
- void 0,
6283
- void 0,
6284
- []
6285
- );
6286
- await client.controlStream.send(publishOk);
6287
6483
  };
6288
6484
 
6289
6485
  // src/client/publication/publish.ts
@@ -6805,6 +7001,8 @@ var MOQtailClient = class _MOQtailClient {
6805
7001
  onDatagramSent;
6806
7002
  /** Fired when an inbound PUBLISH control message is received. */
6807
7003
  onPeerPublish;
7004
+ /** Fired when an inbound PUBLISH_DONE control message is received. */
7005
+ onPeerPublishDone;
6808
7006
  /** Fired when an inbound SUBSCRIBE_NAMESPACE control message is received. */
6809
7007
  onPeerSubscribeNamespace;
6810
7008
  /** Datagram writer for sending datagrams. */
@@ -7886,6 +8084,26 @@ var MOQtailClient = class _MOQtailClient {
7886
8084
  throw error;
7887
8085
  }
7888
8086
  }
8087
+ /**
8088
+ * Signals the end of a published track to the peer/relay.
8089
+ * * @param publishRequestId - The original requestId used when `publish()` was called.
8090
+ */
8091
+ async publishDone(publishRequestId, statusCode = 0, reasonPhrase = "Track Ended") {
8092
+ this.#ensureActive();
8093
+ try {
8094
+ if (typeof publishRequestId === "number") publishRequestId = BigInt(publishRequestId);
8095
+ const msg = new PublishDone(publishRequestId, statusCode, 0n, new exports.ReasonPhrase(reasonPhrase));
8096
+ await this.controlStream.send(msg);
8097
+ this.requests.delete(publishRequestId);
8098
+ this.requestIdMap.removeMappingByRequestId(publishRequestId);
8099
+ this.subscriptionAliasMap.delete(publishRequestId);
8100
+ } catch (error) {
8101
+ await this.disconnect(
8102
+ new exports.InternalError("MOQtailClient.publishDone", error instanceof Error ? error.message : String(error))
8103
+ );
8104
+ throw error;
8105
+ }
8106
+ }
7889
8107
  /**
7890
8108
  * Registers an incoming PUBLISH announcement as a valid data receiver.
7891
8109
  * This prepares the client to ingest pushed data streams matching the published alias.
@@ -8472,300 +8690,6 @@ var NetworkTelemetry = class {
8472
8690
  }
8473
8691
  };
8474
8692
 
8475
- // src/util/playout_buffer.ts
8476
- init_extension_header2();
8477
- var DEFAULT_TARGET_LATENCY_MS = 100;
8478
- var DEFAULT_MAX_LATENCY_MS = 1e3;
8479
- var PlayoutBuffer = class {
8480
- constructor(objectStream, options) {
8481
- this.options = options;
8482
- this.#targetLatencyMs = this.options?.targetLatencyMs ?? DEFAULT_TARGET_LATENCY_MS;
8483
- this.#maxLatencyMs = this.options?.maxLatencyMs ?? DEFAULT_MAX_LATENCY_MS;
8484
- this.#clock = this.options?.clock;
8485
- this.#reader = objectStream.getReader();
8486
- this.#fillBuffer();
8487
- this.#serveBuffer();
8488
- }
8489
- #reader;
8490
- #buffer = new Heap__default.default((a, b) => {
8491
- return a.object.location.compare(b.object.location);
8492
- });
8493
- #isRunning = true;
8494
- #targetLatencyMs;
8495
- #moqObjectCountInBuffer = 0;
8496
- #moqObjectCountExitingBuffer = 0;
8497
- #maxLatencyMs;
8498
- #clock;
8499
- onObject = null;
8500
- async hasObjectReady() {
8501
- const now = this.#getNormalizedTime();
8502
- const oldest = this.#buffer.peek();
8503
- return oldest ? now - oldest.createdAt >= this.#targetLatencyMs : false;
8504
- }
8505
- getStatus() {
8506
- const oldest = this.#buffer.peek();
8507
- const result = {
8508
- bufferSize: this.#buffer.length,
8509
- isRunning: this.#isRunning
8510
- };
8511
- if (oldest) {
8512
- result.oldestTimestamp = oldest.createdAt;
8513
- }
8514
- return result;
8515
- }
8516
- cleanup() {
8517
- this.#isRunning = false;
8518
- this.onObject?.(null);
8519
- }
8520
- #getNormalizedTime() {
8521
- if (this.#clock) {
8522
- return this.#clock.now();
8523
- }
8524
- return Date.now();
8525
- }
8526
- async #serveBuffer() {
8527
- while (this.#isRunning) {
8528
- const now = this.#getNormalizedTime();
8529
- const oldest = this.#buffer.peek();
8530
- if (oldest && this.onObject) {
8531
- const timeUntilReady = this.#targetLatencyMs - (now - oldest.createdAt);
8532
- if (timeUntilReady <= 0) {
8533
- const bufferedObj = this.#buffer.pop();
8534
- this.#moqObjectCountExitingBuffer++;
8535
- if (this.#moqObjectCountExitingBuffer % 50 === 0) ;
8536
- this.onObject(bufferedObj.object);
8537
- if (this.#moqObjectCountExitingBuffer % 50 === 0) ;
8538
- } else {
8539
- const sleepTime = Math.min(timeUntilReady, 50);
8540
- await new Promise((resolve) => setTimeout(resolve, sleepTime));
8541
- }
8542
- } else {
8543
- await new Promise((resolve) => setTimeout(resolve, 10));
8544
- }
8545
- }
8546
- }
8547
- async #fillBuffer() {
8548
- while (this.#isRunning) {
8549
- try {
8550
- const { value, done } = await this.#reader.read();
8551
- if (done) {
8552
- this.cleanup();
8553
- return;
8554
- }
8555
- this.#evictOnMaxLatency();
8556
- const bufferedObject = {
8557
- object: value,
8558
- createdAt: this.#extractCreatedAt(value)
8559
- };
8560
- this.#moqObjectCountInBuffer++;
8561
- if (this.#moqObjectCountInBuffer % 50 === 0) {
8562
- }
8563
- this.#buffer.push(bufferedObject);
8564
- } catch (error) {
8565
- this.cleanup();
8566
- }
8567
- }
8568
- }
8569
- #extractCreatedAt(object) {
8570
- if (object.extensionHeaders) {
8571
- const extensionHeaders = exports.ExtensionHeaders.fromKeyValuePairs(object.extensionHeaders);
8572
- for (const header of extensionHeaders) {
8573
- if (exports.ExtensionHeader.isCaptureTimestamp(header)) {
8574
- return Number(header.timestamp);
8575
- }
8576
- }
8577
- }
8578
- return this.#getNormalizedTime();
8579
- }
8580
- #evictOnMaxLatency() {
8581
- const now = this.#getNormalizedTime();
8582
- const oldest = this.#buffer.peek();
8583
- if (oldest && now - oldest.createdAt > this.#maxLatencyMs) {
8584
- if (oldest.object.location.object === 0n) {
8585
- const groupToDrop = oldest.object.location.group;
8586
- this.#dropGop(groupToDrop);
8587
- } else {
8588
- this.#buffer.pop();
8589
- }
8590
- this.#evictOnMaxLatency();
8591
- }
8592
- }
8593
- #dropGop(groupId) {
8594
- while (this.#buffer.length > 0) {
8595
- const oldest = this.#buffer.peek();
8596
- if (oldest && oldest.object.location.group === groupId) {
8597
- this.#buffer.pop();
8598
- } else {
8599
- break;
8600
- }
8601
- }
8602
- }
8603
- };
8604
- var DEFAULT_BUFFER_CAPACITY = 50;
8605
- var DEFAULT_TARGET_LATENCY_MS2 = 500;
8606
- var DEFAULT_MAX_LATENCY_MS2 = 2e3;
8607
- var PullPlayoutBuffer = class {
8608
- constructor(writeStream, options) {
8609
- this.options = options;
8610
- this.#bucketCapacity = this.options.bucketCapacity ?? DEFAULT_BUFFER_CAPACITY;
8611
- this.#targetLatencyMs = this.options.targetLatencyMs ?? DEFAULT_TARGET_LATENCY_MS2;
8612
- this.#maxLatencyMs = this.options.maxLatencyMs ?? DEFAULT_MAX_LATENCY_MS2;
8613
- this.#reader = writeStream.getReader();
8614
- this.#fillBuffer();
8615
- }
8616
- #reader;
8617
- #buffer = new Heap__default.default((a, b) => {
8618
- if (a.location.compare(b.location) <= 0) {
8619
- if (b.location.compare(a.location) <= 0) {
8620
- return 0;
8621
- }
8622
- return -1;
8623
- }
8624
- return 1;
8625
- });
8626
- #isRunning = true;
8627
- #bucketCapacity;
8628
- #targetLatencyMs;
8629
- #maxLatencyMs;
8630
- #lastIncomingTimestamp = 0;
8631
- #pendingCallback = null;
8632
- // Pull-based API: Consumer calls this when ready for next object
8633
- nextObject(callback) {
8634
- if (this.#buffer.length > 0) {
8635
- const obj = this.#buffer.pop();
8636
- callback(obj || null);
8637
- return;
8638
- }
8639
- this.#pendingCallback = callback;
8640
- }
8641
- // Check if there's an object ready immediately (non-blocking)
8642
- hasObjectReady() {
8643
- return this.#buffer.length > 0;
8644
- }
8645
- // Get current buffer status for debugging
8646
- getStatus() {
8647
- return {
8648
- bufferSize: this.#buffer.length,
8649
- isRunning: this.#isRunning
8650
- };
8651
- }
8652
- // Cleanup method - called when buffer is destroyed
8653
- cleanup() {
8654
- this.#isRunning = false;
8655
- }
8656
- // Simple background filling - just fills the buffer as objects arrive
8657
- async #fillBuffer() {
8658
- while (this.#isRunning) {
8659
- try {
8660
- const { value, done } = await this.#reader.read();
8661
- if (done) {
8662
- this.#isRunning = false;
8663
- if (this.#pendingCallback) {
8664
- const callback = this.#pendingCallback;
8665
- this.#pendingCallback = null;
8666
- callback(null);
8667
- }
8668
- return;
8669
- }
8670
- this.#lastIncomingTimestamp = performance.now();
8671
- if (this.#buffer.length >= this.#bucketCapacity) {
8672
- this.#manageBufferOverflow();
8673
- }
8674
- this.#buffer.push(value);
8675
- if (this.#pendingCallback) {
8676
- const callback = this.#pendingCallback;
8677
- this.#pendingCallback = null;
8678
- const obj = this.#buffer.pop();
8679
- callback(obj || null);
8680
- }
8681
- } catch (error) {
8682
- console.error("Error in fillBuffer:", error);
8683
- this.#isRunning = false;
8684
- if (this.#pendingCallback) {
8685
- const callback = this.#pendingCallback;
8686
- this.#pendingCallback = null;
8687
- callback(null);
8688
- }
8689
- }
8690
- }
8691
- }
8692
- // Manage buffer overflow by dropping oldest GOPs
8693
- #manageBufferOverflow() {
8694
- const droppedGops = this.#dropMultipleGopsToTarget();
8695
- if (droppedGops === 0) {
8696
- const dropCount = Math.floor(this.#bucketCapacity * 0.2);
8697
- for (let i = 0; i < dropCount; i++) {
8698
- this.#buffer.pop();
8699
- }
8700
- console.log(`\u{1F5D1}\uFE0F [PULL BUFFER] Buffer overflow: dropped ${dropCount} oldest objects (fallback)`);
8701
- }
8702
- }
8703
- // Find GOP boundaries based on group IDs
8704
- #findGopBoundaries(objects) {
8705
- const gops = [];
8706
- if (objects.length === 0) return gops;
8707
- const groupMap = /* @__PURE__ */ new Map();
8708
- objects.forEach((obj, index) => {
8709
- const groupId = obj.location.group;
8710
- if (!groupMap.has(groupId)) {
8711
- groupMap.set(groupId, []);
8712
- }
8713
- groupMap.get(groupId).push(index);
8714
- });
8715
- const sortedGroups = Array.from(groupMap.entries()).sort(([a], [b]) => {
8716
- if (a < b) return -1;
8717
- if (a > b) return 1;
8718
- return 0;
8719
- });
8720
- sortedGroups.forEach(([, indices]) => {
8721
- if (indices.length > 0) {
8722
- gops.push({
8723
- start: Math.min(...indices),
8724
- end: Math.max(...indices)
8725
- });
8726
- }
8727
- });
8728
- console.log(`\u{1F3AC} [PULL BUFFER] Found ${gops.length} GOPs (groups) in buffer`);
8729
- return gops;
8730
- }
8731
- // Drop oldest GOP (complete group)
8732
- #dropOldestGop() {
8733
- const allObjects = this.#buffer.toArray();
8734
- const gops = this.#findGopBoundaries(allObjects);
8735
- if (gops.length > 0) {
8736
- const oldestGop = gops[0];
8737
- if (oldestGop) {
8738
- const firstObj = allObjects[oldestGop.start];
8739
- const groupId = firstObj?.location.group;
8740
- for (let i = oldestGop.start; i <= oldestGop.end; i++) {
8741
- this.#buffer.pop();
8742
- }
8743
- console.log(`\u{1F5D1}\uFE0F [PULL BUFFER] Dropped GOP (Group ${groupId}): ${oldestGop.end - oldestGop.start + 1} objects`);
8744
- return true;
8745
- }
8746
- }
8747
- return false;
8748
- }
8749
- // Drop multiple GOPs to reach target buffer size
8750
- #dropMultipleGopsToTarget() {
8751
- const targetBufferSize = Math.floor(this.#bucketCapacity * 0.7);
8752
- let droppedGops = 0;
8753
- while (this.#buffer.length > targetBufferSize && droppedGops < 3) {
8754
- if (this.#dropOldestGop()) {
8755
- droppedGops++;
8756
- } else {
8757
- break;
8758
- }
8759
- }
8760
- if (droppedGops > 0) {
8761
- console.log(
8762
- `\u{1F5D1}\uFE0F [PULL BUFFER] Dropped ${droppedGops} GOPs to reduce buffer size. New buffer size: ${this.#buffer.length}`
8763
- );
8764
- }
8765
- return droppedGops;
8766
- }
8767
- };
8768
-
8769
8693
  // src/util/clock_normalizer.ts
8770
8694
  var DEFAULT_SAMPLE_SIZE = 5;
8771
8695
  var DEFAULT_TIME_SERVER = "https://time.akamai.com/?ms";
@@ -8836,6 +8760,7 @@ var ClockNormalizer = class _ClockNormalizer {
8836
8760
  };
8837
8761
 
8838
8762
  exports.AuthorizationToken = AuthorizationToken;
8763
+ exports.CMSFCatalog = CMSFCatalog;
8839
8764
  exports.ClientSetup = ClientSetup;
8840
8765
  exports.ClockNormalizer = ClockNormalizer;
8841
8766
  exports.CommonType = CommonType;
@@ -8864,7 +8789,6 @@ exports.MaxRequestIdParameter = MaxRequestId2;
8864
8789
  exports.MemoryObjectCache = MemoryObjectCache;
8865
8790
  exports.NetworkTelemetry = NetworkTelemetry;
8866
8791
  exports.Path = Path;
8867
- exports.PlayoutBuffer = PlayoutBuffer;
8868
8792
  exports.Publish = Publish;
8869
8793
  exports.PublishDone = PublishDone;
8870
8794
  exports.PublishDoneStatusCode = PublishDoneStatusCode;
@@ -8880,7 +8804,6 @@ exports.PublishNamespaceRequest = PublishNamespaceRequest;
8880
8804
  exports.PublishOk = PublishOk;
8881
8805
  exports.PublishPublication = PublishPublication;
8882
8806
  exports.PublishRequest = PublishRequest;
8883
- exports.PullPlayoutBuffer = PullPlayoutBuffer;
8884
8807
  exports.RecvDatagramStream = RecvDatagramStream;
8885
8808
  exports.RecvStream = RecvStream;
8886
8809
  exports.RequestsBlocked = RequestsBlocked;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,4 @@
1
- export { ControlStream, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource } from './client/index.cjs';
2
- export { B as BaseByteBuffer, a as ByteBuffer, D as DatagramObject, h as DatagramStatus, e as FetchHeaderType, j as FetchObject, F as FrozenByteBuffer, m as FullTrackName, K as KeyValuePair, L as Location, l as MAX_FULL_TRACK_NAME_LENGTH, k as MAX_NAMESPACE_TUPLE_COUNT, M as MAX_REASON_PHRASE_LEN, n as MoqtObject, O as ObjectDatagramStatusType, d as ObjectDatagramType, f as ObjectForwardingPreference, g as ObjectStatus, R as ReasonPhrase, S as SubgroupHeaderType, o as SubgroupObject, c as Tuple, T as TupleField, b as isBytes, i as isVarInt } from './byte_buffer-BM4uNj4n.cjs';
3
- export { ah as AuthTokenVariant, ai as AuthorizationToken, C as ClientSetup, a9 as CommonType, w as ControlMessage, d as ControlMessageType, D as DRAFT_14, am as DeliveryTimeout, x as Fetch, y as FetchCancel, z as FetchError, l as FetchErrorCode, a0 as FetchHeader, A as FetchOk, h as FetchType, F as FilterType, B as GoAway, G as GroupOrder, a3 as Header, al as MaxAuthTokenCacheSize, an as MaxCacheDuration, M as MaxRequestId, aj as MaxRequestIdParameter, a8 as Parameter, ak as Path, L as Publish, K as PublishDone, q as PublishDoneStatusCode, N as PublishError, u as PublishErrorCode, P as PublishNamespace, c as PublishNamespaceCancel, Z as PublishNamespaceDone, a as PublishNamespaceError, f as PublishNamespaceErrorCode, b as PublishNamespaceOk, O as PublishOk, a2 as RequestIdMap, R as RequestsBlocked, E as ServerSetup, a4 as SetupParameter, ab as SetupParameterType, a5 as SetupParameters, a1 as SubgroupHeader, S as Subscribe, Q as SubscribeError, k as SubscribeErrorCode, H as SubscribeNamespace, I as SubscribeNamespaceError, n as SubscribeNamespaceErrorCode, J as SubscribeNamespaceOk, U as SubscribeOk, V as SubscribeUpdate, af as TokenAliasType, W as TrackStatus, T as TrackStatusCode, X as TrackStatusError, Y as TrackStatusOk, _ as Unsubscribe, $ as UnsubscribeNamespace, a6 as VersionSpecificParameter, ad as VersionSpecificParameterType, a7 as VersionSpecificParameters, aa as commonTypeFromNumber, e as controlMessageTypeFromBigInt, m as fetchErrorCodeFromBigInt, i as fetchTypeFromBigInt, g as filterTypeFromBigInt, j as groupOrderFromNumber, r as publishDoneStatusCodeFromBigInt, v as publishErrorCodeFromBigInt, p as publishNamespaceErrorCodeFromBigInt, ac as setupParameterTypeFromNumber, s as subscribeErrorCodeFromBigInt, o as subscribeNamespaceErrorCodeFromBigInt, ag as tokenAliasTypeFromNumber, t as trackStatusCodeFromBigInt, ae as versionSpecificParameterTypeFromNumber } from './version_parameter-BpmuiMQj.cjs';
4
- export { AudioLevel, CaptureTimestamp, CastingError, ExtensionHeader, ExtensionHeaders, InternalError, InvalidTypeError, InvalidUTF8Error, KeyValueFormattingError, LOCHeaderExtensionId, LengthExceedsMaxError, MOQtailError, NotEnoughBytesError, ProtocolViolationError, RequestIdError, Switch, TerminationCode, TerminationError, TimeoutError, TrackNameError, VarIntOverflowError, VideoConfig, VideoFrameMarking, locHeaderExtensionIdFromNumber } from './model/index.cjs';
5
- export { BufferedObject, Clock, ClockNormalizer, NetworkTelemetry, PlayoutBuffer, PullPlayoutBuffer } from './util/index.cjs';
1
+ export { ControlStream, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource } from './client.cjs';
2
+ export { AudioLevel, CMSF, CMSFCatalog, CMSFTrack, CaptureTimestamp, CastingError, ExtensionHeader, ExtensionHeaders, InternalError, InvalidTypeError, InvalidUTF8Error, KeyValueFormattingError, LOCHeaderExtensionId, LengthExceedsMaxError, MOQtailError, NotEnoughBytesError, ProtocolViolationError, RequestIdError, Switch, TerminationCode, TerminationError, TimeoutError, TrackNameError, VarIntOverflowError, VideoConfig, VideoFrameMarking, locHeaderExtensionIdFromNumber } from './model.cjs';
3
+ export { A as AuthTokenVariant, a as AuthorizationToken, B as BaseByteBuffer, b as ByteBuffer, C as ClientSetup, c as CommonType, d as ControlMessage, e as ControlMessageType, D as DRAFT_14, f as DatagramObject, g as DatagramStatus, h as DeliveryTimeout, F as Fetch, i as FetchCancel, j as FetchError, k as FetchErrorCode, l as FetchHeader, m as FetchHeaderType, n as FetchObject, o as FetchOk, p as FetchType, q as FilterType, r as FrozenByteBuffer, s as FullTrackName, G as GoAway, t as GroupOrder, H as Header, K as KeyValuePair, L as Location, M as MAX_FULL_TRACK_NAME_LENGTH, u as MAX_NAMESPACE_TUPLE_COUNT, v as MAX_REASON_PHRASE_LEN, w as MaxAuthTokenCacheSize, x as MaxCacheDuration, y as MaxRequestId, z as MaxRequestIdParameter, E as MoqtObject, O as ObjectDatagramStatusType, I as ObjectDatagramType, J as ObjectForwardingPreference, N as ObjectStatus, P as Parameter, Q as Path, R as Publish, S as PublishDone, T as PublishDoneStatusCode, U as PublishError, V as PublishErrorCode, W as PublishNamespace, X as PublishNamespaceCancel, Y as PublishNamespaceDone, Z as PublishNamespaceError, _ as PublishNamespaceErrorCode, $ as PublishNamespaceOk, a0 as PublishOk, a1 as ReasonPhrase, a2 as RequestIdMap, a3 as RequestsBlocked, a4 as ServerSetup, a5 as SetupParameter, a6 as SetupParameterType, a7 as SetupParameters, a8 as SubgroupHeader, a9 as SubgroupHeaderType, aa as SubgroupObject, ab as Subscribe, ac as SubscribeError, ad as SubscribeErrorCode, ae as SubscribeNamespace, af as SubscribeNamespaceError, ag as SubscribeNamespaceErrorCode, ah as SubscribeNamespaceOk, ai as SubscribeOk, aj as SubscribeUpdate, ak as TokenAliasType, al as TrackStatus, am as TrackStatusCode, an as TrackStatusError, ao as TrackStatusOk, ap as Tuple, aq as TupleField, ar as Unsubscribe, as as UnsubscribeNamespace, at as VersionSpecificParameter, au as VersionSpecificParameterType, av as VersionSpecificParameters, aw as commonTypeFromNumber, ax as controlMessageTypeFromBigInt, ay as fetchErrorCodeFromBigInt, az as fetchTypeFromBigInt, aA as filterTypeFromBigInt, aB as groupOrderFromNumber, aC as isBytes, aD as isVarInt, aE as publishDoneStatusCodeFromBigInt, aF as publishErrorCodeFromBigInt, aG as publishNamespaceErrorCodeFromBigInt, aH as setupParameterTypeFromNumber, aI as subscribeErrorCodeFromBigInt, aJ as subscribeNamespaceErrorCodeFromBigInt, aK as tokenAliasTypeFromNumber, aL as trackStatusCodeFromBigInt, aM as versionSpecificParameterTypeFromNumber } from './version_parameter-DXBOBueW.cjs';
4
+ export { ClockNormalizer, NetworkTelemetry } from './util.cjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export { ControlStream, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource } from './client/index.js';
2
- export { B as BaseByteBuffer, a as ByteBuffer, D as DatagramObject, h as DatagramStatus, e as FetchHeaderType, j as FetchObject, F as FrozenByteBuffer, m as FullTrackName, K as KeyValuePair, L as Location, l as MAX_FULL_TRACK_NAME_LENGTH, k as MAX_NAMESPACE_TUPLE_COUNT, M as MAX_REASON_PHRASE_LEN, n as MoqtObject, O as ObjectDatagramStatusType, d as ObjectDatagramType, f as ObjectForwardingPreference, g as ObjectStatus, R as ReasonPhrase, S as SubgroupHeaderType, o as SubgroupObject, c as Tuple, T as TupleField, b as isBytes, i as isVarInt } from './byte_buffer-BM4uNj4n.js';
3
- export { ah as AuthTokenVariant, ai as AuthorizationToken, C as ClientSetup, a9 as CommonType, w as ControlMessage, d as ControlMessageType, D as DRAFT_14, am as DeliveryTimeout, x as Fetch, y as FetchCancel, z as FetchError, l as FetchErrorCode, a0 as FetchHeader, A as FetchOk, h as FetchType, F as FilterType, B as GoAway, G as GroupOrder, a3 as Header, al as MaxAuthTokenCacheSize, an as MaxCacheDuration, M as MaxRequestId, aj as MaxRequestIdParameter, a8 as Parameter, ak as Path, L as Publish, K as PublishDone, q as PublishDoneStatusCode, N as PublishError, u as PublishErrorCode, P as PublishNamespace, c as PublishNamespaceCancel, Z as PublishNamespaceDone, a as PublishNamespaceError, f as PublishNamespaceErrorCode, b as PublishNamespaceOk, O as PublishOk, a2 as RequestIdMap, R as RequestsBlocked, E as ServerSetup, a4 as SetupParameter, ab as SetupParameterType, a5 as SetupParameters, a1 as SubgroupHeader, S as Subscribe, Q as SubscribeError, k as SubscribeErrorCode, H as SubscribeNamespace, I as SubscribeNamespaceError, n as SubscribeNamespaceErrorCode, J as SubscribeNamespaceOk, U as SubscribeOk, V as SubscribeUpdate, af as TokenAliasType, W as TrackStatus, T as TrackStatusCode, X as TrackStatusError, Y as TrackStatusOk, _ as Unsubscribe, $ as UnsubscribeNamespace, a6 as VersionSpecificParameter, ad as VersionSpecificParameterType, a7 as VersionSpecificParameters, aa as commonTypeFromNumber, e as controlMessageTypeFromBigInt, m as fetchErrorCodeFromBigInt, i as fetchTypeFromBigInt, g as filterTypeFromBigInt, j as groupOrderFromNumber, r as publishDoneStatusCodeFromBigInt, v as publishErrorCodeFromBigInt, p as publishNamespaceErrorCodeFromBigInt, ac as setupParameterTypeFromNumber, s as subscribeErrorCodeFromBigInt, o as subscribeNamespaceErrorCodeFromBigInt, ag as tokenAliasTypeFromNumber, t as trackStatusCodeFromBigInt, ae as versionSpecificParameterTypeFromNumber } from './version_parameter-f75NkWiO.js';
4
- export { AudioLevel, CaptureTimestamp, CastingError, ExtensionHeader, ExtensionHeaders, InternalError, InvalidTypeError, InvalidUTF8Error, KeyValueFormattingError, LOCHeaderExtensionId, LengthExceedsMaxError, MOQtailError, NotEnoughBytesError, ProtocolViolationError, RequestIdError, Switch, TerminationCode, TerminationError, TimeoutError, TrackNameError, VarIntOverflowError, VideoConfig, VideoFrameMarking, locHeaderExtensionIdFromNumber } from './model/index.js';
5
- export { BufferedObject, Clock, ClockNormalizer, NetworkTelemetry, PlayoutBuffer, PullPlayoutBuffer } from './util/index.js';
1
+ export { ControlStream, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource } from './client.js';
2
+ export { AudioLevel, CMSF, CMSFCatalog, CMSFTrack, CaptureTimestamp, CastingError, ExtensionHeader, ExtensionHeaders, InternalError, InvalidTypeError, InvalidUTF8Error, KeyValueFormattingError, LOCHeaderExtensionId, LengthExceedsMaxError, MOQtailError, NotEnoughBytesError, ProtocolViolationError, RequestIdError, Switch, TerminationCode, TerminationError, TimeoutError, TrackNameError, VarIntOverflowError, VideoConfig, VideoFrameMarking, locHeaderExtensionIdFromNumber } from './model.js';
3
+ export { A as AuthTokenVariant, a as AuthorizationToken, B as BaseByteBuffer, b as ByteBuffer, C as ClientSetup, c as CommonType, d as ControlMessage, e as ControlMessageType, D as DRAFT_14, f as DatagramObject, g as DatagramStatus, h as DeliveryTimeout, F as Fetch, i as FetchCancel, j as FetchError, k as FetchErrorCode, l as FetchHeader, m as FetchHeaderType, n as FetchObject, o as FetchOk, p as FetchType, q as FilterType, r as FrozenByteBuffer, s as FullTrackName, G as GoAway, t as GroupOrder, H as Header, K as KeyValuePair, L as Location, M as MAX_FULL_TRACK_NAME_LENGTH, u as MAX_NAMESPACE_TUPLE_COUNT, v as MAX_REASON_PHRASE_LEN, w as MaxAuthTokenCacheSize, x as MaxCacheDuration, y as MaxRequestId, z as MaxRequestIdParameter, E as MoqtObject, O as ObjectDatagramStatusType, I as ObjectDatagramType, J as ObjectForwardingPreference, N as ObjectStatus, P as Parameter, Q as Path, R as Publish, S as PublishDone, T as PublishDoneStatusCode, U as PublishError, V as PublishErrorCode, W as PublishNamespace, X as PublishNamespaceCancel, Y as PublishNamespaceDone, Z as PublishNamespaceError, _ as PublishNamespaceErrorCode, $ as PublishNamespaceOk, a0 as PublishOk, a1 as ReasonPhrase, a2 as RequestIdMap, a3 as RequestsBlocked, a4 as ServerSetup, a5 as SetupParameter, a6 as SetupParameterType, a7 as SetupParameters, a8 as SubgroupHeader, a9 as SubgroupHeaderType, aa as SubgroupObject, ab as Subscribe, ac as SubscribeError, ad as SubscribeErrorCode, ae as SubscribeNamespace, af as SubscribeNamespaceError, ag as SubscribeNamespaceErrorCode, ah as SubscribeNamespaceOk, ai as SubscribeOk, aj as SubscribeUpdate, ak as TokenAliasType, al as TrackStatus, am as TrackStatusCode, an as TrackStatusError, ao as TrackStatusOk, ap as Tuple, aq as TupleField, ar as Unsubscribe, as as UnsubscribeNamespace, at as VersionSpecificParameter, au as VersionSpecificParameterType, av as VersionSpecificParameters, aw as commonTypeFromNumber, ax as controlMessageTypeFromBigInt, ay as fetchErrorCodeFromBigInt, az as fetchTypeFromBigInt, aA as filterTypeFromBigInt, aB as groupOrderFromNumber, aC as isBytes, aD as isVarInt, aE as publishDoneStatusCodeFromBigInt, aF as publishErrorCodeFromBigInt, aG as publishNamespaceErrorCodeFromBigInt, aH as setupParameterTypeFromNumber, aI as subscribeErrorCodeFromBigInt, aJ as subscribeNamespaceErrorCodeFromBigInt, aK as tokenAliasTypeFromNumber, aL as trackStatusCodeFromBigInt, aM as versionSpecificParameterTypeFromNumber } from './version_parameter-DXBOBueW.js';
4
+ export { ClockNormalizer, NetworkTelemetry } from './util.js';