@gcorevideo/player 2.22.16 → 2.22.17
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/core.js +6 -8
- package/dist/index.css +1338 -1338
- package/dist/index.js +361 -439
- package/dist/player.d.ts +216 -159
- package/dist/plugins/index.css +1463 -1463
- package/dist/plugins/index.js +354 -427
- package/docs/api/player.clapprstats.exportmetrics.md +1 -1
- package/docs/api/player.clapprstats.md +5 -15
- package/docs/api/player.clapprstatssettings.md +13 -0
- package/docs/api/player.clips.destroy.md +18 -0
- package/docs/api/player.clips.disable.md +18 -0
- package/docs/api/player.clips.enable.md +18 -0
- package/docs/api/player.clips.md +170 -0
- package/docs/api/player.clips.render.md +18 -0
- package/docs/api/player.clips.supportedversion.md +16 -0
- package/docs/api/player.clips.version.md +14 -0
- package/docs/api/player.clipspluginsettings.md +2 -2
- package/docs/api/player.clipspluginsettings.text.md +1 -1
- package/docs/api/player.md +27 -18
- package/docs/api/player.mediacontrol.md +1 -1
- package/docs/api/{player.mediacontrol.getelement.md → player.mediacontrol.mount.md} +20 -7
- package/docs/api/player.mediacontrolleftelement.md +1 -1
- package/docs/api/{player.clapprnerdstats._constructor_.md → player.nerdstats._constructor_.md} +3 -3
- package/docs/api/{player.clapprnerdstats.md → player.nerdstats.md} +5 -5
- package/docs/api/player.qualitylevel.height.md +1 -1
- package/docs/api/player.qualitylevel.level.md +1 -1
- package/docs/api/player.qualitylevel.md +4 -4
- package/docs/api/player.qualitylevel.width.md +1 -1
- package/docs/api/player.timeposition.current.md +1 -1
- package/docs/api/player.timeposition.md +2 -2
- package/docs/api/player.timeposition.total.md +1 -1
- package/docs/api/player.timeprogress.md +6 -4
- package/docs/api/player.timevalue.md +1 -1
- package/lib/index.plugins.d.ts +2 -1
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +2 -1
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +5 -7
- package/lib/playback.types.d.ts +22 -9
- package/lib/playback.types.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +4 -0
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +20 -23
- package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts +83 -0
- package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts.map +1 -0
- package/lib/plugins/clappr-nerd-stats/NerdStats.js +339 -0
- package/lib/plugins/clappr-stats/ClapprStats.d.ts +27 -32
- package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
- package/lib/plugins/clappr-stats/ClapprStats.js +94 -202
- package/lib/plugins/clappr-stats/types.d.ts +65 -24
- package/lib/plugins/clappr-stats/types.d.ts.map +1 -1
- package/lib/plugins/clappr-stats/types.js +37 -2
- package/lib/plugins/clappr-stats/utils.d.ts.map +1 -1
- package/lib/plugins/clappr-stats/utils.js +1 -2
- package/lib/testUtils.d.ts +2 -1
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +3 -2
- package/package.json +1 -1
- package/src/index.plugins.ts +2 -1
- package/src/playback/dash-playback/DashPlayback.ts +5 -8
- package/src/playback.types.ts +23 -8
- package/src/plugins/clappr-nerd-stats/{ClapprNerdStats.ts → NerdStats.ts} +25 -30
- package/src/plugins/clappr-stats/ClapprStats.ts +242 -306
- package/src/plugins/clappr-stats/__tests__/ClapprStats.test.ts +133 -0
- package/src/plugins/clappr-stats/types.ts +72 -25
- package/src/plugins/clappr-stats/utils.ts +1 -2
- package/src/plugins/error-screen/__tests__/ErrorScreen.test.ts +3 -4
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -0
- package/src/testUtils.ts +3 -2
- package/temp/player.api.json +311 -159
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.clapprstats.setupdatemetrics.md +0 -56
- package/docs/api/player.clipsplugin.gettext.md +0 -58
- package/docs/api/player.clipsplugin.md +0 -59
package/dist/plugins/index.js
CHANGED
|
@@ -10310,6 +10310,339 @@ class BottomGear extends UICorePlugin {
|
|
|
10310
10310
|
}
|
|
10311
10311
|
}
|
|
10312
10312
|
|
|
10313
|
+
/**
|
|
10314
|
+
* @beta
|
|
10315
|
+
*/
|
|
10316
|
+
var Chronograph;
|
|
10317
|
+
(function (Chronograph) {
|
|
10318
|
+
Chronograph["Startup"] = "startup";
|
|
10319
|
+
Chronograph["Watch"] = "watch";
|
|
10320
|
+
Chronograph["Pause"] = "pause";
|
|
10321
|
+
Chronograph["Buffering"] = "buffering";
|
|
10322
|
+
Chronograph["Session"] = "session";
|
|
10323
|
+
// Latency = 'latency',
|
|
10324
|
+
})(Chronograph || (Chronograph = {}));
|
|
10325
|
+
/**
|
|
10326
|
+
* @beta
|
|
10327
|
+
*/
|
|
10328
|
+
var Counter;
|
|
10329
|
+
(function (Counter) {
|
|
10330
|
+
Counter["Play"] = "play";
|
|
10331
|
+
Counter["Pause"] = "pause";
|
|
10332
|
+
Counter["Error"] = "error";
|
|
10333
|
+
Counter["Buffering"] = "buffering";
|
|
10334
|
+
Counter["DecodedFrames"] = "decodedFrames";
|
|
10335
|
+
Counter["DroppedFrames"] = "droppedFrames";
|
|
10336
|
+
Counter["Fps"] = "fps";
|
|
10337
|
+
Counter["ChangeLevel"] = "changeLevel";
|
|
10338
|
+
Counter["Seek"] = "seek";
|
|
10339
|
+
Counter["Fullscreen"] = "fullscreen";
|
|
10340
|
+
Counter["DvrUsage"] = "dvrUsage";
|
|
10341
|
+
})(Counter || (Counter = {}));
|
|
10342
|
+
/**
|
|
10343
|
+
* @beta
|
|
10344
|
+
*/
|
|
10345
|
+
var ClapprStatsEvents;
|
|
10346
|
+
(function (ClapprStatsEvents) {
|
|
10347
|
+
/**
|
|
10348
|
+
* Emitted periodically with current measurements.
|
|
10349
|
+
*/
|
|
10350
|
+
ClapprStatsEvents["REPORT"] = "clappr:stats:report";
|
|
10351
|
+
/**
|
|
10352
|
+
* Emitted when the playback reaches a certain percentage of the total duration.
|
|
10353
|
+
*/
|
|
10354
|
+
// PERCENTAGE = 'clappr:stats:percentage',
|
|
10355
|
+
})(ClapprStatsEvents || (ClapprStatsEvents = {}));
|
|
10356
|
+
|
|
10357
|
+
function newMetrics$1() {
|
|
10358
|
+
return {
|
|
10359
|
+
counters: {
|
|
10360
|
+
play: 0,
|
|
10361
|
+
pause: 0,
|
|
10362
|
+
error: 0,
|
|
10363
|
+
buffering: 0,
|
|
10364
|
+
decodedFrames: 0,
|
|
10365
|
+
droppedFrames: 0,
|
|
10366
|
+
fps: 0,
|
|
10367
|
+
changeLevel: 0,
|
|
10368
|
+
seek: 0,
|
|
10369
|
+
fullscreen: 0,
|
|
10370
|
+
dvrUsage: 0,
|
|
10371
|
+
},
|
|
10372
|
+
chrono: {
|
|
10373
|
+
startup: 0,
|
|
10374
|
+
watch: 0,
|
|
10375
|
+
pause: 0,
|
|
10376
|
+
buffering: 0,
|
|
10377
|
+
session: 0,
|
|
10378
|
+
},
|
|
10379
|
+
extra: {
|
|
10380
|
+
playbackName: '',
|
|
10381
|
+
playbackType: '',
|
|
10382
|
+
bitratesHistory: [],
|
|
10383
|
+
bitrateWeightedMean: 0,
|
|
10384
|
+
bitrateMostUsed: 0,
|
|
10385
|
+
buffersize: 0,
|
|
10386
|
+
watchHistory: [],
|
|
10387
|
+
watchedPercentage: 0,
|
|
10388
|
+
bufferingPercentage: 0,
|
|
10389
|
+
bandwidth: 0,
|
|
10390
|
+
duration: 0,
|
|
10391
|
+
currentTime: 0,
|
|
10392
|
+
},
|
|
10393
|
+
custom: {},
|
|
10394
|
+
};
|
|
10395
|
+
}
|
|
10396
|
+
|
|
10397
|
+
/**
|
|
10398
|
+
* `PLUGIN` that measures data about playback, which can be useful for analyzing performance and UX.
|
|
10399
|
+
* @beta
|
|
10400
|
+
* @remarks
|
|
10401
|
+
* This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
|
|
10402
|
+
*
|
|
10403
|
+
* Configuration options - {@link ClapprStatsSettings}
|
|
10404
|
+
*
|
|
10405
|
+
* Events - {@link ClapprStatsEvents}
|
|
10406
|
+
*/
|
|
10407
|
+
class ClapprStats extends ContainerPlugin {
|
|
10408
|
+
timerId = null;
|
|
10409
|
+
lastDecodedFramesCount = 0;
|
|
10410
|
+
metrics = newMetrics$1();
|
|
10411
|
+
timers = {
|
|
10412
|
+
[Chronograph.Startup]: 0,
|
|
10413
|
+
[Chronograph.Watch]: 0,
|
|
10414
|
+
[Chronograph.Pause]: 0,
|
|
10415
|
+
[Chronograph.Buffering]: 0,
|
|
10416
|
+
[Chronograph.Session]: 0,
|
|
10417
|
+
};
|
|
10418
|
+
runEach;
|
|
10419
|
+
/**
|
|
10420
|
+
* @internal
|
|
10421
|
+
*/
|
|
10422
|
+
get name() {
|
|
10423
|
+
return 'clappr_stats';
|
|
10424
|
+
}
|
|
10425
|
+
/**
|
|
10426
|
+
* @internal
|
|
10427
|
+
*/
|
|
10428
|
+
get supportedVersion() {
|
|
10429
|
+
return { min: CLAPPR_VERSION$1 };
|
|
10430
|
+
}
|
|
10431
|
+
get playbackName() {
|
|
10432
|
+
return String(this.container.playback.name || '');
|
|
10433
|
+
}
|
|
10434
|
+
get playbackType() {
|
|
10435
|
+
return this.container.getPlaybackType();
|
|
10436
|
+
}
|
|
10437
|
+
now() {
|
|
10438
|
+
const hasPerformanceSupport = window.performance && typeof window.performance.now === 'function';
|
|
10439
|
+
return hasPerformanceSupport
|
|
10440
|
+
? window.performance.now()
|
|
10441
|
+
: new Date().getTime();
|
|
10442
|
+
}
|
|
10443
|
+
inc(counter) {
|
|
10444
|
+
this.metrics.counters[counter] += 1;
|
|
10445
|
+
}
|
|
10446
|
+
// _timerHasStarted(timer) {
|
|
10447
|
+
// return this[`_start${timer}`] !== undefined;
|
|
10448
|
+
// }
|
|
10449
|
+
start(timer) {
|
|
10450
|
+
// this[`_start${timer}`] = this._now();
|
|
10451
|
+
this.timers[timer] = this.now();
|
|
10452
|
+
}
|
|
10453
|
+
stop(timer) {
|
|
10454
|
+
// this._metrics.timers[timer] += this._now() - this[`_start${timer}`];
|
|
10455
|
+
this.metrics.chrono[timer] += this.now() - this.timers[timer];
|
|
10456
|
+
}
|
|
10457
|
+
constructor(container) {
|
|
10458
|
+
super(container);
|
|
10459
|
+
this.runEach = container.options.clapprStats?.runEach ?? 5000;
|
|
10460
|
+
}
|
|
10461
|
+
/**
|
|
10462
|
+
* @internal
|
|
10463
|
+
*/
|
|
10464
|
+
bindEvents() {
|
|
10465
|
+
this.listenTo(this.container, Events.CONTAINER_BITRATE, this.onBitrate);
|
|
10466
|
+
this.listenTo(this.container, Events.CONTAINER_STOP, this.stopReporting);
|
|
10467
|
+
this.listenTo(this.container, Events.CONTAINER_ENDED, this.stopReporting);
|
|
10468
|
+
this.listenToOnce(this.container.playback, Events.PLAYBACK_PLAY_INTENT, this.startTimers);
|
|
10469
|
+
this.listenToOnce(this.container, Events.CONTAINER_PLAY, this.onFirstPlaying);
|
|
10470
|
+
this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay);
|
|
10471
|
+
this.listenTo(this.container, Events.CONTAINER_PAUSE, this.onPause);
|
|
10472
|
+
this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
10473
|
+
this.listenTo(this.container, Events.CONTAINER_SEEK, this.onSeek);
|
|
10474
|
+
this.listenTo(this.container, Events.CONTAINER_ERROR, () => this.inc(Counter.Error));
|
|
10475
|
+
this.listenTo(this.container, Events.CONTAINER_FULLSCREEN, () => this.inc(Counter.Fullscreen));
|
|
10476
|
+
this.listenTo(this.container, Events.CONTAINER_PLAYBACKDVRSTATECHANGED, (dvrInUse) => {
|
|
10477
|
+
dvrInUse && this.inc(Counter.DvrUsage);
|
|
10478
|
+
});
|
|
10479
|
+
this.listenTo(this.container.playback, Events.PLAYBACK_PROGRESS, this.onProgress);
|
|
10480
|
+
this.listenTo(this.container.playback, Events.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
|
|
10481
|
+
}
|
|
10482
|
+
/**
|
|
10483
|
+
* @internal
|
|
10484
|
+
*/
|
|
10485
|
+
destroy() {
|
|
10486
|
+
this.stopReporting();
|
|
10487
|
+
super.destroy();
|
|
10488
|
+
}
|
|
10489
|
+
/**
|
|
10490
|
+
* Returns the collected metrics.
|
|
10491
|
+
* @returns Measurements collected so far
|
|
10492
|
+
*/
|
|
10493
|
+
exportMetrics() {
|
|
10494
|
+
return structuredClone(this.metrics);
|
|
10495
|
+
}
|
|
10496
|
+
onBitrate(newBitrate) {
|
|
10497
|
+
const bitrate = newBitrate.bitrate;
|
|
10498
|
+
const now = this.now();
|
|
10499
|
+
if (this.metrics.extra.bitratesHistory.length > 0) {
|
|
10500
|
+
const last = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
|
|
10501
|
+
last.end = now;
|
|
10502
|
+
last.time = now - last.start;
|
|
10503
|
+
}
|
|
10504
|
+
this.metrics.extra.bitratesHistory.push({ start: this.now(), bitrate });
|
|
10505
|
+
this.inc(Counter.ChangeLevel);
|
|
10506
|
+
}
|
|
10507
|
+
stopReporting() {
|
|
10508
|
+
this.buildReport();
|
|
10509
|
+
if (this.timerId !== null) {
|
|
10510
|
+
clearInterval(this.timerId);
|
|
10511
|
+
this.timerId = null;
|
|
10512
|
+
}
|
|
10513
|
+
}
|
|
10514
|
+
startTimers() {
|
|
10515
|
+
this.timerId = setInterval(this.buildReport.bind(this), this.runEach);
|
|
10516
|
+
this.start(Chronograph.Session);
|
|
10517
|
+
this.start(Chronograph.Startup);
|
|
10518
|
+
}
|
|
10519
|
+
onFirstPlaying() {
|
|
10520
|
+
this.listenTo(this.container, Events.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
|
|
10521
|
+
this.start(Chronograph.Watch);
|
|
10522
|
+
this.stop(Chronograph.Startup);
|
|
10523
|
+
}
|
|
10524
|
+
playAfterPause() {
|
|
10525
|
+
this.listenTo(this.container, Events.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
|
|
10526
|
+
this.stop(Chronograph.Pause);
|
|
10527
|
+
this.start(Chronograph.Watch);
|
|
10528
|
+
}
|
|
10529
|
+
onPlay() {
|
|
10530
|
+
this.inc(Counter.Play);
|
|
10531
|
+
}
|
|
10532
|
+
onPause() {
|
|
10533
|
+
this.stop(Chronograph.Watch);
|
|
10534
|
+
this.start(Chronograph.Pause);
|
|
10535
|
+
this.inc(Counter.Pause);
|
|
10536
|
+
this.listenToOnce(this.container, Events.CONTAINER_PLAY, this.playAfterPause);
|
|
10537
|
+
this.stopListening(this.container, Events.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
|
|
10538
|
+
}
|
|
10539
|
+
onSeek(e) {
|
|
10540
|
+
this.inc(Counter.Seek);
|
|
10541
|
+
this.metrics.extra.watchHistory.push([e * 1000, e * 1000]);
|
|
10542
|
+
}
|
|
10543
|
+
onTimeUpdate(e) {
|
|
10544
|
+
const current = e.current * 1000, total = e.total * 1000, l = this.metrics.extra.watchHistory.length;
|
|
10545
|
+
this.metrics.extra.duration = total;
|
|
10546
|
+
this.metrics.extra.currentTime = current;
|
|
10547
|
+
// TODO what if it's a live stream?
|
|
10548
|
+
this.metrics.extra.watchedPercentage = (current / total) * 100;
|
|
10549
|
+
if (l === 0) {
|
|
10550
|
+
this.metrics.extra.watchHistory.push([current, current]);
|
|
10551
|
+
}
|
|
10552
|
+
else {
|
|
10553
|
+
this.metrics.extra.watchHistory[l - 1][1] = current;
|
|
10554
|
+
}
|
|
10555
|
+
if (this.metrics.extra.bitratesHistory.length > 0) {
|
|
10556
|
+
const lastBitrate = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
|
|
10557
|
+
if (!lastBitrate.end) {
|
|
10558
|
+
lastBitrate.time = this.now() - lastBitrate.start;
|
|
10559
|
+
}
|
|
10560
|
+
}
|
|
10561
|
+
this.onCompletion();
|
|
10562
|
+
}
|
|
10563
|
+
onContainerUpdateWhilePlaying() {
|
|
10564
|
+
if (this.container.playback.isPlaying()) {
|
|
10565
|
+
this.stop(Chronograph.Watch);
|
|
10566
|
+
this.start(Chronograph.Watch);
|
|
10567
|
+
}
|
|
10568
|
+
}
|
|
10569
|
+
onBuffering() {
|
|
10570
|
+
this.inc(Counter.Buffering);
|
|
10571
|
+
this.start(Chronograph.Buffering);
|
|
10572
|
+
this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERFULL, this.onBufferfull);
|
|
10573
|
+
}
|
|
10574
|
+
onBufferfull() {
|
|
10575
|
+
this.stop(Chronograph.Buffering);
|
|
10576
|
+
this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
10577
|
+
}
|
|
10578
|
+
onProgress(progress) {
|
|
10579
|
+
this.metrics.extra.buffersize = progress.current * 1000;
|
|
10580
|
+
}
|
|
10581
|
+
onCompletion() {
|
|
10582
|
+
// Decide if this is needed
|
|
10583
|
+
// const currentPercentage = this.metrics.extra.watchedPercentage;
|
|
10584
|
+
// this.trigger(ClapprStatsEvents.PERCENTAGE, currentPercentage);
|
|
10585
|
+
}
|
|
10586
|
+
buildReport() {
|
|
10587
|
+
this.stop(Chronograph.Session);
|
|
10588
|
+
this.start(Chronograph.Session);
|
|
10589
|
+
this.metrics.extra.playbackName = this.playbackName;
|
|
10590
|
+
this.metrics.extra.playbackType = this.playbackType;
|
|
10591
|
+
this.calcBitrates();
|
|
10592
|
+
this.calcBufferingPercentage();
|
|
10593
|
+
// TODO calc FPS properly, e.g., on TIMEUPDATE event
|
|
10594
|
+
this.fetchFPS();
|
|
10595
|
+
this.trigger(ClapprStatsEvents.REPORT, structuredClone(this.metrics));
|
|
10596
|
+
}
|
|
10597
|
+
fetchFPS() {
|
|
10598
|
+
// TODO check if the playback and media sources support video, then use the common method
|
|
10599
|
+
// flashls ??? - hls.droppedFramesl hls.stream.bufferLength (seconds)
|
|
10600
|
+
// hls ??? (use the same?)
|
|
10601
|
+
const fetchFPS = {
|
|
10602
|
+
html5_video: this.html5FetchFPS,
|
|
10603
|
+
hls: this.html5FetchFPS,
|
|
10604
|
+
dash: this.html5FetchFPS,
|
|
10605
|
+
};
|
|
10606
|
+
if (this.playbackName in fetchFPS) {
|
|
10607
|
+
fetchFPS[this.playbackName].call(this);
|
|
10608
|
+
}
|
|
10609
|
+
}
|
|
10610
|
+
// TODO sort out
|
|
10611
|
+
calcBitrates() {
|
|
10612
|
+
const { bitratesHistory } = this.metrics.extra;
|
|
10613
|
+
if (bitratesHistory.length === 0) {
|
|
10614
|
+
return;
|
|
10615
|
+
}
|
|
10616
|
+
let totalTime = 0;
|
|
10617
|
+
let weightedTotal = 0;
|
|
10618
|
+
for (const { bitrate, time = 0 } of bitratesHistory) {
|
|
10619
|
+
totalTime += time;
|
|
10620
|
+
weightedTotal += bitrate * time;
|
|
10621
|
+
}
|
|
10622
|
+
this.metrics.extra.bitrateWeightedMean = weightedTotal / totalTime;
|
|
10623
|
+
this.metrics.extra.bitrateMostUsed = bitratesHistory.reduce((mostUsed, current) => (current.time || 0) > (mostUsed.time || 0) ? current : mostUsed, { time: 0, bitrate: 0, start: 0, end: 0 }).bitrate;
|
|
10624
|
+
}
|
|
10625
|
+
calcBufferingPercentage() {
|
|
10626
|
+
if (this.metrics.extra.duration > 0) {
|
|
10627
|
+
this.metrics.extra.bufferingPercentage =
|
|
10628
|
+
(this.metrics.chrono.buffering / this.metrics.extra.duration) * 100;
|
|
10629
|
+
}
|
|
10630
|
+
}
|
|
10631
|
+
html5FetchFPS() {
|
|
10632
|
+
const videoTag = this.container.playback.el;
|
|
10633
|
+
const getFirstValidValue = (...args) => args.find((val) => val !== undefined);
|
|
10634
|
+
const decodedFrames = getFirstValidValue(videoTag.webkitDecodedFrameCount, videoTag.mozDecodedFrames, 0);
|
|
10635
|
+
const droppedFrames = getFirstValidValue(videoTag.webkitDroppedFrameCount, videoTag.mozParsedFrames && videoTag.mozDecodedFrames
|
|
10636
|
+
? videoTag.mozParsedFrames - videoTag.mozDecodedFrames
|
|
10637
|
+
: 0, 0);
|
|
10638
|
+
const delta = decodedFrames - (this.lastDecodedFramesCount || 0);
|
|
10639
|
+
this.metrics.counters.decodedFrames = decodedFrames;
|
|
10640
|
+
this.metrics.counters.droppedFrames = droppedFrames;
|
|
10641
|
+
this.metrics.counters.fps = delta / (this.runEach / 1000); // TODO use time delta instead of runEach
|
|
10642
|
+
this.lastDecodedFramesCount = decodedFrames;
|
|
10643
|
+
}
|
|
10644
|
+
}
|
|
10645
|
+
|
|
10313
10646
|
function getDefaultExportFromCjs (x) {
|
|
10314
10647
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
10315
10648
|
}
|
|
@@ -11381,56 +11714,6 @@ function requireMousetrap () {
|
|
|
11381
11714
|
var mousetrapExports = requireMousetrap();
|
|
11382
11715
|
const Mousetrap = /*@__PURE__*/getDefaultExportFromCjs(mousetrapExports);
|
|
11383
11716
|
|
|
11384
|
-
/**
|
|
11385
|
-
* @beta
|
|
11386
|
-
*/
|
|
11387
|
-
var ClapprStatsEvents;
|
|
11388
|
-
(function (ClapprStatsEvents) {
|
|
11389
|
-
ClapprStatsEvents["REPORT_EVENT"] = "clappr:stats:report";
|
|
11390
|
-
ClapprStatsEvents["PERCENTAGE_EVENT"] = "clappr:stats:percentage";
|
|
11391
|
-
})(ClapprStatsEvents || (ClapprStatsEvents = {}));
|
|
11392
|
-
|
|
11393
|
-
function newMetrics$1() {
|
|
11394
|
-
return {
|
|
11395
|
-
counters: {
|
|
11396
|
-
play: 0,
|
|
11397
|
-
pause: 0,
|
|
11398
|
-
error: 0,
|
|
11399
|
-
buffering: 0,
|
|
11400
|
-
decodedFrames: 0,
|
|
11401
|
-
droppedFrames: 0,
|
|
11402
|
-
fps: 0,
|
|
11403
|
-
changeLevel: 0,
|
|
11404
|
-
seek: 0,
|
|
11405
|
-
fullscreen: 0,
|
|
11406
|
-
dvrUsage: 0,
|
|
11407
|
-
},
|
|
11408
|
-
timers: {
|
|
11409
|
-
startup: 0,
|
|
11410
|
-
watch: 0,
|
|
11411
|
-
pause: 0,
|
|
11412
|
-
buffering: 0,
|
|
11413
|
-
session: 0,
|
|
11414
|
-
latency: 0,
|
|
11415
|
-
},
|
|
11416
|
-
extra: {
|
|
11417
|
-
playbackName: '',
|
|
11418
|
-
playbackType: '',
|
|
11419
|
-
bitratesHistory: [],
|
|
11420
|
-
bitrateWeightedMean: 0,
|
|
11421
|
-
bitrateMostUsed: 0,
|
|
11422
|
-
buffersize: 0,
|
|
11423
|
-
watchHistory: [],
|
|
11424
|
-
watchedPercentage: 0,
|
|
11425
|
-
bufferingPercentage: 0,
|
|
11426
|
-
bandwidth: 0,
|
|
11427
|
-
duration: 0,
|
|
11428
|
-
currentTime: 0,
|
|
11429
|
-
},
|
|
11430
|
-
custom: {},
|
|
11431
|
-
};
|
|
11432
|
-
}
|
|
11433
|
-
|
|
11434
11717
|
var humanFormat$2 = {exports: {}};
|
|
11435
11718
|
|
|
11436
11719
|
var humanFormat$1 = humanFormat$2.exports;
|
|
@@ -12461,7 +12744,7 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
|
|
|
12461
12744
|
* When clicked, it shows an overlay window with the information about the network speed, latency, etc,
|
|
12462
12745
|
* and recommended quality level.
|
|
12463
12746
|
*/
|
|
12464
|
-
class
|
|
12747
|
+
class NerdStats extends UICorePlugin {
|
|
12465
12748
|
container = null;
|
|
12466
12749
|
customMetrics = {
|
|
12467
12750
|
connectionSpeed: 0,
|
|
@@ -12544,29 +12827,29 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
12544
12827
|
this.listenTo(bottomGear, GearEvents.RENDERED, this.addToBottomGear);
|
|
12545
12828
|
this.container = this.core.activeContainer;
|
|
12546
12829
|
const clapprStats = this.container?.getPlugin('clappr_stats');
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12830
|
+
assert(clapprStats, 'clappr-stats not available. Please, include it as a plugin of your Clappr instance.\n' +
|
|
12831
|
+
'For more info, visit: https://github.com/clappr/clappr-stats.');
|
|
12832
|
+
Mousetrap.bind(this.shortcut, this.toggle);
|
|
12833
|
+
this.listenTo(this.core, Events.CORE_RESIZE, this.onPlayerResize);
|
|
12834
|
+
this.listenTo(clapprStats, ClapprStatsEvents.REPORT, this.updateMetrics);
|
|
12835
|
+
this.updateMetrics(clapprStats.exportMetrics());
|
|
12836
|
+
this.render();
|
|
12837
|
+
}
|
|
12838
|
+
/**
|
|
12839
|
+
* @internal
|
|
12840
|
+
*/
|
|
12841
|
+
destroy() {
|
|
12842
|
+
Mousetrap.unbind(this.shortcut);
|
|
12843
|
+
return super.destroy();
|
|
12561
12844
|
}
|
|
12562
|
-
toggle() {
|
|
12845
|
+
toggle = () => {
|
|
12563
12846
|
if (this.showing) {
|
|
12564
12847
|
this.hide();
|
|
12565
12848
|
}
|
|
12566
12849
|
else {
|
|
12567
12850
|
this.show();
|
|
12568
12851
|
}
|
|
12569
|
-
}
|
|
12852
|
+
};
|
|
12570
12853
|
show() {
|
|
12571
12854
|
this.core.$el.find(this.statsBoxElem).show();
|
|
12572
12855
|
this.showing = true;
|
|
@@ -12623,7 +12906,7 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
12623
12906
|
this.addGeneralMetrics();
|
|
12624
12907
|
this.addCustomMetrics();
|
|
12625
12908
|
const scrollTop = this.core.$el.find(this.statsBoxElem).scrollTop();
|
|
12626
|
-
this.$el.html(
|
|
12909
|
+
this.$el.html(NerdStats.template({
|
|
12627
12910
|
metrics: Formatter.format(this.metrics),
|
|
12628
12911
|
iconPosition: this.iconPosition,
|
|
12629
12912
|
}));
|
|
@@ -12657,8 +12940,8 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
12657
12940
|
addToBottomGear() {
|
|
12658
12941
|
const gear = this.core.getPlugin('bottom_gear');
|
|
12659
12942
|
gear
|
|
12660
|
-
.addItem('
|
|
12661
|
-
.html(
|
|
12943
|
+
.addItem('nerd_stats')
|
|
12944
|
+
.html(NerdStats.buttonTemplate({
|
|
12662
12945
|
icon: statsIcon,
|
|
12663
12946
|
i18n: this.core.i18n,
|
|
12664
12947
|
}))
|
|
@@ -12700,362 +12983,6 @@ function newMetrics() {
|
|
|
12700
12983
|
};
|
|
12701
12984
|
}
|
|
12702
12985
|
|
|
12703
|
-
// TODO: fix
|
|
12704
|
-
const updateMetrics = () => { };
|
|
12705
|
-
/**
|
|
12706
|
-
* `PLUGIN` that collects useful statistics about playback performance.
|
|
12707
|
-
* @beta
|
|
12708
|
-
* @remarks
|
|
12709
|
-
* This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
|
|
12710
|
-
*/
|
|
12711
|
-
class ClapprStats extends ContainerPlugin {
|
|
12712
|
-
bwMeasureCount = 0;
|
|
12713
|
-
intervalId = null;
|
|
12714
|
-
lastDecodedFramesCount = 0;
|
|
12715
|
-
metrics = newMetrics$1();
|
|
12716
|
-
completion;
|
|
12717
|
-
_onReport;
|
|
12718
|
-
runBandwidthTestEvery;
|
|
12719
|
-
runEach;
|
|
12720
|
-
timers = {
|
|
12721
|
-
startup: 0,
|
|
12722
|
-
watch: 0,
|
|
12723
|
-
pause: 0,
|
|
12724
|
-
buffering: 0,
|
|
12725
|
-
session: 0,
|
|
12726
|
-
latency: 0,
|
|
12727
|
-
};
|
|
12728
|
-
updateFn = updateMetrics;
|
|
12729
|
-
urisToMeasureBandwidth;
|
|
12730
|
-
uriToMeasureLatency;
|
|
12731
|
-
/**
|
|
12732
|
-
* @internal
|
|
12733
|
-
*/
|
|
12734
|
-
get name() {
|
|
12735
|
-
return 'clappr_stats';
|
|
12736
|
-
}
|
|
12737
|
-
/**
|
|
12738
|
-
* @internal
|
|
12739
|
-
*/
|
|
12740
|
-
get supportedVersion() {
|
|
12741
|
-
return { min: CLAPPR_VERSION$1 };
|
|
12742
|
-
}
|
|
12743
|
-
get _playbackName() {
|
|
12744
|
-
return String(this.container.playback.name || '');
|
|
12745
|
-
}
|
|
12746
|
-
get _playbackType() {
|
|
12747
|
-
return this.container.getPlaybackType();
|
|
12748
|
-
}
|
|
12749
|
-
_now() {
|
|
12750
|
-
const hasPerformanceSupport = window.performance && typeof (window.performance.now) === 'function';
|
|
12751
|
-
return (hasPerformanceSupport) ? window.performance.now() : new Date().getTime();
|
|
12752
|
-
}
|
|
12753
|
-
_inc(counter) {
|
|
12754
|
-
this.metrics.counters[counter] += 1;
|
|
12755
|
-
}
|
|
12756
|
-
// _timerHasStarted(timer) {
|
|
12757
|
-
// return this[`_start${timer}`] !== undefined;
|
|
12758
|
-
// }
|
|
12759
|
-
start(timer) {
|
|
12760
|
-
// this[`_start${timer}`] = this._now();
|
|
12761
|
-
this.timers[timer] = this._now();
|
|
12762
|
-
}
|
|
12763
|
-
_stop(timer) {
|
|
12764
|
-
// this._metrics.timers[timer] += this._now() - this[`_start${timer}`];
|
|
12765
|
-
this.metrics.timers[timer] += this._now() - this.timers[timer];
|
|
12766
|
-
}
|
|
12767
|
-
/**
|
|
12768
|
-
* Registers a callback to receive the metrics.
|
|
12769
|
-
* @param updateMetricsFn - The callback to receive the metrics
|
|
12770
|
-
*/
|
|
12771
|
-
setUpdateMetrics(updateMetricsFn) {
|
|
12772
|
-
// TODO use events instead
|
|
12773
|
-
this.updateFn = updateMetricsFn;
|
|
12774
|
-
}
|
|
12775
|
-
_defaultReport(metrics) {
|
|
12776
|
-
this.updateFn(metrics);
|
|
12777
|
-
}
|
|
12778
|
-
constructor(container) {
|
|
12779
|
-
super(container);
|
|
12780
|
-
this.runEach = container.options.clapprStats?.runEach ?? 5000;
|
|
12781
|
-
this._onReport = container.options.clapprStats?.onReport ?? this._defaultReport;
|
|
12782
|
-
this.uriToMeasureLatency = container.options.clapprStats?.uriToMeasureLatency;
|
|
12783
|
-
this.urisToMeasureBandwidth = container.options.clapprStats?.urisToMeasureBandwidth;
|
|
12784
|
-
this.runBandwidthTestEvery = container.options.clapprStats?.runBandwidthTestEvery ?? 10;
|
|
12785
|
-
this.completion = {
|
|
12786
|
-
watch: container.options.clapprStats?.onCompletion ?? [],
|
|
12787
|
-
calls: []
|
|
12788
|
-
};
|
|
12789
|
-
}
|
|
12790
|
-
/**
|
|
12791
|
-
* @internal
|
|
12792
|
-
*/
|
|
12793
|
-
bindEvents() {
|
|
12794
|
-
this.listenTo(this.container, Events.CONTAINER_BITRATE, this.onBitrate);
|
|
12795
|
-
this.listenTo(this.container, Events.CONTAINER_STOP, this.stopReporting);
|
|
12796
|
-
this.listenTo(this.container, Events.CONTAINER_ENDED, this.stopReporting);
|
|
12797
|
-
this.listenToOnce(this.container.playback, Events.PLAYBACK_PLAY_INTENT, this.startTimers);
|
|
12798
|
-
this.listenToOnce(this.container, Events.CONTAINER_PLAY, this.onFirstPlaying);
|
|
12799
|
-
this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay);
|
|
12800
|
-
this.listenTo(this.container, Events.CONTAINER_PAUSE, this.onPause);
|
|
12801
|
-
this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
12802
|
-
this.listenTo(this.container, Events.CONTAINER_SEEK, this.onSeek);
|
|
12803
|
-
this.listenTo(this.container, Events.CONTAINER_ERROR, () => this._inc('error'));
|
|
12804
|
-
this.listenTo(this.container, Events.CONTAINER_FULLSCREEN, () => this._inc('fullscreen'));
|
|
12805
|
-
this.listenTo(this.container, Events.CONTAINER_PLAYBACKDVRSTATECHANGED, (dvrInUse) => {
|
|
12806
|
-
dvrInUse && this._inc('dvrUsage');
|
|
12807
|
-
});
|
|
12808
|
-
this.listenTo(this.container.playback, Events.PLAYBACK_PROGRESS, this.onProgress);
|
|
12809
|
-
this.listenTo(this.container.playback, Events.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
|
|
12810
|
-
}
|
|
12811
|
-
/**
|
|
12812
|
-
* @internal
|
|
12813
|
-
*/
|
|
12814
|
-
destroy() {
|
|
12815
|
-
this.stopReporting();
|
|
12816
|
-
super.destroy();
|
|
12817
|
-
}
|
|
12818
|
-
/**
|
|
12819
|
-
* Returns the collected metrics.
|
|
12820
|
-
* @returns Currently collected metrics
|
|
12821
|
-
*/
|
|
12822
|
-
exportMetrics() {
|
|
12823
|
-
return structuredClone(this.metrics);
|
|
12824
|
-
}
|
|
12825
|
-
onBitrate(newBitrate) {
|
|
12826
|
-
const bitrate = newBitrate.bitrate;
|
|
12827
|
-
const now = this._now();
|
|
12828
|
-
if (this.metrics.extra.bitratesHistory.length > 0) {
|
|
12829
|
-
const beforeLast = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
|
|
12830
|
-
beforeLast.end = now;
|
|
12831
|
-
beforeLast.time = now - beforeLast.start;
|
|
12832
|
-
}
|
|
12833
|
-
this.metrics.extra.bitratesHistory.push({ start: this._now(), bitrate: bitrate });
|
|
12834
|
-
this._inc('changeLevel');
|
|
12835
|
-
}
|
|
12836
|
-
stopReporting() {
|
|
12837
|
-
this._buildReport();
|
|
12838
|
-
if (this.intervalId !== null) {
|
|
12839
|
-
clearInterval(this.intervalId);
|
|
12840
|
-
this.intervalId = null;
|
|
12841
|
-
}
|
|
12842
|
-
this._newMetrics();
|
|
12843
|
-
// TODO
|
|
12844
|
-
// @ts-ignore
|
|
12845
|
-
this.stopListening();
|
|
12846
|
-
this.bindEvents();
|
|
12847
|
-
}
|
|
12848
|
-
startTimers() {
|
|
12849
|
-
this.intervalId = setInterval(this._buildReport.bind(this), this.runEach);
|
|
12850
|
-
this.start('session');
|
|
12851
|
-
this.start('startup');
|
|
12852
|
-
}
|
|
12853
|
-
onFirstPlaying() {
|
|
12854
|
-
this.listenTo(this.container, Events.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
|
|
12855
|
-
this.start('watch');
|
|
12856
|
-
this._stop('startup');
|
|
12857
|
-
}
|
|
12858
|
-
playAfterPause() {
|
|
12859
|
-
this.listenTo(this.container, Events.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
|
|
12860
|
-
this._stop('pause');
|
|
12861
|
-
this.start('watch');
|
|
12862
|
-
}
|
|
12863
|
-
onPlay() {
|
|
12864
|
-
this._inc('play');
|
|
12865
|
-
}
|
|
12866
|
-
onPause() {
|
|
12867
|
-
this._stop('watch');
|
|
12868
|
-
this.start('pause');
|
|
12869
|
-
this._inc('pause');
|
|
12870
|
-
this.listenToOnce(this.container, Events.CONTAINER_PLAY, this.playAfterPause);
|
|
12871
|
-
this.stopListening(this.container, Events.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
|
|
12872
|
-
}
|
|
12873
|
-
onSeek(e) {
|
|
12874
|
-
this._inc('seek');
|
|
12875
|
-
this.metrics.extra.watchHistory.push([e * 1000, e * 1000]);
|
|
12876
|
-
}
|
|
12877
|
-
onTimeUpdate(e) {
|
|
12878
|
-
const current = e.current * 1000, total = e.total * 1000, l = this.metrics.extra.watchHistory.length;
|
|
12879
|
-
this.metrics.extra.duration = total;
|
|
12880
|
-
this.metrics.extra.currentTime = current;
|
|
12881
|
-
this.metrics.extra.watchedPercentage = (current / total) * 100;
|
|
12882
|
-
if (l === 0) {
|
|
12883
|
-
this.metrics.extra.watchHistory.push([current, current]);
|
|
12884
|
-
}
|
|
12885
|
-
else {
|
|
12886
|
-
this.metrics.extra.watchHistory[l - 1][1] = current;
|
|
12887
|
-
}
|
|
12888
|
-
if (this.metrics.extra.bitratesHistory.length > 0) {
|
|
12889
|
-
const lastBitrate = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
|
|
12890
|
-
if (!lastBitrate.end) {
|
|
12891
|
-
lastBitrate.time = this._now() - lastBitrate.start;
|
|
12892
|
-
}
|
|
12893
|
-
}
|
|
12894
|
-
this._onCompletion();
|
|
12895
|
-
}
|
|
12896
|
-
onContainerUpdateWhilePlaying() {
|
|
12897
|
-
if (this.container.playback.isPlaying()) {
|
|
12898
|
-
this._stop('watch');
|
|
12899
|
-
this.start('watch');
|
|
12900
|
-
}
|
|
12901
|
-
}
|
|
12902
|
-
onBuffering() {
|
|
12903
|
-
this._inc('buffering');
|
|
12904
|
-
this.start('buffering');
|
|
12905
|
-
this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERFULL, this.onBufferfull);
|
|
12906
|
-
}
|
|
12907
|
-
onBufferfull() {
|
|
12908
|
-
this._stop('buffering');
|
|
12909
|
-
this.listenToOnce(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
12910
|
-
}
|
|
12911
|
-
onProgress(progress) {
|
|
12912
|
-
this.metrics.extra.buffersize = progress.current * 1000;
|
|
12913
|
-
}
|
|
12914
|
-
_newMetrics() {
|
|
12915
|
-
this.metrics = newMetrics$1();
|
|
12916
|
-
}
|
|
12917
|
-
_onCompletion() {
|
|
12918
|
-
const currentPercentage = this.metrics.extra.watchedPercentage;
|
|
12919
|
-
const allPercentages = this.completion.watch;
|
|
12920
|
-
const isCalled = this.completion.calls.indexOf(currentPercentage) !== -1;
|
|
12921
|
-
if (allPercentages.indexOf(currentPercentage) !== -1 && !isCalled) {
|
|
12922
|
-
Log.info(this.name + ' PERCENTAGE_EVENT: ' + currentPercentage);
|
|
12923
|
-
this.completion.calls.push(currentPercentage);
|
|
12924
|
-
this.trigger(ClapprStatsEvents.PERCENTAGE_EVENT, currentPercentage);
|
|
12925
|
-
}
|
|
12926
|
-
}
|
|
12927
|
-
_buildReport() {
|
|
12928
|
-
this._stop('session');
|
|
12929
|
-
this.start('session');
|
|
12930
|
-
this.metrics.extra.playbackName = this._playbackName;
|
|
12931
|
-
this.metrics.extra.playbackType = this._playbackType;
|
|
12932
|
-
this._calculateBitrates();
|
|
12933
|
-
this._calculatePercentages();
|
|
12934
|
-
this._fetchFPS();
|
|
12935
|
-
this._measureLatency();
|
|
12936
|
-
this._measureBandwidth();
|
|
12937
|
-
this._onReport(this.metrics);
|
|
12938
|
-
this.trigger(ClapprStatsEvents.REPORT_EVENT, structuredClone(this.metrics));
|
|
12939
|
-
}
|
|
12940
|
-
_fetchFPS() {
|
|
12941
|
-
// flashls ??? - hls.droppedFramesl hls.stream.bufferLength (seconds)
|
|
12942
|
-
// hls ??? (use the same?)
|
|
12943
|
-
const fetchFPS = {
|
|
12944
|
-
'html5_video': this._html5FetchFPS,
|
|
12945
|
-
'hls': this._html5FetchFPS,
|
|
12946
|
-
'dash_shaka_playback': this._html5FetchFPS
|
|
12947
|
-
};
|
|
12948
|
-
if (this._playbackName in fetchFPS) {
|
|
12949
|
-
fetchFPS[this._playbackName].call(this);
|
|
12950
|
-
}
|
|
12951
|
-
}
|
|
12952
|
-
_calculateBitrates() {
|
|
12953
|
-
const { bitratesHistory } = this.metrics.extra;
|
|
12954
|
-
if (bitratesHistory.length === 0) {
|
|
12955
|
-
return;
|
|
12956
|
-
}
|
|
12957
|
-
let totalTime = 0;
|
|
12958
|
-
let weightedTotal = 0;
|
|
12959
|
-
for (const { bitrate, time = 0 } of bitratesHistory) {
|
|
12960
|
-
totalTime += time;
|
|
12961
|
-
weightedTotal += bitrate * time;
|
|
12962
|
-
}
|
|
12963
|
-
this.metrics.extra.bitrateWeightedMean = weightedTotal / totalTime;
|
|
12964
|
-
this.metrics.extra.bitrateMostUsed = bitratesHistory.reduce((mostUsed, current) => (current.time || 0) > (mostUsed.time || 0) ? current : mostUsed, { time: 0, bitrate: 0, start: 0, end: 0 }).bitrate;
|
|
12965
|
-
}
|
|
12966
|
-
_calculatePercentages() {
|
|
12967
|
-
if (this.metrics.extra.duration > 0) {
|
|
12968
|
-
this.metrics.extra.bufferingPercentage = (this.metrics.timers.buffering / this.metrics.extra.duration) * 100;
|
|
12969
|
-
}
|
|
12970
|
-
}
|
|
12971
|
-
_html5FetchFPS() {
|
|
12972
|
-
const videoTag = this.container.playback.el;
|
|
12973
|
-
const getFirstValidValue = (...args) => args.find(val => val !== undefined);
|
|
12974
|
-
const decodedFrames = getFirstValidValue(videoTag.webkitDecodedFrameCount, videoTag.mozDecodedFrames, 0);
|
|
12975
|
-
const droppedFrames = getFirstValidValue(videoTag.webkitDroppedFrameCount, videoTag.mozParsedFrames && videoTag.mozDecodedFrames ? videoTag.mozParsedFrames - videoTag.mozDecodedFrames : 0, 0);
|
|
12976
|
-
const decodedFramesLastTime = decodedFrames - (this.lastDecodedFramesCount || 0);
|
|
12977
|
-
this.metrics.counters.decodedFrames = decodedFrames;
|
|
12978
|
-
this.metrics.counters.droppedFrames = droppedFrames;
|
|
12979
|
-
this.metrics.counters.fps = decodedFramesLastTime / (this.runEach / 1000);
|
|
12980
|
-
this.lastDecodedFramesCount = decodedFrames;
|
|
12981
|
-
}
|
|
12982
|
-
// originally from https://www.smashingmagazine.com/2011/11/analyzing-network-characteristics-using-javascript-and-the-dom-part-1/
|
|
12983
|
-
_measureLatency() {
|
|
12984
|
-
if (this.uriToMeasureLatency) {
|
|
12985
|
-
const t = [];
|
|
12986
|
-
const n = 2;
|
|
12987
|
-
let rtt;
|
|
12988
|
-
const ld = () => {
|
|
12989
|
-
t.push(this._now());
|
|
12990
|
-
if (t.length > n) {
|
|
12991
|
-
done();
|
|
12992
|
-
}
|
|
12993
|
-
else {
|
|
12994
|
-
const img = new Image;
|
|
12995
|
-
img.onload = ld;
|
|
12996
|
-
img.src = this.uriToMeasureLatency + '?' + Math.random()
|
|
12997
|
-
+ '=' + this._now();
|
|
12998
|
-
}
|
|
12999
|
-
};
|
|
13000
|
-
const done = () => {
|
|
13001
|
-
rtt = t[2] - t[1];
|
|
13002
|
-
this.metrics.timers.latency = rtt;
|
|
13003
|
-
};
|
|
13004
|
-
ld();
|
|
13005
|
-
}
|
|
13006
|
-
}
|
|
13007
|
-
// originally from https://www.smashingmagazine.com/2011/11/analyzing-network-characteristics-using-javascript-and-the-dom-part-1/
|
|
13008
|
-
_measureBandwidth() {
|
|
13009
|
-
if (this.urisToMeasureBandwidth && (this.bwMeasureCount % this.runBandwidthTestEvery === 0)) {
|
|
13010
|
-
let i = 0;
|
|
13011
|
-
const ld = (e) => {
|
|
13012
|
-
if (i > 0) {
|
|
13013
|
-
const prev = this.urisToMeasureBandwidth[i - 1];
|
|
13014
|
-
prev.end = this._now();
|
|
13015
|
-
if (prev.timer !== null) {
|
|
13016
|
-
clearTimeout(prev.timer);
|
|
13017
|
-
}
|
|
13018
|
-
}
|
|
13019
|
-
if (i >= this.urisToMeasureBandwidth.length || (i > 0 && this.urisToMeasureBandwidth[i - 1].expired)) {
|
|
13020
|
-
assert(e, 'incorrect invocation in _measureBandwidth');
|
|
13021
|
-
done(e);
|
|
13022
|
-
}
|
|
13023
|
-
else {
|
|
13024
|
-
const xhr = new XMLHttpRequest();
|
|
13025
|
-
xhr.open('GET', this.urisToMeasureBandwidth[i].url, true);
|
|
13026
|
-
xhr.responseType = 'arraybuffer';
|
|
13027
|
-
xhr.onload = xhr.onabort = ld;
|
|
13028
|
-
this.urisToMeasureBandwidth[i].start = this._now();
|
|
13029
|
-
this.urisToMeasureBandwidth[i].timer = setTimeout((j) => {
|
|
13030
|
-
this.urisToMeasureBandwidth[j].expired = true;
|
|
13031
|
-
xhr.abort();
|
|
13032
|
-
}, this.urisToMeasureBandwidth[i].timeout, i);
|
|
13033
|
-
xhr.send();
|
|
13034
|
-
}
|
|
13035
|
-
i++;
|
|
13036
|
-
};
|
|
13037
|
-
const done = (e) => {
|
|
13038
|
-
const timeSpent = (this.urisToMeasureBandwidth[i - 1].end - this.urisToMeasureBandwidth[i - 1].start) / 1000;
|
|
13039
|
-
const bandwidthBps = (e.loaded * 8) / timeSpent;
|
|
13040
|
-
this.metrics.extra.bandwidth = bandwidthBps;
|
|
13041
|
-
this.urisToMeasureBandwidth.forEach((x) => {
|
|
13042
|
-
x.start = 0;
|
|
13043
|
-
x.end = 0;
|
|
13044
|
-
x.expired = false;
|
|
13045
|
-
if (x.timer !== null) {
|
|
13046
|
-
clearTimeout(x.timer);
|
|
13047
|
-
x.timer = null;
|
|
13048
|
-
}
|
|
13049
|
-
});
|
|
13050
|
-
};
|
|
13051
|
-
ld();
|
|
13052
|
-
}
|
|
13053
|
-
this.bwMeasureCount++;
|
|
13054
|
-
}
|
|
13055
|
-
}
|
|
13056
|
-
// ClapprStats.REPORT_EVENT = 'clappr:stats:report';
|
|
13057
|
-
// ClapprStats.PERCENTAGE_EVENT = 'clappr:stats:percentage';
|
|
13058
|
-
|
|
13059
12986
|
// This work is based on the original work of the following authors:
|
|
13060
12987
|
// Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
13061
12988
|
// Use of this source code is governed by a BSD-style
|
|
@@ -18768,4 +18695,4 @@ class VolumeFade extends UICorePlugin {
|
|
|
18768
18695
|
}
|
|
18769
18696
|
}
|
|
18770
18697
|
|
|
18771
|
-
export { AudioTracks as AudioSelector, AudioTracks, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, Clips, ClosedCaptions, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, QualityLevels as LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, QualityLevels, SeekTime, Share, SkipTime, SourceController, SpinnerThreeBounce as Spinner, SpinnerEvents, SpinnerThreeBounce, ClosedCaptions as Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents };
|
|
18698
|
+
export { AudioTracks as AudioSelector, AudioTracks, BigMuteButton, BottomGear, NerdStats as ClapprNerdStats, ClapprStats, ClickToPause, Clips, ClosedCaptions, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, QualityLevels as LevelSelector, Logo, MediaControl, MultiCamera, NerdStats, PictureInPicture, PlaybackRate, Poster, QualityLevels, SeekTime, Share, SkipTime, SourceController, SpinnerThreeBounce as Spinner, SpinnerEvents, SpinnerThreeBounce, ClosedCaptions as Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents };
|