@vindral/web-sdk 4.2.0 → 4.2.1-10-ga7cb21ca

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/react.d.ts CHANGED
@@ -131,7 +131,7 @@ declare class UserAgentInformation {
131
131
  };
132
132
  }
133
133
  type AudioCodec = "aac" | "opus" | "mp3";
134
- type VideoCodec = "h264" | "av1";
134
+ type VideoCodec = "h264" | "h265" | "av1";
135
135
  interface ReconnectState {
136
136
  /**
137
137
  * The number or retry attempts so far.
@@ -464,8 +464,8 @@ interface TrackObject {
464
464
  displayWidth?: number;
465
465
  displayHeight?: number;
466
466
  language?: string;
467
- ["com.vindral.variant_uid"]?: string;
468
- ["com.vindral.drm"]?: string;
467
+ "com.vindral.variant_uid"?: string;
468
+ "com.vindral.drm"?: string;
469
469
  }
470
470
  interface CatalogRoot {
471
471
  version: number;
@@ -693,6 +693,7 @@ declare class ApiClient {
693
693
  private toChannels;
694
694
  private toChannel;
695
695
  }
696
+ type TransportSelectionReason = "unsupported" | "disabled" | "unavailable" | "fallback";
696
697
  interface AdaptivityStatistics {
697
698
  /**
698
699
  * True if adaptive bitrate (ABR) is enabled.
@@ -832,6 +833,7 @@ interface JitterModuleStatistics {
832
833
  interface MseModuleStatistics {
833
834
  quotaErrorCount: number;
834
835
  mediaSourceOpenTime: number;
836
+ playbackStallCount: number;
835
837
  totalVideoFrames?: number;
836
838
  droppedVideoFrames?: number;
837
839
  successfulVideoAppendCalls?: number;
@@ -1163,6 +1165,14 @@ declare class Vindral extends Emitter<PublicVindralEvents> {
1163
1165
  * setting targetBufferTime within that range for consistancy if using both min/max.
1164
1166
  */
1165
1167
  set targetBufferTime(bufferTimeMs: number);
1168
+ /**
1169
+ * Update the dynamic buffer time configuration at runtime.
1170
+ * Allows adjusting min and max buffer time without recreating the Vindral instance.
1171
+ */
1172
+ updateBufferTimeConfig(config: {
1173
+ minBufferTime?: number;
1174
+ maxBufferTime?: number;
1175
+ }): void;
1166
1176
  /**
1167
1177
  * The estimated playback latency based on target buffer time, the connection rtt and local playback drift
1168
1178
  */
@@ -1400,6 +1410,8 @@ declare class Vindral extends Emitter<PublicVindralEvents> {
1400
1410
  private suspend;
1401
1411
  private unsuspend;
1402
1412
  private getRuntimeInfo;
1413
+ private getPlaybackBufferState;
1414
+ private onMediaElementBufferState;
1403
1415
  private onMediaElementState;
1404
1416
  private onBufferEvent;
1405
1417
  /**
@@ -1456,6 +1468,14 @@ interface ConnectionStatistics {
1456
1468
  */
1457
1469
  connectionSuccessRatio: number;
1458
1470
  connectionProtocol: "vindral_ws" | "moq" | "moq_ws" | undefined;
1471
+ /**
1472
+ * When connectionProtocol is "moq_ws", indicates why WebSocket was used instead of WebTransport.
1473
+ * - "unsupported": browser doesn't support WebTransport
1474
+ * - "disabled": webtransportEnabled option is false
1475
+ * - "unavailable": edge did not offer a WebTransport endpoint
1476
+ * - "fallback": WebTransport was attempted but failed or timed out
1477
+ */
1478
+ transportSelectionReason: TransportSelectionReason | undefined;
1459
1479
  }
1460
1480
  interface LanguageSwitchContext {
1461
1481
  /**
@@ -1498,7 +1518,7 @@ interface PublicVindralEvents {
1498
1518
  * In case of a fatal error it is appropriate to indicate what the error was to the user, either by displaying the error.message or
1499
1519
  * by using the error.code() as a key to look up a localization string. To resume streaming it is required to create a new Vindral instance.
1500
1520
  */
1501
- ["error"]: Readonly<VindralError>;
1521
+ error: Readonly<VindralError>;
1502
1522
  /**
1503
1523
  * When the instance needs user input to activate audio or sometimes video playback.
1504
1524
  * Is called with an object
@@ -1509,51 +1529,51 @@ interface PublicVindralEvents {
1509
1529
  * }
1510
1530
  * ```
1511
1531
  */
1512
- ["needs user input"]: NeedsUserInputContext;
1532
+ "needs user input": NeedsUserInputContext;
1513
1533
  /**
1514
1534
  * When a timed metadata event has been triggered
1515
1535
  */
1516
- ["metadata"]: Readonly<Metadata>;
1536
+ metadata: Readonly<Metadata>;
1517
1537
  /**
1518
1538
  * When the playback state changes
1519
1539
  */
1520
- ["playback state"]: Readonly<PlaybackState>;
1540
+ "playback state": Readonly<PlaybackState>;
1521
1541
  /**
1522
1542
  * When the connection state changes
1523
1543
  */
1524
- ["connection state"]: Readonly<ConnectionState>;
1544
+ "connection state": Readonly<ConnectionState>;
1525
1545
  /**
1526
1546
  * When the available rendition levels is changed
1527
1547
  */
1528
- ["rendition levels"]: ReadonlyArray<RenditionLevel>;
1548
+ "rendition levels": ReadonlyArray<RenditionLevel>;
1529
1549
  /**
1530
1550
  * When the rendition level is changed
1531
1551
  */
1532
- ["rendition level"]: Readonly<RenditionLevel>;
1552
+ "rendition level": Readonly<RenditionLevel>;
1533
1553
  /**
1534
1554
  * When the available languages is changed
1535
1555
  */
1536
- ["languages"]: ReadonlyArray<string>;
1556
+ languages: ReadonlyArray<string>;
1537
1557
  /**
1538
1558
  * When the available text tracks are changed
1539
1559
  */
1540
- ["text tracks"]: ReadonlyArray<string>;
1560
+ "text tracks": ReadonlyArray<string>;
1541
1561
  /**
1542
1562
  * When the available channels is changed
1543
1563
  */
1544
- ["channels"]: ReadonlyArray<Channel>;
1564
+ channels: ReadonlyArray<Channel>;
1545
1565
  /**
1546
1566
  * When a context switch state change has occured.
1547
1567
  * E.g. when a channel change has been requested, or quality is changed.
1548
1568
  */
1549
- ["context switch"]: Readonly<ContextSwitchState>;
1569
+ "context switch": Readonly<ContextSwitchState>;
1550
1570
  /**
1551
1571
  * Emitted when a wallclock time message has been received from the server.
1552
1572
  *
1553
1573
  * Note: This is the edge server wallclock time and thus may differ slightly
1554
1574
  * between two viewers if they are connected to different edge servers.
1555
1575
  */
1556
- ["server wallclock time"]: Readonly<number>;
1576
+ "server wallclock time": Readonly<number>;
1557
1577
  /**
1558
1578
  * Is emitted during connection whether the channel is live or not.
1559
1579
  *
@@ -1563,41 +1583,41 @@ interface PublicVindralEvents {
1563
1583
  * Note: If the web-sdk is instantiated at the same time as you are starting the stream it is possible
1564
1584
  * that this emits false until the started state has propagated through the system.
1565
1585
  */
1566
- ["is live"]: boolean;
1586
+ "is live": boolean;
1567
1587
  /**
1568
1588
  * Emitted when a channel switch has been completed and the first frame of the new channel is rendered.
1569
1589
  * A string containing the channel id of the new channel is provided as an argument.
1570
1590
  */
1571
- ["channel switch"]: Readonly<ChannelSwitchContext>;
1591
+ "channel switch": Readonly<ChannelSwitchContext>;
1572
1592
  /**
1573
1593
  * Emmitted when a channel switch fails.
1574
1594
  * A string containing the channel id of the current channel is provided as an argument.
1575
1595
  */
1576
- ["channel switch failed"]: Readonly<ChannelSwitchContext>;
1596
+ "channel switch failed": Readonly<ChannelSwitchContext>;
1577
1597
  /**
1578
1598
  * Emitted when a language switch has been completed and the new language starts playing.
1579
1599
  */
1580
- ["language switch"]: Readonly<LanguageSwitchContext>;
1600
+ "language switch": Readonly<LanguageSwitchContext>;
1581
1601
  /**
1582
1602
  * Emitted when the volume state changes.
1583
1603
  *
1584
1604
  * This is triggered triggered both when the user changes the volume through the Vindral instance, but also
1585
1605
  * from external sources such as OS media shortcuts or other native UI outside of the browser.
1586
1606
  */
1587
- ["volume state"]: Readonly<VolumeState>;
1607
+ "volume state": Readonly<VolumeState>;
1588
1608
  /**
1589
1609
  * Emitted when the timeshift URLs are updated.
1590
1610
  */
1591
- ["timeshift info"]: Readonly<TimeShiftInfo>;
1611
+ "timeshift info": Readonly<TimeShiftInfo>;
1592
1612
  /**
1593
1613
  * Emitted for each CMAF fragment received via the MoQ/VoQ path.
1594
1614
  * Contains raw fMP4 bytes suitable for recording.
1595
1615
  *
1596
1616
  * @internal Not part of the public API — may change without notice.
1597
1617
  */
1598
- ["cmaf fragment"]: Readonly<CmafFragmentEvent>;
1599
- ["buffer state event"]: Readonly<BufferStateEvent>;
1600
- ["initialized media"]: void;
1618
+ "cmaf fragment": Readonly<CmafFragmentEvent>;
1619
+ "buffer state event": Readonly<BufferStateEvent>;
1620
+ "initialized media": void;
1601
1621
  }
1602
1622
  declare abstract class VindralButton extends HTMLElement {
1603
1623
  #private;
@@ -1611,18 +1631,6 @@ declare abstract class VindralButton extends HTMLElement {
1611
1631
  attributeChangedCallback(name: string, _old: string, value: string): void;
1612
1632
  protected abstract handleClick(e: Event): void;
1613
1633
  }
1614
- type AirPlayButtonAttributes = (typeof AirPlayButton.observedAttributes)[number];
1615
- declare class AirPlayButton extends VindralButton {
1616
- #private;
1617
- static observedAttributes: string[];
1618
- constructor();
1619
- connectedCallback(): void;
1620
- disconnectedCallback(): void;
1621
- attributeChangedCallback(name: string, old: string, value: string): void;
1622
- set isAirPlaying(value: boolean);
1623
- get isAirPlaying(): boolean;
1624
- protected handleClick(_: Event): void;
1625
- }
1626
1634
  declare class VindralMenuButton extends VindralButton {
1627
1635
  #private;
1628
1636
  constructor();
@@ -1656,6 +1664,18 @@ declare class AdvancedRenditionMenuList extends HTMLElement {
1656
1664
  handleEvent: (event: Event) => void;
1657
1665
  focus(): void;
1658
1666
  }
1667
+ type AirPlayButtonAttributes = (typeof AirPlayButton.observedAttributes)[number];
1668
+ declare class AirPlayButton extends VindralButton {
1669
+ #private;
1670
+ static observedAttributes: string[];
1671
+ constructor();
1672
+ connectedCallback(): void;
1673
+ disconnectedCallback(): void;
1674
+ attributeChangedCallback(name: string, old: string, value: string): void;
1675
+ set isAirPlaying(value: boolean);
1676
+ get isAirPlaying(): boolean;
1677
+ protected handleClick(_: Event): void;
1678
+ }
1659
1679
  type BufferingIconAttributes = (typeof BufferingIcon.observedAttributes)[number];
1660
1680
  declare class BufferingIcon extends HTMLElement {
1661
1681
  #private;
@@ -1753,15 +1773,15 @@ interface AirPlaySenderEvents {
1753
1773
  /**
1754
1774
  * When airplay targets are available.
1755
1775
  */
1756
- ["available"]: void;
1776
+ available: void;
1757
1777
  /**
1758
1778
  * When a connection has been established with an airplay target.
1759
1779
  */
1760
- ["connected"]: void;
1780
+ connected: void;
1761
1781
  /**
1762
1782
  * When the airplay target has lost or stopped a connection.
1763
1783
  */
1764
- ["disconnected"]: void;
1784
+ disconnected: void;
1765
1785
  }
1766
1786
  interface AirPlayConfig {
1767
1787
  /**
@@ -1820,7 +1840,7 @@ declare class AirPlaySender extends Emitter<AirPlaySenderEvents> {
1820
1840
  private checkHlsUrl;
1821
1841
  }
1822
1842
  interface FullscreenEvents {
1823
- ["on fullscreen change"]: boolean;
1843
+ "on fullscreen change": boolean;
1824
1844
  }
1825
1845
  declare class Fullscreen extends Emitter<FullscreenEvents> {
1826
1846
  private container;
@@ -1841,7 +1861,7 @@ type ControllerAttributes = (typeof Controller.observedAttributes)[number];
1841
1861
  declare class Controller extends HTMLElement {
1842
1862
  #private;
1843
1863
  static observedAttributes: readonly [
1844
- ...("language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src")[],
1864
+ ...("language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src" | "debug-panel-open" | "target-buffer-time" | "drift" | "playback-latency" | "connection-state")[],
1845
1865
  "url",
1846
1866
  "edge-url",
1847
1867
  "target-buffer-time",
@@ -1964,7 +1984,7 @@ declare class PlayButton extends VindralButton {
1964
1984
  type PlayerAttributes = (typeof Player.observedAttributes)[number];
1965
1985
  declare class Player extends HTMLElement {
1966
1986
  #private;
1967
- static observedAttributes: readonly ("title" | "offline" | "advanced" | "poster" | "language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src" | "url" | "decoders" | "edge-url" | "target-buffer-time" | "cast-receiver-id" | "cast-background" | "log-level" | "max-size" | "min-buffer-time" | "max-buffer-time" | "max-audio-bit-rate" | "burst-enabled" | "mse-enabled" | "mse-opus-enabled" | "ios-background-play-enabled" | "ios-wake-lock-enabled" | "stream-to-media-element-enabled" | "ios-media-element-enabled" | "telemetry-enabled" | "video-codecs" | "drm-headers" | "drm-queryparams" | "drm-widevine-video-robustness" | "drm-widevine-audio-robustness" | "drm-playready-video-robustness" | "drm-playready-audio-robustness" | "webtransport-enabled" | "webcodecs-hardware-acceleration" | "offscreen-canvas-enabled" | "reconnect-retries" | "auto-instance-enabled" | "advanced-rendition-menu-enabled" | "refresh-poster-enabled" | "stream-poll-enabled")[];
1987
+ static observedAttributes: readonly ("title" | "offline" | "advanced" | "poster" | "language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src" | "debug-panel-open" | "target-buffer-time" | "drift" | "playback-latency" | "connection-state" | "url" | "decoders" | "min-buffer-time" | "max-buffer-time" | "edge-url" | "cast-receiver-id" | "cast-background" | "log-level" | "max-size" | "max-audio-bit-rate" | "burst-enabled" | "mse-enabled" | "mse-opus-enabled" | "ios-background-play-enabled" | "ios-wake-lock-enabled" | "stream-to-media-element-enabled" | "ios-media-element-enabled" | "telemetry-enabled" | "video-codecs" | "drm-headers" | "drm-queryparams" | "drm-widevine-video-robustness" | "drm-widevine-audio-robustness" | "drm-playready-video-robustness" | "drm-playready-audio-robustness" | "webtransport-enabled" | "webcodecs-hardware-acceleration" | "offscreen-canvas-enabled" | "reconnect-retries" | "auto-instance-enabled" | "advanced-rendition-menu-enabled" | "refresh-poster-enabled" | "stream-poll-enabled")[];
1968
1988
  constructor();
1969
1989
  connectedCallback(): void;
1970
1990
  disconnectedCallback(): void;
package/react.js CHANGED
@@ -1 +0,0 @@
1
-
@@ -1,2 +1,5 @@
1
- import { registerComponents as o } from "./player.js";
2
- o();
1
+ import "./Dxs5czI4.js";
2
+ import { t as e } from "./BFS4Hwu8.js";
3
+ //#region src/vindral-player-component.ts
4
+ e();
5
+ //#endregion
package/BQEuFJLn.js DELETED
@@ -1,206 +0,0 @@
1
- var k = Object.defineProperty, I = Object.defineProperties;
2
- var T = Object.getOwnPropertyDescriptors;
3
- var w = Object.getOwnPropertySymbols;
4
- var M = Object.prototype.hasOwnProperty, C = Object.prototype.propertyIsEnumerable;
5
- var S = (s, e, t) => e in s ? k(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, b = (s, e) => {
6
- for (var t in e || (e = {}))
7
- M.call(e, t) && S(s, t, e[t]);
8
- if (w)
9
- for (var t of w(e))
10
- C.call(e, t) && S(s, t, e[t]);
11
- return s;
12
- }, y = (s, e) => I(s, T(e));
13
- var i = (s, e, t) => S(s, typeof e != "symbol" ? e + "" : e, t);
14
- var v = (s, e, t) => new Promise((r, n) => {
15
- var a = (o) => {
16
- try {
17
- c(t.next(o));
18
- } catch (d) {
19
- n(d);
20
- }
21
- }, l = (o) => {
22
- try {
23
- c(t.throw(o));
24
- } catch (d) {
25
- n(d);
26
- }
27
- }, c = (o) => o.done ? r(o.value) : Promise.resolve(o.value).then(a, l);
28
- c((t = t.apply(s, e)).next());
29
- });
30
- import { F as D, a as q, b as R, c as O } from "./DBHv5ggB.js";
31
- class E {
32
- constructor() {
33
- i(this, "map", /* @__PURE__ */ new Map());
34
- }
35
- enqueue(e, t) {
36
- const r = this.map.get(e);
37
- r ? r.push(t) : this.map.set(e, [t]);
38
- }
39
- dequeue(e) {
40
- const t = this.map.get(e);
41
- if (t && t.length > 0) {
42
- const r = t.shift();
43
- return t.length === 0 && this.map.delete(e), r;
44
- }
45
- }
46
- /**
47
- * Dequeue by exact timestamp, falling back to the oldest pending entry
48
- * when the decoder outputs a timestamp that differs from input.
49
- *
50
- * Safe for audio because all audio frames are independently decodable
51
- * key frames — there's no B-frame reordering that could cause metadata
52
- * mismatches like in video.
53
- */
54
- dequeueWithFallback(e) {
55
- const t = this.dequeue(e);
56
- if (t !== void 0) return t;
57
- for (const [r, n] of this.map)
58
- if (n.length > 0) {
59
- const a = n.shift();
60
- return n.length === 0 && this.map.delete(r), a;
61
- }
62
- }
63
- removeLast(e) {
64
- const t = this.map.get(e);
65
- !t || t.length === 0 || (t.pop(), t.length === 0 && this.map.delete(e));
66
- }
67
- clear() {
68
- this.map.clear();
69
- }
70
- }
71
- const $ = globalThis, u = class u {
72
- constructor(e) {
73
- i(this, "decodedSamples", []);
74
- i(this, "decoder", null);
75
- i(this, "logger");
76
- i(this, "initSegments", /* @__PURE__ */ new Map());
77
- i(this, "previousSample");
78
- i(this, "previousCodec");
79
- i(this, "pendingSamples", new E());
80
- i(this, "errors", new D(10));
81
- i(this, "resetDecoderState", () => {
82
- this.pendingSamples.clear(), this.previousSample = void 0, this.previousCodec = void 0;
83
- });
84
- i(this, "ensureDecoder", () => ((!this.decoder || this.decoder.state === "closed") && (this.decoder = this.createDecoder()), this.decoder));
85
- i(this, "createDecoder", () => new AudioDecoder({
86
- output: (e) => {
87
- const t = this.pendingSamples.dequeueWithFallback(e.timestamp);
88
- if (!t) {
89
- e.close();
90
- return;
91
- }
92
- const { sample: r, decodeStartTime: n } = t;
93
- try {
94
- const a = e.numberOfFrames, l = e.numberOfChannels, c = e.sampleRate, o = e.timestamp, d = e.duration, p = new Float32Array(a * l);
95
- e.copyTo(p, { planeIndex: 0, format: "f32" });
96
- const h = Math.round(o * r.timescale / 1e6), f = typeof d == "number" && Number.isFinite(d) ? Math.max(0, Math.round(d * r.timescale / 1e6)) : r.duration, g = y(b({}, r), {
97
- timestamp: h,
98
- duration: f,
99
- type: "audio",
100
- format: "f32",
101
- data: p,
102
- sampleRate: c,
103
- channels: l,
104
- statistics: {
105
- decodeTime: Math.max(performance.now() - n, 0),
106
- transportTimeFromWorker: 0,
107
- transportTimeToWorker: 0,
108
- samplesInBatch: 1
109
- }
110
- });
111
- this.decodedSamples.push(g);
112
- } finally {
113
- e.close();
114
- }
115
- },
116
- error: (e) => {
117
- this.logger.error("Decoder error:", e.name, e.message), this.resetDecoderState(), this.errors.push(e);
118
- }
119
- }));
120
- /**
121
- * Build AudioDecoderConfig codec string from audio codec type.
122
- */
123
- i(this, "buildCodecString", q);
124
- /**
125
- * Get the description for AudioDecoderConfig.
126
- * Uses init segment data if available, otherwise generates codec-specific description.
127
- */
128
- i(this, "getDescription", (e, t) => {
129
- const r = this.initSegments.get(t.renditionId);
130
- if (r && r.data.byteLength > 0 && r.codec === e)
131
- return r.data;
132
- if (e === "opus")
133
- return R(t.channels, t.sampleRate);
134
- if (e === "aac")
135
- return O(t.channels, t.sampleRate);
136
- });
137
- i(this, "unload", () => {
138
- this.decodedSamples = [], this.resetDecoderState(), this.decoder && this.decoder.state !== "closed" && this.decoder.close(), this.decoder = null;
139
- });
140
- i(this, "initSegment", (e) => {
141
- this.initSegments.set(e.renditionId, e);
142
- });
143
- i(this, "enqueue", (e) => {
144
- var d, p;
145
- const t = this.ensureDecoder(), r = e.codec, n = ((d = this.previousSample) == null ? void 0 : d.channelId) !== e.channelId, a = ((p = this.previousSample) == null ? void 0 : p.renditionId) !== e.renditionId, l = this.previousCodec !== r;
146
- if (!this.previousSample || n || a || l) {
147
- this.previousSample && t.state === "configured" && t.flush().catch((m) => {
148
- this.logger.warn("Failed to flush before reconfiguration:", m);
149
- });
150
- const h = this.buildCodecString(r), f = this.getDescription(r, e), g = {
151
- codec: h,
152
- sampleRate: e.sampleRate,
153
- numberOfChannels: e.channels,
154
- description: f
155
- };
156
- try {
157
- t.configure(g), this.previousCodec = r;
158
- } catch (m) {
159
- this.logger.error(
160
- `Failed to configure decoder for ${r} (rendition ${e.renditionId}), dropping sample`,
161
- m
162
- ), this.errors.push(m instanceof Error ? m : new Error(`Failed to configure decoder for ${r}`)), this.resetDecoderState(), this.ensureDecoder();
163
- return;
164
- }
165
- }
166
- if (e.timescale <= 0) {
167
- this.logger.error(`Invalid timescale ${e.timescale} in sample, dropping sample`);
168
- return;
169
- }
170
- this.previousSample = e;
171
- const c = Math.floor(1e6 * e.timestamp / e.timescale), o = Math.floor(1e6 * e.duration / e.timescale);
172
- try {
173
- const h = new EncodedAudioChunk({
174
- // Audio codecs (Opus, AAC, MP3) always produce independently decodable frames
175
- type: "key",
176
- timestamp: c,
177
- duration: o > 0 ? o : void 0,
178
- data: e.data
179
- });
180
- this.pendingSamples.enqueue(c, { sample: e, decodeStartTime: performance.now() }), t.decode(h);
181
- } catch (h) {
182
- this.logger.error("Failed to decode chunk:", h), this.pendingSamples.removeLast(c), t.state === "closed" && (this.resetDecoderState(), this.ensureDecoder());
183
- }
184
- });
185
- i(this, "flush", () => v(this, null, function* () {
186
- if (this.decoder && this.decoder.state === "configured")
187
- try {
188
- yield this.decoder.flush();
189
- } catch (e) {
190
- this.logger.error("Failed to flush decoder:", e), this.resetDecoderState();
191
- }
192
- }));
193
- i(this, "error", () => this.errors.pop());
194
- i(this, "take", () => this.decodedSamples.shift());
195
- this.logger = e, this.decoder = this.createDecoder();
196
- }
197
- };
198
- i(u, "isSupported", () => typeof $.AudioDecoder != "undefined"), i(u, "create", (e) => v(null, null, function* () {
199
- if (!u.isSupported())
200
- throw new Error("WebCodecs AudioDecoder is not supported in this environment");
201
- return new u(e);
202
- }));
203
- let F = u;
204
- export {
205
- F as WebCodecsAudioDecoderContext
206
- };