@stinkycomputing/web-live-player 0.1.15 → 0.1.16
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/web-live-player.mjs
CHANGED
|
@@ -1093,6 +1093,7 @@ const G = class G extends lU {
|
|
|
1093
1093
|
l(this, "audioPlayer", null);
|
|
1094
1094
|
l(this, "ownsAudioContext", !1);
|
|
1095
1095
|
l(this, "audioCodecData", null);
|
|
1096
|
+
l(this, "volume", 1);
|
|
1096
1097
|
// Timing tracking: maps frame timestamp to arrival time
|
|
1097
1098
|
l(this, "arrivalTimes", /* @__PURE__ */ new Map());
|
|
1098
1099
|
// Track keyframe status per timestamp
|
|
@@ -1137,15 +1138,20 @@ const G = class G extends lU {
|
|
|
1137
1138
|
}
|
|
1138
1139
|
/**
|
|
1139
1140
|
* Set audio volume (0-1)
|
|
1141
|
+
*
|
|
1142
|
+
* The value is remembered and re-applied whenever a new audio player is
|
|
1143
|
+
* created, so calls made before audio arrives (or across codec changes)
|
|
1144
|
+
* are not lost.
|
|
1140
1145
|
*/
|
|
1141
1146
|
setVolume(U) {
|
|
1142
|
-
|
|
1147
|
+
var Q;
|
|
1148
|
+
this.volume = Math.max(0, Math.min(1, U)), (Q = this.audioPlayer) == null || Q.setVolume(this.volume);
|
|
1143
1149
|
}
|
|
1144
1150
|
/**
|
|
1145
1151
|
* Get current audio volume (0-1)
|
|
1146
1152
|
*/
|
|
1147
1153
|
getVolume() {
|
|
1148
|
-
return
|
|
1154
|
+
return this.volume;
|
|
1149
1155
|
}
|
|
1150
1156
|
/**
|
|
1151
1157
|
* Set the stream source (dependency injection)
|
|
@@ -1329,11 +1335,11 @@ const G = class G extends lU {
|
|
|
1329
1335
|
this.currentCodecData = (W = Q.header.media) == null ? void 0 : W.codecData, this.isConfiguring = !0, this.pendingDuringConfig = [Q], await this.configureDecoder((Z = Q.header.media) == null ? void 0 : Z.codecData), this.isConfiguring = !1, this.waitingForKeyframe = !0;
|
|
1330
1336
|
const a = this.pendingDuringConfig;
|
|
1331
1337
|
this.pendingDuringConfig = [], this.logger.info(`Processing ${a.length} frames queued during configuration`);
|
|
1332
|
-
for (const
|
|
1338
|
+
for (const m of a)
|
|
1333
1339
|
await this.handleStreamData({
|
|
1334
1340
|
trackName: U.trackName,
|
|
1335
1341
|
streamType: U.streamType,
|
|
1336
|
-
data:
|
|
1342
|
+
data: m
|
|
1337
1343
|
});
|
|
1338
1344
|
return;
|
|
1339
1345
|
}
|
|
@@ -1355,18 +1361,18 @@ const G = class G extends lU {
|
|
|
1355
1361
|
this.logger.debug("Keyframe received, resuming decode"), this.waitingForKeyframe = !1, this.lastWaitingForKeyframeLog = 0;
|
|
1356
1362
|
}
|
|
1357
1363
|
try {
|
|
1358
|
-
const a = performance.now(),
|
|
1364
|
+
const a = performance.now(), m = (i = (C = Q.header.media) == null ? void 0 : C.codecData) != null && i.timebaseDen && ((I = (E = Q.header.media) == null ? void 0 : E.codecData) != null && I.timebaseNum) ? { num: Q.header.media.codecData.timebaseNum, den: Q.header.media.codecData.timebaseDen } : { num: 1, den: 1e6 }, b = { num: 1, den: 1e6 }, g = P(((c = Q.header.media) == null ? void 0 : c.pts) ?? 0, m, b);
|
|
1359
1365
|
if (this.arrivalTimes.set(g, a), this.keyframeStatus.set(g, V), this.lastVideoTimestampUs >= 0 && g > this.lastVideoTimestampUs) {
|
|
1360
1366
|
const D = g - this.lastVideoTimestampUs;
|
|
1361
1367
|
if (D > 5e3 && D < 1e6 && (this.fpsEstimateSamples.push(D), this.fpsEstimateSamples.length > G.FPS_SAMPLE_COUNT && this.fpsEstimateSamples.shift(), this.fpsEstimateSamples.length >= 3)) {
|
|
1362
|
-
const
|
|
1363
|
-
this.estimatedFrameRate = Math.round(1e6 /
|
|
1368
|
+
const M = this.fpsEstimateSamples.reduce((x, w) => x + w, 0) / this.fpsEstimateSamples.length;
|
|
1369
|
+
this.estimatedFrameRate = Math.round(1e6 / M);
|
|
1364
1370
|
}
|
|
1365
1371
|
}
|
|
1366
1372
|
if (this.lastVideoTimestampUs = g, this.arrivalTimes.size > 100) {
|
|
1367
1373
|
const D = [...this.arrivalTimes.entries()];
|
|
1368
|
-
for (let
|
|
1369
|
-
this.arrivalTimes.delete(D[
|
|
1374
|
+
for (let M = 0; M < D.length - 100; M++)
|
|
1375
|
+
this.arrivalTimes.delete(D[M][0]), this.keyframeStatus.delete(D[M][0]);
|
|
1370
1376
|
}
|
|
1371
1377
|
this.decoder.decodeBinary(Q);
|
|
1372
1378
|
} catch (a) {
|
|
@@ -1383,7 +1389,7 @@ const G = class G extends lU {
|
|
|
1383
1389
|
const Q = this.audioCodecData ?? void 0;
|
|
1384
1390
|
(R = (B = U.header) == null ? void 0 : B.media) != null && R.codecData && _(Q, U.header.media.codecData) && (this.audioCodecData = U.header.media.codecData, this.audioPlayer && (this.audioPlayer.dispose(), this.audioPlayer = null), this.audioContext || (this.config.audioContext ? (this.audioContext = this.config.audioContext, this.ownsAudioContext = !1) : (this.audioContext = new AudioContext(), this.ownsAudioContext = !0)), this.audioPlayer = new hU(this.audioContext, {
|
|
1385
1391
|
bufferDelayMs: this.config.bufferDelayMs ?? 100
|
|
1386
|
-
}), await this.audioPlayer.init((d = U.header.media) == null ? void 0 : d.codecData), this.audioPlayer.start(), this.logger.info(`Audio player started: ${(J = (V = U.header.media) == null ? void 0 : V.codecData) == null ? void 0 : J.codecType}, ${(S = (n = U.header.media) == null ? void 0 : n.codecData) == null ? void 0 : S.sampleRate}Hz, ${(W = (t = U.header.media) == null ? void 0 : t.codecData) == null ? void 0 : W.channels}ch`)), this.audioPlayer && U.payload && U.header && this.audioPlayer.decode(U.payload, (Z = U.header.media) == null ? void 0 : Z.pts);
|
|
1392
|
+
}), await this.audioPlayer.init((d = U.header.media) == null ? void 0 : d.codecData), this.audioPlayer.setVolume(this.volume), this.audioPlayer.start(), this.logger.info(`Audio player started: ${(J = (V = U.header.media) == null ? void 0 : V.codecData) == null ? void 0 : J.codecType}, ${(S = (n = U.header.media) == null ? void 0 : n.codecData) == null ? void 0 : S.sampleRate}Hz, ${(W = (t = U.header.media) == null ? void 0 : t.codecData) == null ? void 0 : W.channels}ch`)), this.audioPlayer && U.payload && U.header && this.audioPlayer.decode(U.payload, (Z = U.header.media) == null ? void 0 : Z.pts);
|
|
1387
1393
|
}
|
|
1388
1394
|
/**
|
|
1389
1395
|
* Configure the decoder for a specific codec
|
|
@@ -1613,8 +1619,8 @@ class FU {
|
|
|
1613
1619
|
});
|
|
1614
1620
|
if (!a.ok && a.status !== 206)
|
|
1615
1621
|
throw new Error(`Failed to fetch chunk: ${a.status} ${a.statusText}`);
|
|
1616
|
-
const
|
|
1617
|
-
if (b.fileStart = Q, Q +=
|
|
1622
|
+
const m = await a.arrayBuffer(), b = m;
|
|
1623
|
+
if (b.fileStart = Q, Q += m.byteLength, this.loadedBytes = Q, (o = (T = this.events).onProgress) == null || o.call(T, this.loadedBytes, this.fileSize), (r = this.mp4File) == null || r.appendBuffer(b), B && V) {
|
|
1618
1624
|
this.continueLoadingInBackground(F, Q, U), R(this.fileInfo);
|
|
1619
1625
|
return;
|
|
1620
1626
|
}
|
|
@@ -1726,7 +1732,7 @@ class FU {
|
|
|
1726
1732
|
* Handle file ready event
|
|
1727
1733
|
*/
|
|
1728
1734
|
handleFileReady(F) {
|
|
1729
|
-
var U, Q, B, R, d, V, J, n, S, t, W, Z, s, h, k, T, o, r, C, i, E, I, c, a,
|
|
1735
|
+
var U, Q, B, R, d, V, J, n, S, t, W, Z, s, h, k, T, o, r, C, i, E, I, c, a, m, b, g, D, M, x;
|
|
1730
1736
|
if (F.videoTracks.length > 0) {
|
|
1731
1737
|
this.videoTrack = F.videoTracks[0], this.videoTrackId = this.videoTrack.id, this.totalVideoSamples = this.videoTrack.nb_samples;
|
|
1732
1738
|
const w = (U = this.mp4File) == null ? void 0 : U.getTrackById(this.videoTrackId);
|
|
@@ -1776,12 +1782,12 @@ class FU {
|
|
|
1776
1782
|
duration: this.videoTrack.duration / this.videoTrack.timescale,
|
|
1777
1783
|
timescale: this.videoTrack.timescale,
|
|
1778
1784
|
width: ((a = this.videoTrack.video) == null ? void 0 : a.width) ?? 0,
|
|
1779
|
-
height: ((
|
|
1785
|
+
height: ((m = this.videoTrack.video) == null ? void 0 : m.height) ?? 0,
|
|
1780
1786
|
videoCodec: this.videoTrack.codec,
|
|
1781
1787
|
frameRate: this.videoTrack.nb_samples / (this.videoTrack.duration / this.videoTrack.timescale),
|
|
1782
1788
|
bitrate: this.videoTrack.bitrate,
|
|
1783
1789
|
isMoovAtStart: ((b = this.mp4File) == null ? void 0 : b.isProgressive) ?? void 0
|
|
1784
|
-
}, this.audioTrack && (this.fileInfo.audioCodec = this.audioTrack.codec, this.fileInfo.audioChannels = (g = this.audioTrack.audio) == null ? void 0 : g.channel_count, this.fileInfo.audioSampleRate = (D = this.audioTrack.audio) == null ? void 0 : D.sample_rate), this.requestSamples(), (x = (
|
|
1790
|
+
}, this.audioTrack && (this.fileInfo.audioCodec = this.audioTrack.codec, this.fileInfo.audioChannels = (g = this.audioTrack.audio) == null ? void 0 : g.channel_count, this.fileInfo.audioSampleRate = (D = this.audioTrack.audio) == null ? void 0 : D.sample_rate), this.requestSamples(), (x = (M = this.events).onReady) == null || x.call(M, this.fileInfo);
|
|
1785
1791
|
}
|
|
1786
1792
|
/**
|
|
1787
1793
|
* Request samples to be extracted
|
|
@@ -2195,6 +2201,7 @@ class rU extends lU {
|
|
|
2195
2201
|
l(this, "audioPlayer", null);
|
|
2196
2202
|
l(this, "ownsAudioContext", !1);
|
|
2197
2203
|
l(this, "audioInitialized", !1);
|
|
2204
|
+
l(this, "volume", 1);
|
|
2198
2205
|
// File info
|
|
2199
2206
|
l(this, "fileInfo", null);
|
|
2200
2207
|
// Frame buffer - sorted by timestamp
|
|
@@ -2292,15 +2299,19 @@ class rU extends lU {
|
|
|
2292
2299
|
}
|
|
2293
2300
|
/**
|
|
2294
2301
|
* Set audio volume (0-1)
|
|
2302
|
+
*
|
|
2303
|
+
* The value is remembered and re-applied whenever the audio decoder is
|
|
2304
|
+
* (re)initialized, so calls made before the decoder is ready are not lost.
|
|
2295
2305
|
*/
|
|
2296
2306
|
setVolume(U) {
|
|
2297
|
-
|
|
2307
|
+
var Q;
|
|
2308
|
+
this.volume = Math.max(0, Math.min(1, U)), (Q = this.audioPlayer) == null || Q.setVolume(this.volume);
|
|
2298
2309
|
}
|
|
2299
2310
|
/**
|
|
2300
2311
|
* Get current audio volume (0-1)
|
|
2301
2312
|
*/
|
|
2302
2313
|
getVolume() {
|
|
2303
|
-
return
|
|
2314
|
+
return this.volume;
|
|
2304
2315
|
}
|
|
2305
2316
|
/**
|
|
2306
2317
|
* Load a video file from URL
|
|
@@ -2391,7 +2402,7 @@ class rU extends lU {
|
|
|
2391
2402
|
this.fileInfo.audioSampleRate ?? 48e3,
|
|
2392
2403
|
this.fileInfo.audioChannels ?? 2,
|
|
2393
2404
|
U ?? void 0
|
|
2394
|
-
), this.audioInitialized = !0, this.logger.info(`Audio decoder configured: ${this.fileInfo.audioCodec}`), this.feedAudioDecoder();
|
|
2405
|
+
), this.audioPlayer.setVolume(this.volume), this.audioInitialized = !0, this.logger.info(`Audio decoder configured: ${this.fileInfo.audioCodec}`), this.feedAudioDecoder();
|
|
2395
2406
|
} catch (U) {
|
|
2396
2407
|
this.logger.warn(`Failed to initialize audio: ${U}`), this.audioPlayer = null;
|
|
2397
2408
|
}
|
|
@@ -2820,11 +2831,11 @@ class pU extends RU {
|
|
|
2820
2831
|
function yU(e) {
|
|
2821
2832
|
return new pU(e);
|
|
2822
2833
|
}
|
|
2823
|
-
function
|
|
2834
|
+
function mU(e) {
|
|
2824
2835
|
return e instanceof VideoFrame;
|
|
2825
2836
|
}
|
|
2826
2837
|
function HU(e) {
|
|
2827
|
-
return !
|
|
2838
|
+
return !mU(e) && "y" in e && "u" in e && "v" in e;
|
|
2828
2839
|
}
|
|
2829
2840
|
const y = {
|
|
2830
2841
|
video: {
|
|
@@ -2881,7 +2892,7 @@ function xU(e) {
|
|
|
2881
2892
|
function vU(e) {
|
|
2882
2893
|
return e >= N.CODEC_TYPE_AUDIO_OPUS && e <= N.CODEC_TYPE_AUDIO_PCM;
|
|
2883
2894
|
}
|
|
2884
|
-
class
|
|
2895
|
+
class MU {
|
|
2885
2896
|
constructor(F, U, Q, B) {
|
|
2886
2897
|
l(this, "audioWorker");
|
|
2887
2898
|
l(this, "videoWorker");
|
|
@@ -3391,7 +3402,7 @@ class v {
|
|
|
3391
3402
|
channels: (Q = this.audioMetadata) == null ? void 0 : Q.channels,
|
|
3392
3403
|
sampleRate: (B = this.audioMetadata) == null ? void 0 : B.sampleRate
|
|
3393
3404
|
} : void 0;
|
|
3394
|
-
this.encoder = new
|
|
3405
|
+
this.encoder = new MU(
|
|
3395
3406
|
this.mediaStream,
|
|
3396
3407
|
J,
|
|
3397
3408
|
n,
|
|
@@ -3508,7 +3519,7 @@ export {
|
|
|
3508
3519
|
A as LiveVideoPlayer,
|
|
3509
3520
|
FU as MP4FileSource,
|
|
3510
3521
|
v as MediaCapture,
|
|
3511
|
-
|
|
3522
|
+
MU as MediaStreamEncoder,
|
|
3512
3523
|
K as MoQCaptureSink,
|
|
3513
3524
|
VU as MoQSource,
|
|
3514
3525
|
UU as WasmDecoder,
|
|
@@ -3526,7 +3537,7 @@ export {
|
|
|
3526
3537
|
yU as createWebSocketSource,
|
|
3527
3538
|
vU as isAudioCodec,
|
|
3528
3539
|
xU as isVideoCodec,
|
|
3529
|
-
|
|
3540
|
+
mU as isVideoFrame,
|
|
3530
3541
|
HU as isYUVFrame,
|
|
3531
3542
|
WU as silentLogger
|
|
3532
3543
|
};
|
package/package.json
CHANGED