@mattebox/player-diagnostics 0.1.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/LICENSE +21 -0
- package/NOTICE +24 -0
- package/README.md +45 -0
- package/dist/cdn/mattebox-player-diagnostics.min.js +124 -0
- package/dist/charts.d.ts +35 -0
- package/dist/charts.d.ts.map +1 -0
- package/dist/charts.js +401 -0
- package/dist/charts.js.map +1 -0
- package/dist/element.d.ts +62 -0
- package/dist/element.d.ts.map +1 -0
- package/dist/element.js +677 -0
- package/dist/element.js.map +1 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/asyncToGenerator.js +27 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/defineProperty.js +12 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/objectSpread2.js +25 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/toPrimitive.js +14 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/toPropertyKey.js +9 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/typeof.js +11 -0
- package/dist/es2015/charts.js +380 -0
- package/dist/es2015/element.js +651 -0
- package/dist/es2015/format.js +38 -0
- package/dist/es2015/host.js +34 -0
- package/dist/es2015/icon.js +46 -0
- package/dist/es2015/index.js +15 -0
- package/dist/es2015/report.js +145 -0
- package/dist/es2015/sampler.js +196 -0
- package/dist/es2015/style.js +135 -0
- package/dist/es2015/support.js +351 -0
- package/dist/es2015/trace.js +99 -0
- package/dist/format.d.ts +20 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +45 -0
- package/dist/format.js.map +1 -0
- package/dist/host.d.ts +19 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +38 -0
- package/dist/host.js.map +1 -0
- package/dist/icon.d.ts +31 -0
- package/dist/icon.d.ts.map +1 -0
- package/dist/icon.js +44 -0
- package/dist/icon.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/report.d.ts +140 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +125 -0
- package/dist/report.js.map +1 -0
- package/dist/sampler.d.ts +68 -0
- package/dist/sampler.d.ts.map +1 -0
- package/dist/sampler.js +208 -0
- package/dist/sampler.js.map +1 -0
- package/dist/style.d.ts +10 -0
- package/dist/style.d.ts.map +1 -0
- package/dist/style.js +133 -0
- package/dist/style.js.map +1 -0
- package/dist/support.d.ts +46 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +247 -0
- package/dist/support.js.map +1 -0
- package/dist/trace.d.ts +14 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +100 -0
- package/dist/trace.js.map +1 -0
- package/package.json +59 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mattebox/player-diagnostics: <mbx-diagnostics>, a control for the
|
|
3
|
+
* player's bar, or a panel under the video, that shows what the session
|
|
4
|
+
* is doing and what the browser can do, and writes a report. Importing
|
|
5
|
+
* this module registers the element; that is the package's one side
|
|
6
|
+
* effect. It reaches the player only through the contract a control of
|
|
7
|
+
* the page's own has, and the engine through its public surface.
|
|
8
|
+
*/
|
|
9
|
+
import { MbxDiagnostics } from './element.js';
|
|
10
|
+
export { MbxDiagnostics } from './element.js';
|
|
11
|
+
export type { DiagnosticsReport, EngineReport, PlaybackReport } from './report.js';
|
|
12
|
+
export type { Counters, Mark, Sample } from './sampler.js';
|
|
13
|
+
export type { CodecRow, DrmRow, PlatformRow, Support } from './support.js';
|
|
14
|
+
export { probeSupport } from './support.js';
|
|
15
|
+
export declare const DIAGNOSTICS = "mbx-diagnostics";
|
|
16
|
+
declare global {
|
|
17
|
+
interface HTMLElementTagNameMap {
|
|
18
|
+
'mbx-diagnostics': MbxDiagnostics;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnF,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3D,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAM7C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,cAAc,CAAC;KACnC;CACF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mattebox/player-diagnostics: <mbx-diagnostics>, a control for the
|
|
3
|
+
* player's bar, or a panel under the video, that shows what the session
|
|
4
|
+
* is doing and what the browser can do, and writes a report. Importing
|
|
5
|
+
* this module registers the element; that is the package's one side
|
|
6
|
+
* effect. It reaches the player only through the contract a control of
|
|
7
|
+
* the page's own has, and the engine through its public surface.
|
|
8
|
+
*/
|
|
9
|
+
import { MbxDiagnostics } from './element.js';
|
|
10
|
+
export { MbxDiagnostics } from './element.js';
|
|
11
|
+
export { probeSupport } from './support.js';
|
|
12
|
+
export const DIAGNOSTICS = 'mbx-diagnostics';
|
|
13
|
+
if (customElements.get(DIAGNOSTICS) === undefined) {
|
|
14
|
+
customElements.define(DIAGNOSTICS, MbxDiagnostics);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE7C,IAAI,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;IAClD,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/report.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The report: everything the panel shows, as one plain object a page can
|
|
3
|
+
* send when something goes wrong, and the trace the engine's guide asks
|
|
4
|
+
* for with every error report (chapter 12), as the element kept it: see
|
|
5
|
+
* `trace.ts` for what is kept of each entry. Every field is serializable;
|
|
6
|
+
* a native session has no engine part.
|
|
7
|
+
*/
|
|
8
|
+
import type { Mattebox } from 'mattebox';
|
|
9
|
+
import type { PlayerError, PlayerHost } from './host.js';
|
|
10
|
+
import type { Counters, Mark, Sample } from './sampler.js';
|
|
11
|
+
import type { Support } from './support.js';
|
|
12
|
+
export interface RangeReport {
|
|
13
|
+
readonly start: number;
|
|
14
|
+
readonly end: number;
|
|
15
|
+
}
|
|
16
|
+
export interface PlaybackReport {
|
|
17
|
+
readonly currentTime: number;
|
|
18
|
+
readonly duration: number;
|
|
19
|
+
readonly paused: boolean;
|
|
20
|
+
readonly ended: boolean;
|
|
21
|
+
readonly seeking: boolean;
|
|
22
|
+
readonly readyState: number;
|
|
23
|
+
readonly networkState: number;
|
|
24
|
+
readonly playbackRate: number;
|
|
25
|
+
readonly volume: number;
|
|
26
|
+
readonly muted: boolean;
|
|
27
|
+
readonly videoWidth: number;
|
|
28
|
+
readonly videoHeight: number;
|
|
29
|
+
readonly buffered: readonly RangeReport[];
|
|
30
|
+
readonly seekable: readonly RangeReport[];
|
|
31
|
+
readonly frames: {
|
|
32
|
+
readonly decoded: number;
|
|
33
|
+
readonly dropped: number;
|
|
34
|
+
} | null;
|
|
35
|
+
readonly mediaError: {
|
|
36
|
+
readonly code: number;
|
|
37
|
+
readonly message: string;
|
|
38
|
+
} | null;
|
|
39
|
+
}
|
|
40
|
+
export interface EngineReport {
|
|
41
|
+
readonly phase: string;
|
|
42
|
+
readonly capabilities: readonly string[];
|
|
43
|
+
readonly throughput: {
|
|
44
|
+
readonly slow: number;
|
|
45
|
+
readonly fast: number;
|
|
46
|
+
};
|
|
47
|
+
readonly bufferGoal: number;
|
|
48
|
+
readonly buffers: ReadonlyArray<{
|
|
49
|
+
readonly id: string;
|
|
50
|
+
readonly codecs: string;
|
|
51
|
+
readonly ranges: readonly RangeReport[];
|
|
52
|
+
}>;
|
|
53
|
+
readonly inflight: ReadonlyArray<{
|
|
54
|
+
readonly trackId: string;
|
|
55
|
+
readonly seq: number;
|
|
56
|
+
readonly url: string;
|
|
57
|
+
}>;
|
|
58
|
+
readonly live: {
|
|
59
|
+
readonly start: number;
|
|
60
|
+
readonly end: number;
|
|
61
|
+
readonly edge: number;
|
|
62
|
+
readonly latency: number | null;
|
|
63
|
+
} | null;
|
|
64
|
+
readonly tracks: {
|
|
65
|
+
readonly active: Readonly<Record<string, string | null>>;
|
|
66
|
+
readonly available: ReadonlyArray<{
|
|
67
|
+
readonly id: string;
|
|
68
|
+
readonly contentType: string;
|
|
69
|
+
readonly mimeType: string;
|
|
70
|
+
readonly lang: string | null;
|
|
71
|
+
readonly role: string | null;
|
|
72
|
+
readonly renditions: number;
|
|
73
|
+
}>;
|
|
74
|
+
};
|
|
75
|
+
readonly quality: {
|
|
76
|
+
readonly playing: string | null;
|
|
77
|
+
readonly active: string | null;
|
|
78
|
+
readonly pinned: string | null;
|
|
79
|
+
readonly allowed: readonly string[];
|
|
80
|
+
readonly renditions: ReadonlyArray<{
|
|
81
|
+
readonly id: string;
|
|
82
|
+
readonly bitrate: number;
|
|
83
|
+
readonly width: number | null;
|
|
84
|
+
readonly height: number | null;
|
|
85
|
+
readonly frameRate: number | null;
|
|
86
|
+
readonly codecs: string | null;
|
|
87
|
+
}>;
|
|
88
|
+
};
|
|
89
|
+
readonly drm: {
|
|
90
|
+
readonly keySystem: string | null;
|
|
91
|
+
readonly sessions: ReadonlyArray<{
|
|
92
|
+
readonly keyId: string;
|
|
93
|
+
readonly status: string;
|
|
94
|
+
}>;
|
|
95
|
+
} | null;
|
|
96
|
+
readonly error: {
|
|
97
|
+
readonly category: string;
|
|
98
|
+
readonly code: string;
|
|
99
|
+
readonly fatal: boolean;
|
|
100
|
+
readonly recoverable: boolean;
|
|
101
|
+
readonly context: Readonly<Record<string, unknown>> | null;
|
|
102
|
+
} | null;
|
|
103
|
+
}
|
|
104
|
+
export interface DiagnosticsReport {
|
|
105
|
+
/** When the report was taken, ISO 8601. */
|
|
106
|
+
readonly at: string;
|
|
107
|
+
readonly userAgent: string;
|
|
108
|
+
readonly source: {
|
|
109
|
+
readonly url: string | null;
|
|
110
|
+
readonly type: string | null;
|
|
111
|
+
/** The name of the handler that won, or null before a session. */
|
|
112
|
+
readonly handler: string | null;
|
|
113
|
+
};
|
|
114
|
+
readonly playback: PlaybackReport;
|
|
115
|
+
/** The player's fatal error of the current load, or null. */
|
|
116
|
+
readonly error: PlayerError | null;
|
|
117
|
+
/** Null for a native session. */
|
|
118
|
+
readonly engine: EngineReport | null;
|
|
119
|
+
readonly counters: Counters;
|
|
120
|
+
/** The last two minutes of samples, and the marks in them. */
|
|
121
|
+
readonly samples: readonly Sample[];
|
|
122
|
+
readonly marks: readonly Mark[];
|
|
123
|
+
/** What the browser supports, when it was probed before the report. */
|
|
124
|
+
readonly support: Support | null;
|
|
125
|
+
/** The trace entries the element kept, slimmed, oldest first, or null for a native session. */
|
|
126
|
+
readonly trace: readonly unknown[] | null;
|
|
127
|
+
}
|
|
128
|
+
export declare function playbackFacts(video: HTMLVideoElement): PlaybackReport;
|
|
129
|
+
export declare function engineFacts(engine: Mattebox): EngineReport;
|
|
130
|
+
export interface ReportSources {
|
|
131
|
+
readonly player: PlayerHost;
|
|
132
|
+
readonly samples: readonly Sample[];
|
|
133
|
+
readonly marks: readonly Mark[];
|
|
134
|
+
readonly counters: Counters;
|
|
135
|
+
/** The trace entries kept, slimmed, oldest first. */
|
|
136
|
+
readonly history: readonly unknown[];
|
|
137
|
+
readonly support: Support | null;
|
|
138
|
+
}
|
|
139
|
+
export declare function buildReport(sources: ReportSources): DiagnosticsReport;
|
|
140
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
package/dist/report.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
function ranges(list) {
|
|
2
|
+
return Array.from({ length: list.length }, (_, i) => ({
|
|
3
|
+
start: list.start(i),
|
|
4
|
+
end: list.end(i),
|
|
5
|
+
}));
|
|
6
|
+
}
|
|
7
|
+
export function playbackFacts(video) {
|
|
8
|
+
const quality = video.getVideoPlaybackQuality?.();
|
|
9
|
+
return {
|
|
10
|
+
currentTime: video.currentTime,
|
|
11
|
+
duration: video.duration,
|
|
12
|
+
paused: video.paused,
|
|
13
|
+
ended: video.ended,
|
|
14
|
+
seeking: video.seeking,
|
|
15
|
+
readyState: video.readyState,
|
|
16
|
+
networkState: video.networkState,
|
|
17
|
+
playbackRate: video.playbackRate,
|
|
18
|
+
volume: video.volume,
|
|
19
|
+
muted: video.muted,
|
|
20
|
+
videoWidth: video.videoWidth,
|
|
21
|
+
videoHeight: video.videoHeight,
|
|
22
|
+
buffered: ranges(video.buffered),
|
|
23
|
+
seekable: ranges(video.seekable),
|
|
24
|
+
frames: quality === undefined
|
|
25
|
+
? null
|
|
26
|
+
: { decoded: quality.totalVideoFrames, dropped: quality.droppedVideoFrames },
|
|
27
|
+
mediaError: video.error === null ? null : { code: video.error.code, message: video.error.message },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function engineFacts(engine) {
|
|
31
|
+
const state = engine.stats.snapshot();
|
|
32
|
+
const optional = engine;
|
|
33
|
+
const error = engine.error;
|
|
34
|
+
return {
|
|
35
|
+
phase: state.lifecycle.phase,
|
|
36
|
+
capabilities: [...engine.capabilities()],
|
|
37
|
+
throughput: { slow: state.stats.throughputEwma, fast: state.stats.throughputFastEwma },
|
|
38
|
+
bufferGoal: state.scheduling.bufferGoal,
|
|
39
|
+
buffers: [...state.buffers.entries()].map(([id, buffer]) => ({
|
|
40
|
+
id,
|
|
41
|
+
codecs: buffer.codecs,
|
|
42
|
+
ranges: buffer.ranges.map((range) => ({ start: range.start, end: range.end })),
|
|
43
|
+
})),
|
|
44
|
+
inflight: [...state.scheduling.inflight.values()].map((request) => ({
|
|
45
|
+
trackId: request.trackId,
|
|
46
|
+
seq: request.seq,
|
|
47
|
+
url: request.url,
|
|
48
|
+
})),
|
|
49
|
+
live: state.live === null
|
|
50
|
+
? null
|
|
51
|
+
: {
|
|
52
|
+
start: state.live.span.start,
|
|
53
|
+
end: state.live.span.end,
|
|
54
|
+
edge: state.live.edge,
|
|
55
|
+
latency: optional.live?.latency ?? null,
|
|
56
|
+
},
|
|
57
|
+
tracks: {
|
|
58
|
+
active: Object.fromEntries(['video', 'audio', 'text'].map((type) => [
|
|
59
|
+
type,
|
|
60
|
+
engine.tracks.active(type)?.id ?? null,
|
|
61
|
+
])),
|
|
62
|
+
available: engine.tracks.available.map((track) => ({
|
|
63
|
+
id: track.id,
|
|
64
|
+
contentType: track.contentType,
|
|
65
|
+
mimeType: track.mimeType,
|
|
66
|
+
lang: track.lang ?? null,
|
|
67
|
+
role: track.role ?? null,
|
|
68
|
+
renditions: track.renditions.length,
|
|
69
|
+
})),
|
|
70
|
+
},
|
|
71
|
+
quality: {
|
|
72
|
+
playing: engine.quality.playing?.id ?? null,
|
|
73
|
+
active: engine.quality.active?.id ?? null,
|
|
74
|
+
pinned: engine.quality.pinned,
|
|
75
|
+
allowed: engine.quality.allowed.map((r) => r.id),
|
|
76
|
+
renditions: engine.quality.renditions.map((r) => ({
|
|
77
|
+
id: r.id,
|
|
78
|
+
bitrate: r.bitrate,
|
|
79
|
+
width: r.width ?? null,
|
|
80
|
+
height: r.height ?? null,
|
|
81
|
+
frameRate: r.frameRate ?? null,
|
|
82
|
+
codecs: r.codecs,
|
|
83
|
+
})),
|
|
84
|
+
},
|
|
85
|
+
drm: optional.drm === undefined
|
|
86
|
+
? null
|
|
87
|
+
: { keySystem: optional.drm.keySystem, sessions: [...optional.drm.sessions] },
|
|
88
|
+
error: error === null
|
|
89
|
+
? null
|
|
90
|
+
: {
|
|
91
|
+
category: error.category,
|
|
92
|
+
code: error.code,
|
|
93
|
+
fatal: error.fatal,
|
|
94
|
+
recoverable: error.recoverable,
|
|
95
|
+
context: error.context ?? null,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Two minutes of samples at two a second, and the marks of the same two minutes. */
|
|
100
|
+
const KEEP_SAMPLES = 240;
|
|
101
|
+
const KEEP_MS = 120_000;
|
|
102
|
+
export function buildReport(sources) {
|
|
103
|
+
const { player } = sources;
|
|
104
|
+
const engine = player.engine;
|
|
105
|
+
const samples = sources.samples.slice(-KEEP_SAMPLES);
|
|
106
|
+
const since = performance.now() - KEEP_MS;
|
|
107
|
+
return {
|
|
108
|
+
at: new Date().toISOString(),
|
|
109
|
+
userAgent: navigator.userAgent,
|
|
110
|
+
source: {
|
|
111
|
+
url: player.getAttribute('src'),
|
|
112
|
+
type: player.getAttribute('type'),
|
|
113
|
+
handler: player.player?.session?.handler ?? null,
|
|
114
|
+
},
|
|
115
|
+
playback: playbackFacts(player.video),
|
|
116
|
+
error: player.error,
|
|
117
|
+
engine: engine === null ? null : engineFacts(engine),
|
|
118
|
+
counters: sources.counters,
|
|
119
|
+
samples,
|
|
120
|
+
marks: sources.marks.filter((mark) => mark.t >= since),
|
|
121
|
+
support: sources.support,
|
|
122
|
+
trace: engine === null ? null : sources.history,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAiIA,SAAS,MAAM,CAAC,IAAgB;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACpB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;KACjB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAuB;IACnD,MAAM,OAAO,GAAG,KAAK,CAAC,uBAAuB,EAAE,EAAE,CAAC;IAClD,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QAChC,MAAM,EACJ,OAAO,KAAK,SAAS;YACnB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,kBAAkB,EAAE;QAChF,UAAU,EACR,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE;KACzF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAgB;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAoB,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK;QAC5B,YAAY,EAAE,CAAC,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;QACxC,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE;QACtF,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,UAAU;QACvC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3D,EAAE;YACF,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;SAC/E,CAAC,CAAC;QACH,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAClE,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,IAAI,EACF,KAAK,CAAC,IAAI,KAAK,IAAI;YACjB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC;gBACE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;gBAC5B,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;gBACrB,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI;aACxC;QACP,MAAM,EAAE;YACN,MAAM,EAAE,MAAM,CAAC,WAAW,CACvB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBAClD,IAAI;gBACJ,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,IAAI;aACvC,CAAC,CACH;YACD,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACjD,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;gBACxB,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM;aACpC,CAAC,CAAC;SACJ;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,IAAI;YAC3C,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI;YACzC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAChD,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI;gBACtB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;gBACxB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,IAAI;gBAC9B,MAAM,EAAE,CAAC,CAAC,MAAM;aACjB,CAAC,CAAC;SACJ;QACD,GAAG,EACD,QAAQ,CAAC,GAAG,KAAK,SAAS;YACxB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QACjF,KAAK,EACH,KAAK,KAAK,IAAI;YACZ,CAAC,CAAC,IAAI;YACN,CAAC,CAAC;gBACE,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;aAC/B;KACR,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,OAAO,GAAG,OAAO,CAAC;AAYxB,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IAC1C,OAAO;QACL,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,MAAM,EAAE;YACN,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC;YAC/B,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;YACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI;SACjD;QACD,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC;QACrC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;QACpD,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO;QACP,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QACtD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO;KAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sampler: what the charts, the counters and the report are drawn
|
|
3
|
+
* from, taken every half second while the element is attached, so a stall
|
|
4
|
+
* counted before the panel opened is still counted. It reads the way the
|
|
5
|
+
* engine's playground reads: the kernel state through
|
|
6
|
+
* `engine.stats.snapshot()`, the rendition playing through
|
|
7
|
+
* `engine.quality.playing`, the trace for the segments, the stalls, the
|
|
8
|
+
* seeks and what recovery did, and the video itself for the buffer ahead,
|
|
9
|
+
* the frames and whether it is stalled. The engine emits no event for a
|
|
10
|
+
* quality switch, so the switch is a poll's diff.
|
|
11
|
+
*
|
|
12
|
+
* The trace arrives as `trace` events where the engine emits them, one
|
|
13
|
+
* entry at a time, and the sampler keeps its own history of them, slimmed
|
|
14
|
+
* and bounded, which is what the report sends. An engine without the
|
|
15
|
+
* event keeps a ring instead, and the sampler reads it through a cursor
|
|
16
|
+
* that remembers the last entry seen by identity and, once the ring has
|
|
17
|
+
* evicted it, by its clock. Both routes feed the same intake, and an
|
|
18
|
+
* entry seen once is not taken twice.
|
|
19
|
+
*/
|
|
20
|
+
import type { Mattebox } from 'mattebox';
|
|
21
|
+
export interface Sample {
|
|
22
|
+
/** performance.now() */
|
|
23
|
+
readonly t: number;
|
|
24
|
+
readonly currentTime: number;
|
|
25
|
+
/** The slow and the fast throughput estimates, bits per second. */
|
|
26
|
+
readonly slow: number;
|
|
27
|
+
readonly fast: number;
|
|
28
|
+
/** Seconds buffered ahead of the playhead. */
|
|
29
|
+
readonly ahead: number;
|
|
30
|
+
readonly stalled: boolean;
|
|
31
|
+
/** Frames dropped and decoded since the last sample. */
|
|
32
|
+
readonly dropped: number;
|
|
33
|
+
readonly decoded: number;
|
|
34
|
+
readonly playingId: string | null;
|
|
35
|
+
readonly playingBitrate: number;
|
|
36
|
+
readonly playingHeight: number;
|
|
37
|
+
}
|
|
38
|
+
export type MarkKind = 'segment' | 'stall' | 'seek' | 'nudge' | 'flush' | 'skip' | 'gap-jump' | 'switch';
|
|
39
|
+
export interface Mark {
|
|
40
|
+
readonly t: number;
|
|
41
|
+
readonly kind: MarkKind;
|
|
42
|
+
readonly value: number;
|
|
43
|
+
readonly label: string;
|
|
44
|
+
readonly trackId?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface Counters {
|
|
47
|
+
readonly stalls: number;
|
|
48
|
+
/** Seconds spent stalled, the current stall included. */
|
|
49
|
+
readonly stalledSeconds: number;
|
|
50
|
+
readonly switches: number;
|
|
51
|
+
/** The video's own totals for the session. */
|
|
52
|
+
readonly decoded: number;
|
|
53
|
+
readonly dropped: number;
|
|
54
|
+
}
|
|
55
|
+
export interface Sampler {
|
|
56
|
+
/** Forgets everything and follows a session's trace: a new session starts its counts at zero. */
|
|
57
|
+
attach(video: HTMLVideoElement, engine: Mattebox | null): void;
|
|
58
|
+
/** Lets go of the session's trace. */
|
|
59
|
+
release(): void;
|
|
60
|
+
poll(video: HTMLVideoElement, engine: Mattebox | null): void;
|
|
61
|
+
readonly samples: readonly Sample[];
|
|
62
|
+
readonly marks: readonly Mark[];
|
|
63
|
+
readonly counters: Counters;
|
|
64
|
+
/** The trace entries kept, slimmed and plain, oldest first. */
|
|
65
|
+
readonly history: readonly unknown[];
|
|
66
|
+
}
|
|
67
|
+
export declare function createSampler(): Sampler;
|
|
68
|
+
//# sourceMappingURL=sampler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampler.d.ts","sourceRoot":"","sources":["../src/sampler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAyB,MAAM,UAAU,CAAC;AAGhE,MAAM,WAAW,MAAM;IACrB,wBAAwB;IACxB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,QAAQ,GAChB,SAAS,GACT,OAAO,GACP,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,iGAAiG;IACjG,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;IAC/D,sCAAsC;IACtC,OAAO,IAAI,IAAI,CAAC;IAChB,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;CACtC;AAcD,wBAAgB,aAAa,IAAI,OAAO,CA2MvC"}
|
package/dist/sampler.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { slimEntry } from './trace.js';
|
|
2
|
+
/** Twenty minutes at two samples a second. */
|
|
3
|
+
const MAX_SAMPLES = 2400;
|
|
4
|
+
/** Trace entries kept, the engine's own default for a ring. */
|
|
5
|
+
const MAX_HISTORY = 500;
|
|
6
|
+
const RECOVERY = new Set(['nudge', 'flush', 'skip', 'gap-jump']);
|
|
7
|
+
/** A rendition's name for a mark: its height, else its bitrate. */
|
|
8
|
+
function label(r) {
|
|
9
|
+
return r.height !== undefined ? `${r.height}p` : `${Math.round(r.bitrate / 1000)} kbps`;
|
|
10
|
+
}
|
|
11
|
+
export function createSampler() {
|
|
12
|
+
let samples = [];
|
|
13
|
+
let marks = [];
|
|
14
|
+
let history = [];
|
|
15
|
+
/** Entries already taken, so the event and the ring never count one twice. */
|
|
16
|
+
let seen = new WeakSet();
|
|
17
|
+
let off = null;
|
|
18
|
+
let last = null;
|
|
19
|
+
let lastT = 0;
|
|
20
|
+
let lastQuality = null;
|
|
21
|
+
let lastPlayingId = null;
|
|
22
|
+
let stallStart = null;
|
|
23
|
+
let stalls = 0;
|
|
24
|
+
let stalledTotal = 0;
|
|
25
|
+
let switches = 0;
|
|
26
|
+
let decoded = 0;
|
|
27
|
+
let dropped = 0;
|
|
28
|
+
function push(mark) {
|
|
29
|
+
marks.push(mark);
|
|
30
|
+
if (marks.length > MAX_SAMPLES * 2)
|
|
31
|
+
marks.splice(0, marks.length - MAX_SAMPLES * 2);
|
|
32
|
+
}
|
|
33
|
+
/** The trace entries since the last read, oldest first. */
|
|
34
|
+
function fresh(engine) {
|
|
35
|
+
const trace = engine.stats.trace();
|
|
36
|
+
let from = 0;
|
|
37
|
+
if (last !== null) {
|
|
38
|
+
const at = trace.indexOf(last);
|
|
39
|
+
from = at >= 0 ? at + 1 : trace.findIndex((entry) => entry.t > lastT);
|
|
40
|
+
if (from < 0)
|
|
41
|
+
from = trace.length;
|
|
42
|
+
}
|
|
43
|
+
const tail = trace[trace.length - 1];
|
|
44
|
+
if (tail !== undefined) {
|
|
45
|
+
last = tail;
|
|
46
|
+
lastT = tail.t;
|
|
47
|
+
}
|
|
48
|
+
return trace.slice(from);
|
|
49
|
+
}
|
|
50
|
+
/** One entry in: its marks for the charts, and its slimmed self for the history. */
|
|
51
|
+
function take(entry, video) {
|
|
52
|
+
if (seen.has(entry))
|
|
53
|
+
return;
|
|
54
|
+
seen.add(entry);
|
|
55
|
+
history.push(slimEntry(entry));
|
|
56
|
+
if (history.length > MAX_HISTORY)
|
|
57
|
+
history.splice(0, history.length - MAX_HISTORY);
|
|
58
|
+
{
|
|
59
|
+
const msg = entry.msg;
|
|
60
|
+
if (msg.type === 'SEGMENT_LOADED' && msg.trackId !== 'manifest' && msg.size > 0) {
|
|
61
|
+
push({
|
|
62
|
+
t: entry.t,
|
|
63
|
+
kind: 'segment',
|
|
64
|
+
value: (msg.size * 8000) / Math.max(msg.rtt, 1),
|
|
65
|
+
label: `${msg.trackId} #${msg.seq}`,
|
|
66
|
+
trackId: msg.trackId,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (msg.type === 'STALLED') {
|
|
70
|
+
push({
|
|
71
|
+
t: entry.t,
|
|
72
|
+
kind: 'stall',
|
|
73
|
+
value: msg.at,
|
|
74
|
+
label: `stalled at ${msg.at.toFixed(1)}s`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (msg.type === 'SEEKING') {
|
|
78
|
+
push({ t: entry.t, kind: 'seek', value: msg.to, label: `seek to ${msg.to.toFixed(1)}s` });
|
|
79
|
+
}
|
|
80
|
+
for (const effect of entry.effects) {
|
|
81
|
+
if (effect.kind !== 'emit')
|
|
82
|
+
continue;
|
|
83
|
+
const name = effect.event.replace('recovery:', '');
|
|
84
|
+
if (RECOVERY.has(name)) {
|
|
85
|
+
push({
|
|
86
|
+
t: entry.t,
|
|
87
|
+
kind: name,
|
|
88
|
+
value: video.currentTime,
|
|
89
|
+
label: `recovery ${name}`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function reset() {
|
|
96
|
+
samples = [];
|
|
97
|
+
marks = [];
|
|
98
|
+
history = [];
|
|
99
|
+
seen = new WeakSet();
|
|
100
|
+
last = null;
|
|
101
|
+
lastT = 0;
|
|
102
|
+
lastQuality = null;
|
|
103
|
+
lastPlayingId = null;
|
|
104
|
+
stallStart = null;
|
|
105
|
+
stalls = 0;
|
|
106
|
+
stalledTotal = 0;
|
|
107
|
+
switches = 0;
|
|
108
|
+
decoded = 0;
|
|
109
|
+
dropped = 0;
|
|
110
|
+
}
|
|
111
|
+
function release() {
|
|
112
|
+
off?.();
|
|
113
|
+
off = null;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
attach(video, engine) {
|
|
117
|
+
release();
|
|
118
|
+
reset();
|
|
119
|
+
if (engine === null)
|
|
120
|
+
return;
|
|
121
|
+
off = engine.on('trace', (entry) => {
|
|
122
|
+
take(entry, video);
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
release,
|
|
126
|
+
poll(video, engine) {
|
|
127
|
+
const now = performance.now();
|
|
128
|
+
// The ring, for an engine that keeps one and emits nothing.
|
|
129
|
+
if (engine !== null)
|
|
130
|
+
for (const entry of fresh(engine))
|
|
131
|
+
take(entry, video);
|
|
132
|
+
const state = engine?.stats.snapshot() ?? null;
|
|
133
|
+
const playing = engine?.quality.playing ?? null;
|
|
134
|
+
const quality = video.getVideoPlaybackQuality?.();
|
|
135
|
+
decoded = quality?.totalVideoFrames ?? 0;
|
|
136
|
+
dropped = quality?.droppedVideoFrames ?? 0;
|
|
137
|
+
const droppedDelta = lastQuality === null ? 0 : Math.max(0, dropped - lastQuality.dropped);
|
|
138
|
+
const decodedDelta = lastQuality === null ? 0 : Math.max(0, decoded - lastQuality.decoded);
|
|
139
|
+
lastQuality = { dropped, decoded };
|
|
140
|
+
let ahead = 0;
|
|
141
|
+
for (let i = 0; i < video.buffered.length; i += 1) {
|
|
142
|
+
if (video.buffered.start(i) <= video.currentTime + 0.25 &&
|
|
143
|
+
video.buffered.end(i) > video.currentTime) {
|
|
144
|
+
ahead = video.buffered.end(i) - video.currentTime;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const stalled = !video.paused &&
|
|
148
|
+
!video.ended &&
|
|
149
|
+
!video.seeking &&
|
|
150
|
+
video.readyState < 3 &&
|
|
151
|
+
video.currentTime > 0;
|
|
152
|
+
if (stalled && stallStart === null) {
|
|
153
|
+
stallStart = now;
|
|
154
|
+
stalls += 1;
|
|
155
|
+
}
|
|
156
|
+
else if (!stalled && stallStart !== null) {
|
|
157
|
+
stalledTotal += (now - stallStart) / 1000;
|
|
158
|
+
stallStart = null;
|
|
159
|
+
}
|
|
160
|
+
if (playing !== null && lastPlayingId !== null && playing.id !== lastPlayingId) {
|
|
161
|
+
switches += 1;
|
|
162
|
+
push({
|
|
163
|
+
t: now,
|
|
164
|
+
kind: 'switch',
|
|
165
|
+
value: playing.height ?? playing.bitrate,
|
|
166
|
+
label: `now ${label(playing)}`,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
if (playing !== null)
|
|
170
|
+
lastPlayingId = playing.id;
|
|
171
|
+
samples.push({
|
|
172
|
+
t: now,
|
|
173
|
+
currentTime: video.currentTime,
|
|
174
|
+
slow: state?.stats.throughputEwma ?? 0,
|
|
175
|
+
fast: state?.stats.throughputFastEwma ?? 0,
|
|
176
|
+
ahead,
|
|
177
|
+
stalled,
|
|
178
|
+
dropped: droppedDelta,
|
|
179
|
+
decoded: decodedDelta,
|
|
180
|
+
playingId: playing?.id ?? null,
|
|
181
|
+
playingBitrate: playing?.bitrate ?? 0,
|
|
182
|
+
playingHeight: playing?.height ?? 0,
|
|
183
|
+
});
|
|
184
|
+
if (samples.length > MAX_SAMPLES)
|
|
185
|
+
samples.splice(0, samples.length - MAX_SAMPLES);
|
|
186
|
+
},
|
|
187
|
+
get samples() {
|
|
188
|
+
return samples;
|
|
189
|
+
},
|
|
190
|
+
get marks() {
|
|
191
|
+
return marks;
|
|
192
|
+
},
|
|
193
|
+
get history() {
|
|
194
|
+
return history;
|
|
195
|
+
},
|
|
196
|
+
get counters() {
|
|
197
|
+
const current = stallStart === null ? 0 : (performance.now() - stallStart) / 1000;
|
|
198
|
+
return {
|
|
199
|
+
stalls,
|
|
200
|
+
stalledSeconds: stalledTotal + current,
|
|
201
|
+
switches,
|
|
202
|
+
decoded,
|
|
203
|
+
dropped,
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=sampler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampler.js","sourceRoot":"","sources":["../src/sampler.ts"],"names":[],"mappings":"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"}
|
package/dist/style.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The element's stylesheet. The button is drawn the way the player's own
|
|
3
|
+
* buttons are, in a copy: the player's styles are internal, and a control
|
|
4
|
+
* of the page's own carries its own sheet. Tokens come through the
|
|
5
|
+
* `--mbx-*` custom properties the player sets, which inherit through light
|
|
6
|
+
* DOM; the chart colours have defaults here and a page overrides them the
|
|
7
|
+
* same way. Nothing carries `!important`, so a page's `::part()` rule wins.
|
|
8
|
+
*/
|
|
9
|
+
export declare const STYLE = "\n:host {\n display: inline-flex;\n position: relative;\n --mbx-chart-1: #5aa9e0;\n --mbx-chart-2: #6fbf8f;\n --mbx-chart-3: #d9a83f;\n --mbx-chart-4: #e05a6e;\n --mbx-chart-5: #a98fe0;\n}\n:host([hidden]) { display: none; }\n:host([inline]) { display: block; }\n[part~=\"button\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 40px;\n height: 40px;\n padding: 0;\n font: inherit;\n color: inherit;\n background: transparent;\n border: 0;\n border-radius: var(--mbx-radius);\n cursor: pointer;\n opacity: 0.9;\n}\n[part~=\"button\"]:hover { opacity: 1; }\n[part~=\"button\"]:focus-visible { outline: 2px solid var(--mbx-accent); outline-offset: -2px; }\n[part~=\"icon\"], ::slotted(*) { width: 1.75em; height: 1.75em; fill: currentColor; }\n:host([inline]) [part~=\"button\"] { display: none; }\n[part~=\"panel\"] {\n position: absolute;\n right: 0;\n bottom: 100%;\n box-sizing: border-box;\n width: 560px;\n margin-bottom: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n color: var(--mbx-text, #f2f3f5);\n background: rgba(16, 17, 20, 0.95);\n border-radius: var(--mbx-radius, 4px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);\n font: 400 12px/1.5 var(--mbx-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n text-align: left;\n white-space: normal;\n}\n[part~=\"panel\"][hidden] { display: none; }\n:host([inline]) [part~=\"panel\"] {\n position: static;\n width: auto;\n max-height: none;\n margin: 0;\n box-shadow: none;\n border-radius: 0;\n}\n[part~=\"head\"] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 8px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.12);\n}\n[part~=\"tab\"], [part~=\"chart-tab\"] {\n font: inherit;\n color: var(--mbx-muted, #9aa0a6);\n background: transparent;\n border: 0;\n border-radius: var(--mbx-radius, 4px);\n padding: 3px 8px;\n cursor: pointer;\n}\n[part~=\"tab\"][aria-selected=\"true\"], [part~=\"chart-tab\"][aria-selected=\"true\"] {\n color: var(--mbx-text, #f2f3f5);\n background: rgba(255, 255, 255, 0.12);\n}\n[part~=\"copy\"], [part~=\"close\"], [part~=\"window\"] {\n font: inherit;\n color: inherit;\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.25);\n border-radius: var(--mbx-radius, 4px);\n padding: 2px 8px;\n cursor: pointer;\n}\n[part~=\"copy\"] { margin-left: auto; }\n[part~=\"window\"] { margin-left: auto; }\n[part~=\"window\"] option { color: #000; }\n[part~=\"tab\"]:focus-visible, [part~=\"chart-tab\"]:focus-visible, [part~=\"copy\"]:focus-visible,\n[part~=\"close\"]:focus-visible, [part~=\"window\"]:focus-visible {\n outline: 2px solid var(--mbx-accent, #5b8cff);\n outline-offset: -2px;\n}\n[part~=\"body\"] { min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 8px; }\n[part~=\"page\"][hidden] { display: none; }\n[part~=\"rows\"] { display: grid; grid-template-columns: max-content 1fr; gap: 2px 12px; margin: 0; }\n[part~=\"key\"] { color: var(--mbx-muted, #9aa0a6); white-space: nowrap; }\n[part~=\"value\"] { margin: 0; overflow-wrap: anywhere; }\n[part~=\"heading\"] {\n margin: 10px 0 4px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--mbx-muted, #9aa0a6);\n}\n[part~=\"heading\"]:first-child { margin-top: 0; }\n[part~=\"note\"] { margin: 0; color: var(--mbx-muted, #9aa0a6); }\n[part~=\"chart-tabs\"] { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-bottom: 6px; }\n[part~=\"chart\"] { display: block; width: 100%; height: 160px; }\n[part~=\"legend\"] { display: flex; flex-wrap: wrap; gap: 2px 12px; margin-top: 4px; color: var(--mbx-muted, #9aa0a6); }\n[part~=\"swatch\"] { display: inline-block; width: 10px; height: 10px; margin-right: 4px; border-radius: 2px; vertical-align: middle; }\n[part~=\"readout\"] { margin-top: 4px; }\n[part~=\"table\"] { width: 100%; border-collapse: collapse; margin-bottom: 4px; }\n[part~=\"cell\"] { padding: 2px 6px; text-align: left; border-bottom: 1px solid rgba(255, 255, 255, 0.08); white-space: nowrap; font-weight: 400; }\n[part~=\"label\"] { color: var(--mbx-muted, #9aa0a6); }\n[part~=\"ok\"] { color: var(--mbx-chart-2); }\n[part~=\"bad\"] { color: var(--mbx-chart-4); }\n[part~=\"na\"] { color: var(--mbx-muted, #9aa0a6); }\n[part~=\"ok\"], [part~=\"bad\"], [part~=\"na\"], [part~=\"maybe\"] { font-weight: 600; }\n";
|
|
10
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,g3IA2HjB,CAAC"}
|