diff --git a/package.json b/package.json
index a104b118e..8eecf9a86 100644
--- a/package.json
+++ b/package.json
@@ -51,7 +51,7 @@
"ci:build": "yarn build:types && yarn build all && yarn build:i18n && yarn build:ts && yarn build:docs && yarn test:imports",
"test:imports": "node --test test/esm.test.js test/i18n.test.js test/ssr.test.js",
"typecheck": "node scripts/typecheck.mjs",
- "test:unit": "node --test test/dpip.test.js test/dpip-lifecycle.test.js test/canvas.test.js test/canvas-lifecycle.test.js test/ambilight.test.js test/ambilight-lifecycle.test.js test/ambilight-proxy.test.js test/vast.test.js test/vast-lifecycle.test.js test/ads.test.js test/ads-lifecycle.test.js test/playback.test.js test/dash-control.test.js test/dash-contract.test.js test/dash-lifecycle.test.js test/dash-events.test.js test/hls-control.test.js test/audio-track.test.js test/public-behavior.test.js test/helpers.test.js test/chapter.test.js test/utils.test.js test/resource-scope.test.js test/instance-lifecycle.test.js test/options.test.js test/media-hosts.test.js test/plugins.test.js test/source.test.js test/playback-properties.test.js test/media-events.test.js test/template-resources.test.js test/core-vendor.test.js test/component-resources.test.js test/setting-model.test.js test/setting-layout.test.js test/setting-resources.test.js test/subtitle.test.js test/display-native.test.js test/display-video-fullscreen.test.js test/display-pip.test.js test/display-mini.test.js test/display-sizing.test.js test/display-orientation.test.js test/hotkey.test.js test/listener-registry.test.js test/global-events.test.js test/pointer-events.test.js test/gesture.test.js test/event-scheduling.test.js test/notice.test.js test/fast-forward.test.js test/auto-playback.test.js test/builtin-layers.test.js test/prompt-components.test.js test/screenshot.test.js test/thumbnails.test.js test/progress.test.js test/environment.test.js test/storage.test.js test/facade-properties.test.js test/dom-boundaries.test.js test/initialization.test.js test/entry.test.js test/accessibility-button.test.js test/accessibility-focus.test.js test/accessibility-slider.test.js",
+ "test:unit": "node --test test/mediabunny.test.js test/dpip.test.js test/dpip-lifecycle.test.js test/canvas.test.js test/canvas-lifecycle.test.js test/ambilight.test.js test/ambilight-lifecycle.test.js test/ambilight-proxy.test.js test/vast.test.js test/vast-lifecycle.test.js test/ads.test.js test/ads-lifecycle.test.js test/playback.test.js test/dash-control.test.js test/dash-contract.test.js test/dash-lifecycle.test.js test/dash-events.test.js test/hls-control.test.js test/audio-track.test.js test/public-behavior.test.js test/helpers.test.js test/chapter.test.js test/utils.test.js test/resource-scope.test.js test/instance-lifecycle.test.js test/options.test.js test/media-hosts.test.js test/plugins.test.js test/source.test.js test/playback-properties.test.js test/media-events.test.js test/template-resources.test.js test/core-vendor.test.js test/component-resources.test.js test/setting-model.test.js test/setting-layout.test.js test/setting-resources.test.js test/subtitle.test.js test/display-native.test.js test/display-video-fullscreen.test.js test/display-pip.test.js test/display-mini.test.js test/display-sizing.test.js test/display-orientation.test.js test/hotkey.test.js test/listener-registry.test.js test/global-events.test.js test/pointer-events.test.js test/gesture.test.js test/event-scheduling.test.js test/notice.test.js test/fast-forward.test.js test/auto-playback.test.js test/builtin-layers.test.js test/prompt-components.test.js test/screenshot.test.js test/thumbnails.test.js test/progress.test.js test/environment.test.js test/storage.test.js test/facade-properties.test.js test/dom-boundaries.test.js test/initialization.test.js test/entry.test.js test/accessibility-button.test.js test/accessibility-focus.test.js test/accessibility-slider.test.js",
"test:coverage": "node --test test/coverage.test.js && node scripts/coverage.mjs",
"test": "yarn test:node && yarn test:baseline",
"test:browser": "playwright test",
@@ -75,7 +75,8 @@
"test:canvas": "node --test test/canvas.test.js test/canvas-lifecycle.test.js",
"test:canvas-types-package": "node refactor/scripts/canvas-package-types.mjs",
"test:dpip": "node --test test/dpip.test.js test/dpip-lifecycle.test.js",
- "test:dpip-types-package": "node refactor/scripts/dpip-package-types.mjs"
+ "test:dpip-types-package": "node refactor/scripts/dpip-package-types.mjs",
+ "test:mediabunny": "node --test test/mediabunny.test.js"
},
"browserslist": "last 1 Chrome version",
"devDependencies": {
diff --git a/refactor/baselines/mb-behavior-validation.json b/refactor/baselines/mb-behavior-validation.json
new file mode 100644
index 000000000..54e712dea
--- /dev/null
+++ b/refactor/baselines/mb-behavior-validation.json
@@ -0,0 +1,7058 @@
+{
+ "task": "PKG-MB-02",
+ "status": "done",
+ "parentCommit": "63c8938dd768539cba701a6ef171c17ddd877955",
+ "node": {
+ "tests": 24,
+ "reproducedHistoricalDefectCases": 18,
+ "normalAndVersionControls": 6
+ },
+ "browser": {
+ "report": "refactor/.cache/mb02-final-results/report.json",
+ "results": "refactor/.cache/mb02-final-results/results",
+ "total": 42,
+ "outcomes": {
+ "native-input-playback-and-seek": 16,
+ "historical-trackless-readiness-control": 4,
+ "historical-stream-lock-control": 3,
+ "historical-unsupported-hls-control": 3,
+ "unsupported-capability-control": 10,
+ "native-mp4-playback-observed": 4,
+ "verified-unsupported-capability-control": 2
+ },
+ "records": [
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "webm",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.010666666666666668,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2586666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.38933333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.38933333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.38933333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5693333333333332,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.8200000000000001,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8999999999999999,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.583,
+ "audioClock": 0.5986666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.667,
+ "audioClock": 0.6706666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.708,
+ "audioClock": 0.7186666666666668,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.792,
+ "audioClock": 0.7986666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.833,
+ "audioClock": 0.8493333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8786666666666667,
+ "paused": false
+ }
+ ],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.01633333333333331,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "blob",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.008,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2586666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5693333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.8200000000000001,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.9,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.9,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.5986666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.628,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.668,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7186666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7693333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.7986666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8493333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8786666666666667,
+ "paused": false
+ }
+ ],
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.019333333333333313,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "stream",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.008,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2586666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5693333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.8200000000000001,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.9,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.9,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.5986666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.628,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.668,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7186666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7693333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.7986666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8493333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8786666666666667,
+ "paused": false
+ }
+ ],
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": true
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.019333333333333313,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "audio",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2613333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0.5,
+ "duration": 16,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "hls",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2613333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.4,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.4,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.4,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.548,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.7986666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.8786666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.8786666666666667,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0.8786666666666667,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.5986666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.628,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.668,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7186666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7693333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.7986666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8493333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8786666666666667,
+ "paused": false
+ }
+ ],
+ "tracks": {
+ "initial": 180,
+ "quality": 90,
+ "videoMode": "manual",
+ "language": "fr",
+ "audioMode": "manual",
+ "afterSourceSwitch": null
+ },
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": {
+ "kind": "generated-hls-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "low-%02d.mpegts",
+ "low.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "high-%02d.mpegts",
+ "high.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "english-%02d.mpegts",
+ "english.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "french-%02d.mpegts",
+ "french.m3u8"
+ ]
+ ],
+ "files": {
+ "english-00.mpegts": {
+ "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207",
+ "bytes": 13912
+ },
+ "english-01.mpegts": {
+ "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5",
+ "bytes": 14100
+ },
+ "english-02.mpegts": {
+ "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb",
+ "bytes": 14100
+ },
+ "english-03.mpegts": {
+ "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e",
+ "bytes": 13912
+ },
+ "english-04.mpegts": {
+ "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9",
+ "bytes": 14100
+ },
+ "english-05.mpegts": {
+ "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533",
+ "bytes": 14100
+ },
+ "english-06.mpegts": {
+ "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a",
+ "bytes": 752
+ },
+ "english.m3u8": {
+ "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21",
+ "bytes": 365
+ },
+ "french-00.mpegts": {
+ "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd",
+ "bytes": 13912
+ },
+ "french-01.mpegts": {
+ "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13",
+ "bytes": 14100
+ },
+ "french-02.mpegts": {
+ "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0",
+ "bytes": 14100
+ },
+ "french-03.mpegts": {
+ "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b",
+ "bytes": 13912
+ },
+ "french-04.mpegts": {
+ "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601",
+ "bytes": 14100
+ },
+ "french-05.mpegts": {
+ "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9",
+ "bytes": 14100
+ },
+ "french-06.mpegts": {
+ "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46",
+ "bytes": 752
+ },
+ "french.m3u8": {
+ "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e",
+ "bytes": 358
+ },
+ "high-00.mpegts": {
+ "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833",
+ "bytes": 45308
+ },
+ "high-01.mpegts": {
+ "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c",
+ "bytes": 52264
+ },
+ "high-02.mpegts": {
+ "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440",
+ "bytes": 48128
+ },
+ "high-03.mpegts": {
+ "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5",
+ "bytes": 54144
+ },
+ "high-04.mpegts": {
+ "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c",
+ "bytes": 47376
+ },
+ "high-05.mpegts": {
+ "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15",
+ "bytes": 48128
+ },
+ "high.m3u8": {
+ "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d",
+ "bytes": 311
+ },
+ "low-00.mpegts": {
+ "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62",
+ "bytes": 28952
+ },
+ "low-01.mpegts": {
+ "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507",
+ "bytes": 32900
+ },
+ "low-02.mpegts": {
+ "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2",
+ "bytes": 30268
+ },
+ "low-03.mpegts": {
+ "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b",
+ "bytes": 32336
+ },
+ "low-04.mpegts": {
+ "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af",
+ "bytes": 29704
+ },
+ "low-05.mpegts": {
+ "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45",
+ "bytes": 29516
+ },
+ "low.m3u8": {
+ "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f",
+ "bytes": 305
+ },
+ "master.m3u8": {
+ "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38",
+ "bytes": 470
+ },
+ "video-only.m3u8": {
+ "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc",
+ "bytes": 108
+ }
+ }
+ },
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.019333333333333313,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "trackless",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-trackless-readiness-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": null,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": {
+ "parentSha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
+ "sha256": "8b03d7a9ce2998e592c081bb83e88ed6c15c7a4c9add6a1cc0fda88d88f678c0"
+ },
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "webm",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2613333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.6013333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.852,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8706666666666667,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8706666666666667,
+ "duration": 7.999666666,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.583,
+ "audioClock": 0.6013333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.667,
+ "audioClock": 0.6813333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.708,
+ "audioClock": 0.7106666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.792,
+ "audioClock": 0.8013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.833,
+ "audioClock": 0.852,
+ "paused": false
+ }
+ ],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 7,
+ "maxAbsoluteDeltaSeconds": 0.019000000000000017,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "blob",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2613333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5800000000000001,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.8306666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8813333333333333,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8813333333333333,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.6013333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.6813333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7106666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.8013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.852,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8813333333333333,
+ "paused": false
+ }
+ ],
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.01866666666666661,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "stream",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-stream-lock-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 300,
+ 150,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "Failed to execute 'getReader' on 'ReadableStream': ReadableStreamDefaultReader constructor can only accept readable streams that are not yet locked to a reader"
+ },
+ "readyState": 0,
+ "audioState": "running",
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "audio",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.25866666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.38666666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.38666666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.38666666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0.5,
+ "duration": 16,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "hls",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-unsupported-hls-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 300,
+ 150,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": null,
+ "error": {
+ "code": 4,
+ "message": "Input has an unsupported or unrecognizable format."
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": {
+ "kind": "generated-hls-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "low-%02d.mpegts",
+ "low.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "high-%02d.mpegts",
+ "high.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "english-%02d.mpegts",
+ "english.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "french-%02d.mpegts",
+ "french.m3u8"
+ ]
+ ],
+ "files": {
+ "english-00.mpegts": {
+ "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207",
+ "bytes": 13912
+ },
+ "english-01.mpegts": {
+ "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5",
+ "bytes": 14100
+ },
+ "english-02.mpegts": {
+ "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb",
+ "bytes": 14100
+ },
+ "english-03.mpegts": {
+ "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e",
+ "bytes": 13912
+ },
+ "english-04.mpegts": {
+ "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9",
+ "bytes": 14100
+ },
+ "english-05.mpegts": {
+ "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533",
+ "bytes": 14100
+ },
+ "english-06.mpegts": {
+ "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a",
+ "bytes": 752
+ },
+ "english.m3u8": {
+ "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21",
+ "bytes": 365
+ },
+ "french-00.mpegts": {
+ "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd",
+ "bytes": 13912
+ },
+ "french-01.mpegts": {
+ "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13",
+ "bytes": 14100
+ },
+ "french-02.mpegts": {
+ "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0",
+ "bytes": 14100
+ },
+ "french-03.mpegts": {
+ "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b",
+ "bytes": 13912
+ },
+ "french-04.mpegts": {
+ "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601",
+ "bytes": 14100
+ },
+ "french-05.mpegts": {
+ "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9",
+ "bytes": 14100
+ },
+ "french-06.mpegts": {
+ "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46",
+ "bytes": 752
+ },
+ "french.m3u8": {
+ "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e",
+ "bytes": 358
+ },
+ "high-00.mpegts": {
+ "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833",
+ "bytes": 45308
+ },
+ "high-01.mpegts": {
+ "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c",
+ "bytes": 52264
+ },
+ "high-02.mpegts": {
+ "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440",
+ "bytes": 48128
+ },
+ "high-03.mpegts": {
+ "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5",
+ "bytes": 54144
+ },
+ "high-04.mpegts": {
+ "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c",
+ "bytes": 47376
+ },
+ "high-05.mpegts": {
+ "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15",
+ "bytes": 48128
+ },
+ "high.m3u8": {
+ "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d",
+ "bytes": 311
+ },
+ "low-00.mpegts": {
+ "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62",
+ "bytes": 28952
+ },
+ "low-01.mpegts": {
+ "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507",
+ "bytes": 32900
+ },
+ "low-02.mpegts": {
+ "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2",
+ "bytes": 30268
+ },
+ "low-03.mpegts": {
+ "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b",
+ "bytes": 32336
+ },
+ "low-04.mpegts": {
+ "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af",
+ "bytes": 29704
+ },
+ "low-05.mpegts": {
+ "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45",
+ "bytes": 29516
+ },
+ "low.m3u8": {
+ "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f",
+ "bytes": 305
+ },
+ "master.m3u8": {
+ "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38",
+ "bytes": 470
+ },
+ "video-only.m3u8": {
+ "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc",
+ "bytes": 108
+ }
+ }
+ },
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "trackless",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-trackless-readiness-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 0,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": {
+ "parentSha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
+ "sha256": "8b03d7a9ce2998e592c081bb83e88ed6c15c7a4c9add6a1cc0fda88d88f678c0"
+ },
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "webm",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2506666666666667,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.38933333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.38933333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.38933333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.532,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.78,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.9,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.9,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.583,
+ "audioClock": 0.6013333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.667,
+ "audioClock": 0.6706666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.708,
+ "audioClock": 0.7213333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.792,
+ "audioClock": 0.8013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.833,
+ "audioClock": 0.852,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8813333333333333,
+ "paused": false
+ }
+ ],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.019000000000000017,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "blob",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2693333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.4,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.4,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.4,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5213333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.7693333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8893333333333334,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8893333333333334,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.5906666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6413333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.6706666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7213333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.8013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8493333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8893333333333334,
+ "paused": false
+ }
+ ],
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.016333333333333422,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "stream",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.272,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3813333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5293333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.78,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8706666666666666,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8706666666666666,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.5906666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.6813333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7106666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7613333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.8093333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8413333333333333,
+ "paused": false
+ }
+ ],
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": true
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 7,
+ "maxAbsoluteDeltaSeconds": 0.01766666666666672,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "audio",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.28,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.42133333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.42133333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.42133333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0.5,
+ "duration": 16,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "hls",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.2693333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.42133333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.42133333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.42133333333333334,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5213333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.7693333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.8999999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.8999999999999999,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0.8999999999999999,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.6013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.6706666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7213333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.8013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8493333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8813333333333333,
+ "paused": false
+ }
+ ],
+ "tracks": {
+ "initial": 180,
+ "quality": 90,
+ "videoMode": "manual",
+ "language": "fr",
+ "audioMode": "manual",
+ "afterSourceSwitch": null
+ },
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": {
+ "kind": "generated-hls-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "low-%02d.mpegts",
+ "low.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "high-%02d.mpegts",
+ "high.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "english-%02d.mpegts",
+ "english.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "french-%02d.mpegts",
+ "french.m3u8"
+ ]
+ ],
+ "files": {
+ "english-00.mpegts": {
+ "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207",
+ "bytes": 13912
+ },
+ "english-01.mpegts": {
+ "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5",
+ "bytes": 14100
+ },
+ "english-02.mpegts": {
+ "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb",
+ "bytes": 14100
+ },
+ "english-03.mpegts": {
+ "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e",
+ "bytes": 13912
+ },
+ "english-04.mpegts": {
+ "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9",
+ "bytes": 14100
+ },
+ "english-05.mpegts": {
+ "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533",
+ "bytes": 14100
+ },
+ "english-06.mpegts": {
+ "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a",
+ "bytes": 752
+ },
+ "english.m3u8": {
+ "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21",
+ "bytes": 365
+ },
+ "french-00.mpegts": {
+ "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd",
+ "bytes": 13912
+ },
+ "french-01.mpegts": {
+ "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13",
+ "bytes": 14100
+ },
+ "french-02.mpegts": {
+ "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0",
+ "bytes": 14100
+ },
+ "french-03.mpegts": {
+ "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b",
+ "bytes": 13912
+ },
+ "french-04.mpegts": {
+ "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601",
+ "bytes": 14100
+ },
+ "french-05.mpegts": {
+ "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9",
+ "bytes": 14100
+ },
+ "french-06.mpegts": {
+ "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46",
+ "bytes": 752
+ },
+ "french.m3u8": {
+ "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e",
+ "bytes": 358
+ },
+ "high-00.mpegts": {
+ "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833",
+ "bytes": 45308
+ },
+ "high-01.mpegts": {
+ "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c",
+ "bytes": 52264
+ },
+ "high-02.mpegts": {
+ "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440",
+ "bytes": 48128
+ },
+ "high-03.mpegts": {
+ "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5",
+ "bytes": 54144
+ },
+ "high-04.mpegts": {
+ "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c",
+ "bytes": 47376
+ },
+ "high-05.mpegts": {
+ "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15",
+ "bytes": 48128
+ },
+ "high.m3u8": {
+ "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d",
+ "bytes": 311
+ },
+ "low-00.mpegts": {
+ "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62",
+ "bytes": 28952
+ },
+ "low-01.mpegts": {
+ "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507",
+ "bytes": 32900
+ },
+ "low-02.mpegts": {
+ "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2",
+ "bytes": 30268
+ },
+ "low-03.mpegts": {
+ "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b",
+ "bytes": 32336
+ },
+ "low-04.mpegts": {
+ "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af",
+ "bytes": 29704
+ },
+ "low-05.mpegts": {
+ "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45",
+ "bytes": 29516
+ },
+ "low.m3u8": {
+ "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f",
+ "bytes": 305
+ },
+ "master.m3u8": {
+ "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38",
+ "bytes": 470
+ },
+ "video-only.m3u8": {
+ "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc",
+ "bytes": 108
+ }
+ }
+ },
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.017999999999999905,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "trackless",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-trackless-readiness-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": null,
+ "error": null,
+ "readyState": 4,
+ "audioState": "suspended",
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": {
+ "parentSha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
+ "sha256": "8b03d7a9ce2998e592c081bb83e88ed6c15c7a4c9add6a1cc0fda88d88f678c0"
+ },
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "webm",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.008000000000000007,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.25866666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.39999999999999997,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.39999999999999997,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.39999999999999997,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5479999999999999,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.8093333333333332,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8893333333333333,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8893333333333333,
+ "duration": 7.999666666,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.583,
+ "audioClock": 0.5986666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.628,
+ "paused": false
+ },
+ {
+ "frame": 0.667,
+ "audioClock": 0.6786666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.708,
+ "audioClock": 0.708,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7586666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.792,
+ "audioClock": 0.7986666666666666,
+ "paused": false
+ },
+ {
+ "frame": 0.833,
+ "audioClock": 0.8493333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8786666666666666,
+ "paused": false
+ }
+ ],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.01633333333333331,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "blob",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.26133333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.38133333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.38133333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.38133333333333336,
+ "readyState": 4
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0.5,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.5293333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.78,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.8893333333333334,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "currentTime": 0.8893333333333334,
+ "duration": 8,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [
+ {
+ "frame": 0.5,
+ "audioClock": 0.5,
+ "paused": true
+ },
+ {
+ "frame": 0.5833333333333334,
+ "audioClock": 0.6013333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.625,
+ "audioClock": 0.6306666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.6666666666666666,
+ "audioClock": 0.6813333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.7083333333333334,
+ "audioClock": 0.7106666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.75,
+ "audioClock": 0.7506666666666667,
+ "paused": false
+ },
+ {
+ "frame": 0.7916666666666666,
+ "audioClock": 0.8013333333333333,
+ "paused": false
+ },
+ {
+ "frame": 0.8333333333333334,
+ "audioClock": 0.8493333333333334,
+ "paused": false
+ },
+ {
+ "frame": 0.875,
+ "audioClock": 0.8813333333333334,
+ "paused": false
+ }
+ ],
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": {
+ "samples": 8,
+ "maxAbsoluteDeltaSeconds": 0.018000000000000016,
+ "scope": "Short SDK audio-clock comparison at observed native draws, not acoustic or long-run AV sync"
+ }
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "stream",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-stream-lock-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 300,
+ 150,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "ReadableStream.getReader: Cannot get a new reader for a readable stream already locked by another reader."
+ },
+ "readyState": 0,
+ "audioState": "suspended",
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "audio",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "native-input-playback-and-seek",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:play",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:playing",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:timeupdate",
+ "currentTime": 0.25866666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "video:pause",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeking",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "video:seeked",
+ "currentTime": 0.5,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0.5,
+ "duration": 16,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running",
+ "frameClockSamples": [],
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "hls",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-unsupported-hls-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 300,
+ 150,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": null,
+ "error": {
+ "code": 4,
+ "message": "Input has an unsupported or unrecognizable format."
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": {
+ "kind": "generated-hls-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "low-%02d.mpegts",
+ "low.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "high-%02d.mpegts",
+ "high.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "english-%02d.mpegts",
+ "english.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "french-%02d.mpegts",
+ "french.m3u8"
+ ]
+ ],
+ "files": {
+ "english-00.mpegts": {
+ "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207",
+ "bytes": 13912
+ },
+ "english-01.mpegts": {
+ "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5",
+ "bytes": 14100
+ },
+ "english-02.mpegts": {
+ "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb",
+ "bytes": 14100
+ },
+ "english-03.mpegts": {
+ "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e",
+ "bytes": 13912
+ },
+ "english-04.mpegts": {
+ "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9",
+ "bytes": 14100
+ },
+ "english-05.mpegts": {
+ "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533",
+ "bytes": 14100
+ },
+ "english-06.mpegts": {
+ "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a",
+ "bytes": 752
+ },
+ "english.m3u8": {
+ "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21",
+ "bytes": 365
+ },
+ "french-00.mpegts": {
+ "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd",
+ "bytes": 13912
+ },
+ "french-01.mpegts": {
+ "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13",
+ "bytes": 14100
+ },
+ "french-02.mpegts": {
+ "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0",
+ "bytes": 14100
+ },
+ "french-03.mpegts": {
+ "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b",
+ "bytes": 13912
+ },
+ "french-04.mpegts": {
+ "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601",
+ "bytes": 14100
+ },
+ "french-05.mpegts": {
+ "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9",
+ "bytes": 14100
+ },
+ "french-06.mpegts": {
+ "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46",
+ "bytes": 752
+ },
+ "french.m3u8": {
+ "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e",
+ "bytes": 358
+ },
+ "high-00.mpegts": {
+ "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833",
+ "bytes": 45308
+ },
+ "high-01.mpegts": {
+ "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c",
+ "bytes": 52264
+ },
+ "high-02.mpegts": {
+ "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440",
+ "bytes": 48128
+ },
+ "high-03.mpegts": {
+ "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5",
+ "bytes": 54144
+ },
+ "high-04.mpegts": {
+ "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c",
+ "bytes": 47376
+ },
+ "high-05.mpegts": {
+ "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15",
+ "bytes": 48128
+ },
+ "high.m3u8": {
+ "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d",
+ "bytes": 311
+ },
+ "low-00.mpegts": {
+ "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62",
+ "bytes": 28952
+ },
+ "low-01.mpegts": {
+ "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507",
+ "bytes": 32900
+ },
+ "low-02.mpegts": {
+ "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2",
+ "bytes": 30268
+ },
+ "low-03.mpegts": {
+ "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b",
+ "bytes": 32336
+ },
+ "low-04.mpegts": {
+ "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af",
+ "bytes": 29704
+ },
+ "low-05.mpegts": {
+ "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45",
+ "bytes": 29516
+ },
+ "low.m3u8": {
+ "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f",
+ "bytes": 305
+ },
+ "master.m3u8": {
+ "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38",
+ "bytes": 470
+ },
+ "video-only.m3u8": {
+ "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc",
+ "bytes": 108
+ }
+ }
+ },
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "trackless",
+ "capabilities": {
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-trackless-readiness-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadeddata",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplay",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:canplaythrough",
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 0,
+ "error": null,
+ "readyState": 4,
+ "audioState": "suspended",
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "closed",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": {
+ "parentSha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
+ "sha256": "8b03d7a9ce2998e592c081bb83e88ed6c15c7a4c9add6a1cc0fda88d88f678c0"
+ },
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "webm",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 1,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "blob",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 1
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 1,
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "stream",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 1
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 1,
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": true
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "audio",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 16,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "hls",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 12.031998,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0,
+ "hls": {
+ "levels": [
+ {
+ "id": 1,
+ "height": 90
+ },
+ {
+ "id": 4,
+ "height": 180
+ }
+ ],
+ "audios": [
+ {
+ "id": 2,
+ "lang": "en"
+ },
+ {
+ "id": 3,
+ "lang": "fr"
+ }
+ ]
+ }
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": {
+ "kind": "generated-hls-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "low-%02d.mpegts",
+ "low.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "high-%02d.mpegts",
+ "high.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "english-%02d.mpegts",
+ "english.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "french-%02d.mpegts",
+ "french.m3u8"
+ ]
+ ],
+ "files": {
+ "english-00.mpegts": {
+ "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207",
+ "bytes": 13912
+ },
+ "english-01.mpegts": {
+ "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5",
+ "bytes": 14100
+ },
+ "english-02.mpegts": {
+ "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb",
+ "bytes": 14100
+ },
+ "english-03.mpegts": {
+ "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e",
+ "bytes": 13912
+ },
+ "english-04.mpegts": {
+ "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9",
+ "bytes": 14100
+ },
+ "english-05.mpegts": {
+ "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533",
+ "bytes": 14100
+ },
+ "english-06.mpegts": {
+ "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a",
+ "bytes": 752
+ },
+ "english.m3u8": {
+ "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21",
+ "bytes": 365
+ },
+ "french-00.mpegts": {
+ "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd",
+ "bytes": 13912
+ },
+ "french-01.mpegts": {
+ "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13",
+ "bytes": 14100
+ },
+ "french-02.mpegts": {
+ "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0",
+ "bytes": 14100
+ },
+ "french-03.mpegts": {
+ "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b",
+ "bytes": 13912
+ },
+ "french-04.mpegts": {
+ "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601",
+ "bytes": 14100
+ },
+ "french-05.mpegts": {
+ "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9",
+ "bytes": 14100
+ },
+ "french-06.mpegts": {
+ "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46",
+ "bytes": 752
+ },
+ "french.m3u8": {
+ "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e",
+ "bytes": 358
+ },
+ "high-00.mpegts": {
+ "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833",
+ "bytes": 45308
+ },
+ "high-01.mpegts": {
+ "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c",
+ "bytes": 52264
+ },
+ "high-02.mpegts": {
+ "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440",
+ "bytes": 48128
+ },
+ "high-03.mpegts": {
+ "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5",
+ "bytes": 54144
+ },
+ "high-04.mpegts": {
+ "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c",
+ "bytes": 47376
+ },
+ "high-05.mpegts": {
+ "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15",
+ "bytes": 48128
+ },
+ "high.m3u8": {
+ "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d",
+ "bytes": 311
+ },
+ "low-00.mpegts": {
+ "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62",
+ "bytes": 28952
+ },
+ "low-01.mpegts": {
+ "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507",
+ "bytes": 32900
+ },
+ "low-02.mpegts": {
+ "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2",
+ "bytes": 30268
+ },
+ "low-03.mpegts": {
+ "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b",
+ "bytes": 32336
+ },
+ "low-04.mpegts": {
+ "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af",
+ "bytes": 29704
+ },
+ "low-05.mpegts": {
+ "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45",
+ "bytes": 29516
+ },
+ "low.m3u8": {
+ "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f",
+ "bytes": 305
+ },
+ "master.m3u8": {
+ "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38",
+ "bytes": 470
+ },
+ "video-only.m3u8": {
+ "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc",
+ "bytes": 108
+ }
+ }
+ },
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "input": "trackless",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadedmetadata",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:durationchange",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:progress",
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 1
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": null,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 1,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": {
+ "parentSha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
+ "sha256": "8b03d7a9ce2998e592c081bb83e88ed6c15c7a4c9add6a1cc0fda88d88f678c0"
+ },
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "webm",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 7.999666666,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "blob",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0,
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "stream",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-stream-lock-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 300,
+ 150,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 8,
+ "error": {
+ "code": 4,
+ "message": "ReadableStream is locked"
+ },
+ "readyState": 0,
+ "hls": null,
+ "inputBytes": 251538
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "audio",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 16,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "hls",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "historical-unsupported-hls-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 300,
+ 150,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": null,
+ "error": {
+ "code": 4,
+ "message": "Input has an unsupported or unrecognizable format."
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": {
+ "kind": "generated-hls-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "low-%02d.mpegts",
+ "low.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-t",
+ "12",
+ "-an",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-crf",
+ "28",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "high-%02d.mpegts",
+ "high.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "english-%02d.mpegts",
+ "english.m3u8"
+ ],
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-vn",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-f",
+ "hls",
+ "-hls_time",
+ "2",
+ "-hls_playlist_type",
+ "vod",
+ "-hls_segment_filename",
+ "french-%02d.mpegts",
+ "french.m3u8"
+ ]
+ ],
+ "files": {
+ "english-00.mpegts": {
+ "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207",
+ "bytes": 13912
+ },
+ "english-01.mpegts": {
+ "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5",
+ "bytes": 14100
+ },
+ "english-02.mpegts": {
+ "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb",
+ "bytes": 14100
+ },
+ "english-03.mpegts": {
+ "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e",
+ "bytes": 13912
+ },
+ "english-04.mpegts": {
+ "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9",
+ "bytes": 14100
+ },
+ "english-05.mpegts": {
+ "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533",
+ "bytes": 14100
+ },
+ "english-06.mpegts": {
+ "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a",
+ "bytes": 752
+ },
+ "english.m3u8": {
+ "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21",
+ "bytes": 365
+ },
+ "french-00.mpegts": {
+ "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd",
+ "bytes": 13912
+ },
+ "french-01.mpegts": {
+ "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13",
+ "bytes": 14100
+ },
+ "french-02.mpegts": {
+ "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0",
+ "bytes": 14100
+ },
+ "french-03.mpegts": {
+ "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b",
+ "bytes": 13912
+ },
+ "french-04.mpegts": {
+ "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601",
+ "bytes": 14100
+ },
+ "french-05.mpegts": {
+ "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9",
+ "bytes": 14100
+ },
+ "french-06.mpegts": {
+ "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46",
+ "bytes": 752
+ },
+ "french.m3u8": {
+ "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e",
+ "bytes": 358
+ },
+ "high-00.mpegts": {
+ "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833",
+ "bytes": 45308
+ },
+ "high-01.mpegts": {
+ "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c",
+ "bytes": 52264
+ },
+ "high-02.mpegts": {
+ "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440",
+ "bytes": 48128
+ },
+ "high-03.mpegts": {
+ "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5",
+ "bytes": 54144
+ },
+ "high-04.mpegts": {
+ "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c",
+ "bytes": 47376
+ },
+ "high-05.mpegts": {
+ "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15",
+ "bytes": 48128
+ },
+ "high.m3u8": {
+ "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d",
+ "bytes": 311
+ },
+ "low-00.mpegts": {
+ "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62",
+ "bytes": 28952
+ },
+ "low-01.mpegts": {
+ "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507",
+ "bytes": 32900
+ },
+ "low-02.mpegts": {
+ "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2",
+ "bytes": 30268
+ },
+ "low-03.mpegts": {
+ "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b",
+ "bytes": 32336
+ },
+ "low-04.mpegts": {
+ "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af",
+ "bytes": 29704
+ },
+ "low-05.mpegts": {
+ "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45",
+ "bytes": 29516
+ },
+ "low.m3u8": {
+ "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f",
+ "bytes": 305
+ },
+ "master.m3u8": {
+ "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38",
+ "bytes": 470
+ },
+ "video-only.m3u8": {
+ "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc",
+ "bytes": 108
+ }
+ }
+ },
+ "tracklessFixture": null,
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "input": "trackless",
+ "capabilities": {
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined"
+ },
+ "outcome": "unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "video:waiting",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:loadstart",
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "video:error",
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "currentTime": 0,
+ "duration": 0,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0,
+ "hls": null
+ },
+ "cleanup": {
+ "audioContext": "not-created",
+ "pendingFrames": 0,
+ "streamCancelled": false
+ },
+ "hlsManifest": null,
+ "tracklessFixture": {
+ "parentSha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233",
+ "sha256": "8b03d7a9ce2998e592c081bb83e88ed6c15c7a4c9add6a1cc0fda88d88f678c0"
+ },
+ "scope": "Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "capabilities": {
+ "secure": true,
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined",
+ "coreVersion": "5.4.0"
+ },
+ "outcome": "native-mp4-playback-observed",
+ "state": {
+ "events": [
+ {
+ "name": "waiting",
+ "time": 85.19999998807907,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 85.40000000596046,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "waiting",
+ "time": 85.5,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 85.5,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadedmetadata",
+ "time": 106.80000001192093,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "durationchange",
+ "time": 106.80000001192093,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "progress",
+ "time": 106.90000000596046,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "loadeddata",
+ "time": 118.69999998807907,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplay",
+ "time": 118.80000001192093,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplaythrough",
+ "time": 118.80000001192093,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "progress",
+ "time": 119,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "play",
+ "time": 170.19999998807907,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "playing",
+ "time": 170.19999998807907,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 181.09999999403954,
+ "currentTime": 0.02133333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 431.30000001192093,
+ "currentTime": 0.2693333333333333,
+ "readyState": 4
+ },
+ {
+ "name": "pause",
+ "time": 552.3000000119209,
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "ready": true,
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "paused": true,
+ "currentTime": 0.3893333333333333,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running"
+ },
+ "scope": "Two actual published proxies with actual core5.4.0; native MP4 pixels/clock or explicitly unsupported Windows WebKit APIs. No candidate, HLS or AV-sync acceptance.",
+ "frameClock": null
+ },
+ {
+ "project": "chromium",
+ "browser": "153.0.8010.12",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "capabilities": {
+ "secure": true,
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined",
+ "coreVersion": "5.4.0"
+ },
+ "outcome": "native-mp4-playback-observed",
+ "state": {
+ "events": [
+ {
+ "name": "waiting",
+ "time": 86.90000000596046,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 87,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "waiting",
+ "time": 87,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 87.09999999403954,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadedmetadata",
+ "time": 113.80000001192093,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "durationchange",
+ "time": 113.80000001192093,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "progress",
+ "time": 113.90000000596046,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "loadeddata",
+ "time": 124.90000000596046,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "loadeddata",
+ "time": 124.90000000596046,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplay",
+ "time": 125.19999998807907,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplaythrough",
+ "time": 125.19999998807907,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "progress",
+ "time": 125.19999998807907,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "play",
+ "time": 176.5,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "playing",
+ "time": 176.59999999403954,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 187.40000000596046,
+ "currentTime": 0.010666666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 453.09999999403954,
+ "currentTime": 0.27999999999999997,
+ "readyState": 4
+ },
+ {
+ "name": "pause",
+ "time": 572.1999999880791,
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "ready": true,
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "paused": true,
+ "currentTime": 0.3893333333333333,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running"
+ },
+ "scope": "Two actual published proxies with actual core5.4.0; native MP4 pixels/clock or explicitly unsupported Windows WebKit APIs. No candidate, HLS or AV-sync acceptance.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "capabilities": {
+ "secure": true,
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined",
+ "coreVersion": "5.4.0"
+ },
+ "outcome": "native-mp4-playback-observed",
+ "state": {
+ "events": [
+ {
+ "name": "waiting",
+ "time": 155,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 155,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "waiting",
+ "time": 155,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 155,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadedmetadata",
+ "time": 175,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "durationchange",
+ "time": 175,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "progress",
+ "time": 175,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "loadeddata",
+ "time": 194,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplay",
+ "time": 194,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplaythrough",
+ "time": 194,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "progress",
+ "time": 195,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "play",
+ "time": 299,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "playing",
+ "time": 299,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 303,
+ "currentTime": 0.008000000000000007,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 553,
+ "currentTime": 0.25866666666666666,
+ "readyState": 4
+ },
+ {
+ "name": "pause",
+ "time": 702,
+ "currentTime": 0.408,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "ready": true,
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "paused": true,
+ "currentTime": 0.408,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running"
+ },
+ "scope": "Two actual published proxies with actual core5.4.0; native MP4 pixels/clock or explicitly unsupported Windows WebKit APIs. No candidate, HLS or AV-sync acceptance.",
+ "frameClock": null
+ },
+ {
+ "project": "firefox",
+ "browser": "155.0",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "capabilities": {
+ "secure": true,
+ "VideoDecoder": "function",
+ "AudioDecoder": "function",
+ "AudioContext": "function",
+ "webkitAudioContext": "undefined",
+ "coreVersion": "5.4.0"
+ },
+ "outcome": "native-mp4-playback-observed",
+ "state": {
+ "events": [
+ {
+ "name": "waiting",
+ "time": 137,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 137,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "waiting",
+ "time": 137,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 137,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadedmetadata",
+ "time": 163,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "durationchange",
+ "time": 163,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "progress",
+ "time": 163,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "loadeddata",
+ "time": 172,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "loadeddata",
+ "time": 172,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplay",
+ "time": 173,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "canplaythrough",
+ "time": 173,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "progress",
+ "time": 173,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "play",
+ "time": 254,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "playing",
+ "time": 254,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 255,
+ "currentTime": 0,
+ "readyState": 4
+ },
+ {
+ "name": "timeupdate",
+ "time": 512,
+ "currentTime": 0.25066666666666665,
+ "readyState": 4
+ },
+ {
+ "name": "pause",
+ "time": 650,
+ "currentTime": 0.3893333333333333,
+ "readyState": 4
+ }
+ ],
+ "actions": [],
+ "ready": true,
+ "dimensions": [
+ 320,
+ 180,
+ 320,
+ 180
+ ],
+ "paused": true,
+ "currentTime": 0.3893333333333333,
+ "error": null,
+ "readyState": 4,
+ "audioState": "running"
+ },
+ "scope": "Two actual published proxies with actual core5.4.0; native MP4 pixels/clock or explicitly unsupported Windows WebKit APIs. No candidate, HLS or AV-sync acceptance.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.2.0",
+ "sha256": "7d088c0abe2f3c1e2857cb0547405ce1e5588630f28e484a64211fc675322bbd",
+ "capabilities": {
+ "secure": true,
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined",
+ "coreVersion": "5.4.0"
+ },
+ "outcome": "verified-unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "waiting",
+ "time": 150,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 150,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "waiting",
+ "time": 154,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 154,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "error",
+ "time": 212,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadedmetadata",
+ "time": 214,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "durationchange",
+ "time": 214,
+ "currentTime": 0,
+ "readyState": 1
+ },
+ {
+ "name": "progress",
+ "time": 214,
+ "currentTime": 0,
+ "readyState": 1
+ }
+ ],
+ "actions": [],
+ "ready": false,
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "paused": true,
+ "currentTime": 0,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 1
+ },
+ "scope": "Two actual published proxies with actual core5.4.0; native MP4 pixels/clock or explicitly unsupported Windows WebKit APIs. No candidate, HLS or AV-sync acceptance.",
+ "frameClock": null
+ },
+ {
+ "project": "webkit",
+ "browser": "26.6",
+ "platform": "win32",
+ "implementation": "published-1.0.0",
+ "sha256": "7331465d8c7a6575505b9d3fd45986c5d3d9cb3839b2620ad5a52c581199562b",
+ "capabilities": {
+ "secure": true,
+ "VideoDecoder": "undefined",
+ "AudioDecoder": "undefined",
+ "AudioContext": "undefined",
+ "webkitAudioContext": "undefined",
+ "coreVersion": "5.4.0"
+ },
+ "outcome": "verified-unsupported-capability-control",
+ "state": {
+ "events": [
+ {
+ "name": "waiting",
+ "time": 154,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 154,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "waiting",
+ "time": 154,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "loadstart",
+ "time": 154,
+ "currentTime": 0,
+ "readyState": 0
+ },
+ {
+ "name": "error",
+ "time": 216,
+ "currentTime": 0,
+ "readyState": 0
+ }
+ ],
+ "actions": [],
+ "ready": false,
+ "dimensions": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "paused": true,
+ "currentTime": 0,
+ "error": {
+ "code": 4,
+ "message": "undefined is not a constructor (evaluating 'new t')"
+ },
+ "readyState": 0
+ },
+ "scope": "Two actual published proxies with actual core5.4.0; native MP4 pixels/clock or explicitly unsupported Windows WebKit APIs. No candidate, HLS or AV-sync acceptance.",
+ "frameClock": null
+ }
+ ]
+ },
+ "fixtureSha256LF": {
+ "test/mediabunny.test.js": "cfde988178f6d358fca55bff21473a7f8855b3ceedc0b9507e5a2871fd7ac52e",
+ "test/browser/mediabunny.spec.js": "0d9af2fc2c47a9a78953e8c1fd69148ba553dc3b5e3f5ff0c141f537597ae9fe",
+ "test/browser/mediabunny-inputs.spec.js": "341ec06c3ec6e95ffce563eb47f423618a585b60a5057341e2d847e5004cbf0e",
+ "test/helpers/mediabunny.js": "3e25bd5274d58be4d0bb85cd5fb2a825848cae1bfdbfaf5c91177a0c2b03a87a",
+ "test/helpers/trackless-mp4.js": "41e56b43ba3d7a7dbc1ba0620109384afbf279c5283d8be4fa3e18d356e0d2f8"
+ },
+ "checks": [
+ {
+ "command": "yarn test:mediabunny",
+ "result": "pass",
+ "tests": 24,
+ "scope": "Actual historical engines with controlled lifecycle interleavings and Range responses"
+ },
+ {
+ "command": "focused eslint --no-fix",
+ "result": "pass",
+ "log": "refactor/.cache/mb02-lint-final.log"
+ },
+ {
+ "command": "yarn test:browser test/browser/mediabunny-inputs.spec.js test/browser/mediabunny.spec.js",
+ "result": "pass",
+ "tests": 42,
+ "log": "refactor/.cache/mb02-browser-final.log"
+ },
+ {
+ "command": "yarn ci:check",
+ "result": "pass",
+ "tests": {
+ "unit": 1030,
+ "engineering": 14,
+ "baseline": 141,
+ "mainTotal": 1185,
+ "repeatedContractExecutions": 44
+ },
+ "strictProductionTypeScriptFiles": 290,
+ "log": "refactor/.cache/mb02-ci-integrated.log"
+ },
+ {
+ "command": "production/demo/artifact hashes compared with frozen source",
+ "result": "unchanged",
+ "files": 17
+ }
+ ],
+ "limitations": [
+ "Historical baseline, not candidate fixes or release acceptance.",
+ "36 native-input cases use a controlled ArtPlayer host; six MP4 cases use actual core5.4.0.",
+ "Short frame/audio-clock observations are not acoustic latency, long-run drift or a device support claim; complete AV sync remains MB-06/09.",
+ "Normal settled-playback AudioContext/RAF cleanup does not waive the reproduced pending-operation failures.",
+ "HLS state transitions tested; actual control/setting DOM and concurrent topology updates remain MB-07/09.",
+ "Canvas/Ambilight factory compatibility decision remains pending."
+ ],
+ "ciIntegration": "Added test/mediabunny.test.js to explicit test:unit list and added test:mediabunny; initial full CI passed without these cases, then integration was corrected and full CI rerun."
+}
diff --git a/refactor/changes/2026-09-12-PKG-MB-02-baseline.md b/refactor/changes/2026-09-12-PKG-MB-02-baseline.md
new file mode 100644
index 000000000..2be8739c8
--- /dev/null
+++ b/refactor/changes/2026-09-12-PKG-MB-02-baseline.md
@@ -0,0 +1,71 @@
+# PKG-MB-02 媒体、事件与资源基线
+
+此记录接续63c8938d检查点。完成状态以[验证记录](../baselines/mb-behavior-validation.json)和
+独立完成提交为准;历史负例通过表示问题已经复现,不表示生产实现已修复。
+
+## 浏览器覆盖
+
+两个实际npm proxy 1.0.0/1.2.0,三引擎,共42项:
+
+- 6项完整核心5.4.0组合:4次真实MP4播放/像素/暂停成功,2次Windows WebKit能力失败对照。
+- 36项真实SDK输入,使用实际核心utils/config与受控ArtPlayer宿主:WebM、MP4 Blob、4096字节分块
+ ReadableStream、纯音频、HLS、无轨道容器。受控宿主用于隔离核心自动重连,不模拟浏览器解码器。
+- 后36项中16项完成真实输入播放、暂停、精确seek和恢复;10项缺失WebCodecs/Web Audio构造器;
+ 3项1.0.0流锁定错误,3项1.0.0 HLS不支持;4项无轨道容器错误地声称ready的历史行为。
+- 总计20次真实播放成功、12次环境能力对照、6次历史输入失败、4次无轨道就绪行为;不能称42次播放成功。
+
+1.0.0的ReadableStream同时被旧音/视频输入读取,三个浏览器报精确的stream locked错误;
+1.0.0的HLS错误为`Input has an unsupported or unrecognizable format.`。
+这些在1.2.0已正常,候选必须保持修正。Windows WebKit的构造器缺失单独判断,不能把同一环境
+中的历史stream/HLS错误都归为环境问题,也不能将Windows WebKit结论扩大为全部Safari。
+
+## 就绪、seek、HLS与时钟
+
+就绪顺序和次数使用逐事件断言:1.0.0 WebM/Blob初次有两个loadeddata,seek又发一次;1.2.0无该重复。
+视频为空但音频存在的正常容器单独验证;无任何轨道的容器由仓库MP4移除trak后确定性生成,
+记录父文件和派生文件哈希,不下载不明媒体。两代均readyState=4且尺寸0,1.2.0的loadedmetadata
+发两次、1.0.0一次。MB-READY-01保留后续协调修复责任。
+
+seek测试观测公开currentTime setter调用实际engine.seek的Promise,不替换实现;验证目标时间、
+seeking/paused和精确事件序列。HLS使用既有哈希校验的本地12秒样本,实际切到90p、法语音轨,
+核对manual模式,再切回MP4并确认HLS状态null。真实控件/设置DOM、并发选轨和组合长播仍由MB-07/09验收。
+
+纯音频/HLS检查实际AudioBufferSink和已排程Web Audio节点。视频恢复播放时观测实际CanvasSink
+迭代器的frame timestamp和真正drawImage时的audio.currentTime,保留原始样本与偏差统计。
+这是短时SDK时钟基线,不能当作声学音画延迟、长期漂移或各设备音频输出都已验证;对应后续MB-06/09。
+
+settled playback完成后验证创建的AudioContext关闭、所观测代理RAF队列归零。
+不据此宣称所有内部资源或pending操作都已释放;后者有明确失败基线。
+
+## 生命周期与Range
+
+24项Node测试使用三份实际历史主产物、原始engine方法,控制外部Promise、音频动作和timer:
+
+1. destroy后晚load失败仍回写error/networkState,waiting/loadstart两个timer仍执行。
+2. pending play遇到pause,晚返回仍video.start并发play/playing,paused却为true。
+3. pending play遇到destroy,晚返回仍video.start并发事件。
+4. audio.play拒绝后engine.paused保持false,第二次play不再重试。
+5. pending seek遇到destroy,晚返回仍seeked并恢复play。
+6. 成功load与destroy都未回收loadTimeout timer;已settled的race继续观察其晚拒绝。
+7. 正常超时仍保持code4/Load timeout,不被底层更晚的拒绝覆盖。
+8. HEAD Range预检拒绝缺失响应头、网络异常警告后继续;不设置engine.error;1.0.0仍预检HLS,1.2.0跳过。
+
+前6组共18项复现历史问题;后2组6项保留正常/版本边界。不会将受控宿主发事件直接等同于
+完整ArtPlayer核心destroy后用户仍收到事件;也不会用模拟音频动作宣称真实音画同步通过。
+
+## 检查与后续
+
+```sh
+node --test test/mediabunny.test.js
+yarn test:browser test/browser/mediabunny-inputs.spec.js test/browser/mediabunny.spec.js
+yarn ci:check
+```
+
+早期30项输入实验中的四个Chromium/Firefox 1.0.0错误已保留完整报告、trace及截图,随后才建立
+精确历史负例。各次浏览器report和整个results目录分别归档,未覆盖失败证据。
+下一步MB-03处理input、Range和取消,MB-04处理主状态/事件协调,05/06处理帧及音频调度,
+07处理轨道/控件。这些缺陷均未在本步修改生产代码;工厂类型待决项仍只影响Canvas/Ambilight。
+
+最终CI1185项(1030单元+14工程+141基线)通过,另44重复契约;290生产TS严格检查。
+新增test:mediabunny并将24项加入test:unit,补齐首次CI未包含该文件的入口遗漏后重跑全量CI。
+17个冻结生产/demo/产物和五个最终测试文件哈希已复核;本任务独立本地提交。
diff --git a/refactor/mb-validation.md b/refactor/mb-validation.md
index 2d52842e3..f960ecbfe 100644
--- a/refactor/mb-validation.md
+++ b/refactor/mb-validation.md
@@ -1,7 +1,8 @@
# MediaBunny proxy 验证入口
开始改动前读取[冻结契约](baselines/mb-contract.md)、[接口快照](baselines/mb-surface.json)、
-[归档/源码哈希](baselines/mb-release.json)。当前阶段为PKG-MB-01;不得把接口基线称为真实媒体验收。
+[归档/源码哈希](baselines/mb-release.json)。MB-01接口基线与
+[MB-02行为基线](changes/2026-09-12-PKG-MB-02-baseline.md)分开记录;不得把接口测试称为真实媒体验收。
## 可重复命令
@@ -10,6 +11,8 @@
```sh
node refactor/scripts/mb-contract.mjs
node --test refactor/scripts/mb-contract.test.mjs
+node --test test/mediabunny.test.js
+yarn test:browser test/browser/mediabunny-inputs.spec.js test/browser/mediabunny.spec.js
yarn ci:check
```
@@ -22,8 +25,9 @@ play/load/seek转发测试刻意截获engine方法;不得宣传为真实播放
## 后续顺序
-1. MB-02建立真实MP4/WebM/HLS/Blob/Stream和失败样本;三浏览器能力分别记录。
- 复现pending load/destroy、超时后释放、无轨道、并发seek/选轨、metadata重复与晚帧/音频回调。
+1. MB-02的输入、seek、HLS轨道、无轨道和失败样本见行为基线。42项浏览器检查须区分
+ 20次实际播放、12次能力对照、6次历史输入失败及4次无轨道就绪行为;24项生命周期测试含18个历史缺陷。
+ 后续修改须复跑对应正常和负例,不把全部负例变为候选豁免;并发选轨、晚帧和音频回调的完整修复分别在04/05/06/07。
2. MB-03输入/取消,MB-04事件/状态协调,MB-05帧调度,MB-06音频时钟,MB-07配对轨道/控件。
按已批准计划分步迁移,不等到MB-08才一次性堆积全部源码修改。
3. MB-08完成严格TS和公开声明兼容矩阵;保留HTMLCanvasElement精确Result、可选工厂和全工厂
diff --git a/refactor/plan.md b/refactor/plan.md
index d4bb1a00b..2aef873f7 100644
--- a/refactor/plan.md
+++ b/refactor/plan.md
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 222 项,范围 22 个包及工作区/示例。
-状态:todo 116 / doing 8 / blocked 0 / done 98 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
+状态:todo 116 / doing 7 / blocked 0 / done 99 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -330,7 +330,7 @@
| ID | 范围 / 步骤 | 前置依赖 | 交付物 | 验收条件 | 风险 | 状态 |
| --- | --- | --- | --- | --- | --- | --- |
| PKG-MB-01 | artplayer-proxy-mediabunny
核对 shim 与媒体契约 | BASE-05 | 全部 option、art.mediabunny、canvas/shim 属性及事件表 | 公开暴露成员和实际发布依赖/资源范围明确;核实 third-party.json 所记录依赖 MPL-2.0 元数据与实际 bundle 的许可/通知范围,不从根 MIT 推断 | H | done |
-| PKG-MB-02 | artplayer-proxy-mediabunny
建立真实媒体与事件基线 | PKG-MB-01, ENG-05, ENG-08 | MP4/WebM/HLS/Blob/Stream、seek/错误/轨道切换样本 | ready 事件顺序、音画同步、超时和释放可重跑 | H | doing |
+| PKG-MB-02 | artplayer-proxy-mediabunny
建立真实媒体与事件基线 | PKG-MB-01, ENG-05, ENG-08 | MP4/WebM/HLS/Blob/Stream、seek/错误/轨道切换样本 | ready 事件顺序、音画同步、超时和释放可重跑 | H | done |
| PKG-MB-03 | artplayer-proxy-mediabunny
整理 input 与加载取消 | PKG-MB-02, CORE-09 | input.js 源检测、输入资源、Range 与取消 | HLS 检测在 input 边界,旧来源类型和超时保持 | H | todo |
| PKG-MB-04 | artplayer-proxy-mediabunny
整理 VideoShim/EventTarget/Engine 协调 | PKG-MB-03, CORE-06, CORE-11 | shim 描述符、事件桥、加载状态和操作隔离 | 公开属性/同步异步返回与事件重入顺序保持 | H | todo |
| PKG-MB-05 | artplayer-proxy-mediabunny
整理视频解码、seek 和帧释放 | PKG-MB-04 | VideoEngine 调度、队列、晚帧处理和资源释放 | 暂停/seek/切源无旧帧覆盖,默认丢帧策略不变 | H | todo |
@@ -521,5 +521,5 @@
- PKG-CANVAS-03: [记录](changes/2026-09-12-PKG-CANVAS-03-lifecycle.md) [记录](baselines/canvas-lifecycle-validation.json) [记录](canvas-validation.md)
- PKG-CANVAS-04: [记录](changes/2026-09-12-PKG-CANVAS-04-types.md) [记录](baselines/canvas-types-validation.json) [记录](canvas-validation.md)
- PKG-MB-01: [记录](baselines/mb-release.json) [记录](baselines/mb-surface.json) [记录](baselines/mb-contract.md) [记录](baselines/mb-contract-validation.json) [记录](mb-validation.md) [记录](changes/2026-09-12-PKG-MB-01-contract.md)
-- PKG-MB-02: [记录](changes/2026-09-12-PKG-MB-02-checkpoint.md) [记录](baselines/mb-media-checkpoint.json) [记录](mb-validation.md)
+- PKG-MB-02: [记录](changes/2026-09-12-PKG-MB-02-checkpoint.md) [记录](baselines/mb-media-checkpoint.json) [记录](mb-validation.md) [记录](changes/2026-09-12-PKG-MB-02-baseline.md) [记录](baselines/mb-behavior-validation.json)
- PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md)
diff --git a/refactor/progress.md b/refactor/progress.md
index e59fe95e9..006e910dd 100644
--- a/refactor/progress.md
+++ b/refactor/progress.md
@@ -1,5 +1,15 @@
# 进度与证据
+## 最新完成:PKG-MB-02 媒体、事件与资源基线
+
+24项历史生命周期检查通过,已接入统一CI;42项真实浏览器检查包含20次播放、12次环境能力
+对照、6次历史输入失败和4次无轨道就绪行为,不能当作42次播放成功。短时帧/音频时钟、seek、
+HLS轨道状态及正常AudioContext/RAF释放均有证据;待完成操作的泄漏和陈旧回调已复现。
+完整CI1185项(1030单元+14工程+141基线)通过,另44重复契约,290生产TS。
+见[任务记录](changes/2026-09-12-PKG-MB-02-baseline.md)和[验证证据](baselines/mb-behavior-validation.json)。
+生产源码未在本步变更;接着MB-03输入与加载取消。222项:99 done、7 doing、116 todo。
+Canvas/Ambilight类型决定仍待确认;未推送或发布。
+
## 当前检查点:PKG-MB-02 真实MP4与销毁负例
22项Node(含3个销毁后晚加载历史缺陷)通过;6项浏览器检查中,4项Chromium/Firefox
diff --git a/refactor/risk-table.md b/refactor/risk-table.md
index 59fc2ac7f..09a7ff4a4 100644
--- a/refactor/risk-table.md
+++ b/refactor/risk-table.md
@@ -172,3 +172,4 @@
| MB-LIFE-01 | open / 已复现 | MediaBunny load, track replacement, timeout, RAF and audio callbacks lack one shared terminal owner | PKG-MB-02, PKG-MB-03, PKG-MB-04, PKG-MB-05, PKG-MB-06, PKG-MB-07, PKG-MB-09 |
| MB-TYPE-01 | open / 已复现 | MediaBunny proxy declares only Canvas while exposing a shim and changes CommonJS export generation between releases | PKG-MB-08, PKG-MB-10 |
| MB-CAP-01 | open / 已复现 | Current Windows WebKit lacks WebCodecs and Web Audio constructors needed by historical MediaBunny proxies | PKG-MB-02, PKG-MB-09 |
+| MB-READY-01 | open / 已复现 | MediaBunny historical readiness can repeat for trackless input and occur after capability errors | PKG-MB-04, PKG-MB-09 |
diff --git a/refactor/risks.json b/refactor/risks.json
index 846950375..3097670cf 100644
--- a/refactor/risks.json
+++ b/refactor/risks.json
@@ -3648,7 +3648,7 @@
"PKG-MB-07",
"PKG-MB-09"
],
- "compatibleResolution": "Reproduce pending operations and destroy/source-switch races before migrating each owner; preserve public event and promise behavior while preventing stale resource use. MB-02 now reproduces late load rejection and uncancelled waiting/loadstart timers after destroy in all three historical implementations using a controlled host. Other interleavings and full-core native behavior are not yet verified.",
+ "compatibleResolution": "Reproduce pending operations and destroy/source-switch races before migrating each owner; preserve public event and promise behavior while preventing stale resource use. MB-02 now reproduces late load rejection and uncancelled waiting/loadstart timers after destroy in all three historical implementations using a controlled host. Other interleavings and full-core native behavior are not yet verified. Expanded MB-02 baseline reproduces play-after-pause/destroy, rejected-play false state, seek-after-destroy and retained successful-load timeout timers in all three actual historical implementations; Range and active-timeout normal controls remain separate.",
"closureCriteria": "Historical failing interleavings and candidate cancellation/cleanup pass with real media and event evidence, including long playback and track topology.",
"status": "open",
"evidence": [
@@ -3656,7 +3656,9 @@
"refactor/baselines/mb-contract.md",
"refactor/changes/2026-09-12-PKG-MB-01-contract.md",
"refactor/changes/2026-09-12-PKG-MB-02-checkpoint.md",
- "refactor/baselines/mb-media-checkpoint.json"
+ "refactor/baselines/mb-media-checkpoint.json",
+ "refactor/changes/2026-09-12-PKG-MB-02-baseline.md",
+ "refactor/baselines/mb-behavior-validation.json"
]
},
{
@@ -3689,7 +3691,25 @@
"closureCriteria": "Per-browser native media/support matrix and predictable unsupported-capability behavior verified, including target Safari evidence where support is claimed.",
"evidence": [
"refactor/changes/2026-09-12-PKG-MB-02-checkpoint.md",
- "refactor/baselines/mb-media-checkpoint.json"
+ "refactor/baselines/mb-media-checkpoint.json",
+ "refactor/changes/2026-09-12-PKG-MB-02-baseline.md",
+ "refactor/baselines/mb-behavior-validation.json"
+ ]
+ },
+ {
+ "id": "MB-READY-01",
+ "title": "MediaBunny historical readiness can repeat for trackless input and occur after capability errors",
+ "status": "open",
+ "confirmation": "reproduced",
+ "owners": [
+ "PKG-MB-04",
+ "PKG-MB-09"
+ ],
+ "compatibleResolution": "Use explicit coordinated readiness and failure state, preserving valid event order while preventing duplicate or stale callbacks; evaluate trackless behavior separately from normal media.",
+ "closureCriteria": "Candidate metadata/data/canplay ordering and counts pass normal, absent-track and failure interleavings in native browsers and controlled race tests.",
+ "evidence": [
+ "refactor/changes/2026-09-12-PKG-MB-02-baseline.md",
+ "refactor/baselines/mb-behavior-validation.json"
]
}
]
diff --git a/refactor/tasks.json b/refactor/tasks.json
index cf796d1ae..1717a6ef0 100644
--- a/refactor/tasks.json
+++ b/refactor/tasks.json
@@ -3416,14 +3416,16 @@
"ENG-05",
"ENG-08"
],
- "status": "doing",
+ "status": "done",
"risk": "H",
"deliverable": "MP4/WebM/HLS/Blob/Stream、seek/错误/轨道切换样本",
"acceptance": "ready 事件顺序、音画同步、超时和释放可重跑",
"evidence": [
"changes/2026-09-12-PKG-MB-02-checkpoint.md",
"baselines/mb-media-checkpoint.json",
- "mb-validation.md"
+ "mb-validation.md",
+ "changes/2026-09-12-PKG-MB-02-baseline.md",
+ "baselines/mb-behavior-validation.json"
]
},
{
diff --git a/test/browser/mediabunny-inputs.spec.js b/test/browser/mediabunny-inputs.spec.js
new file mode 100644
index 000000000..53242df3e
--- /dev/null
+++ b/test/browser/mediabunny-inputs.spec.js
@@ -0,0 +1,215 @@
+import assert from 'node:assert/strict'
+import fs from 'node:fs'
+import { hash } from '../../refactor/scripts/releases.mjs'
+import { mbHistorical } from '../helpers/mediabunny.js'
+import { tracklessMp4 } from '../helpers/trackless-mp4.js'
+import { expect, test } from './fixtures.js'
+
+const implementations = (await mbHistorical()).filter(item => item.name.startsWith('published'))
+const manifest = JSON.parse(fs.readFileSync(new URL('./media/hls/manifest.json', import.meta.url)))
+const hls = new Map(Object.entries(manifest.files).map(([name, expected]) => {
+ const bytes = fs.readFileSync(new URL(`./media/hls/${name}`, import.meta.url))
+ assert.equal(hash(bytes), expected.sha256)
+ return [name, bytes]
+}))
+const pattern = fs.readFileSync(new URL('./media/pattern.mp4', import.meta.url))
+const trackless = tracklessMp4(pattern)
+
+for (const implementation of implementations) {
+ for (const input of ['webm', 'blob', 'stream', 'audio', 'hls', 'trackless']) {
+ test(`MediaBunny ${implementation.name}: native ${input} input and seek baseline`, async ({ page, browserName }, testInfo) => {
+ await page.route('**/mb-hls/**', async (route) => {
+ const name = new URL(route.request().url()).pathname.split('/').at(-1)
+ const body = hls.get(name)
+ await route.fulfill({ status: body ? 200 : 404, body: body || 'Missing fixture', contentType: name.endsWith('.m3u8') ? 'application/vnd.apple.mpegurl' : 'video/mp2t' })
+ })
+ await page.route('**/mb-trackless.mp4', route => route.fulfill({ status: 200, body: trackless, contentType: 'video/mp4' }))
+ await page.goto('/test/player.html?core=published')
+ await page.addScriptTag({ content: `(() => {
+ const pendingFrames = new Set();
+ const requestAnimationFrame = callback => {
+ const id = window.requestAnimationFrame(time => { pendingFrames.delete(id); callback(time); });
+ pendingFrames.add(id); return id;
+ };
+ const cancelAnimationFrame = id => { pendingFrames.delete(id); window.cancelAnimationFrame(id); };
+ window.mbPendingFrames = pendingFrames;
+ const module = { exports: {} }; const exports = module.exports;
+ ${implementation.code}; window.mbFactory = module.exports.default || module.exports;
+ })();` })
+ const capabilities = await page.evaluate(() => ({ VideoDecoder: typeof VideoDecoder, AudioDecoder: typeof AudioDecoder, AudioContext: typeof AudioContext, webkitAudioContext: typeof window.webkitAudioContext }))
+ let outcome = 'unverified'
+ try {
+ await page.evaluate(async (input) => {
+ const listeners = new Map()
+ window.mbEvents = []
+ window.mbActions = []
+ window.mbHost = {
+ constructor: window.Artplayer,
+ option: { url: '', autoSize: false },
+ template: { $player: document.querySelector('.player') },
+ on(name, fn) {
+ const list = listeners.get(name) || []
+ list.push(fn)
+ listeners.set(name, list)
+ },
+ emit(name, ...args) {
+ window.mbEvents.push({ name, currentTime: window.mbCanvas?.currentTime, readyState: window.mbCanvas?.readyState })
+ for (const fn of listeners.get(name) || []) fn(...args)
+ },
+ }
+ const canvas = window.mbFactory({ muted: true })(window.mbHost)
+ window.mbCanvas = canvas
+ document.querySelector('.player').appendChild(canvas)
+ let source = input === 'webm' ? '/test/pattern.webm' : input === 'audio' ? '/test/audio-tone.m4a' : input === 'hls' ? '/mb-hls/master.m3u8' : input === 'trackless' ? '/mb-trackless.mp4' : '/test/pattern.mp4'
+ if (input === 'blob' || input === 'stream') {
+ const bytes = new Uint8Array(await (await fetch(source)).arrayBuffer())
+ window.mbInputBytes = bytes.length
+ source = input === 'blob'
+ ? new Blob([bytes], { type: 'video/mp4' })
+ : new ReadableStream({
+ start(controller) {
+ for (let offset = 0; offset < bytes.length; offset += 4096) controller.enqueue(bytes.slice(offset, offset + 4096))
+ controller.close()
+ },
+ cancel() { window.mbStreamCancelled = true },
+ })
+ }
+ const load = canvas.engine.load.bind(canvas.engine)
+ canvas.engine.load = (source) => {
+ window.mbLoad = load(source)
+ return window.mbLoad
+ }
+ canvas.src = source
+ await window.mbLoad
+ document.querySelector('#play').onclick = () => canvas.play().catch(error => window.mbActions.push({ name: error.name, message: error.message }))
+ }, input)
+ const loaded = await page.evaluate(() => ({ error: window.mbCanvas.error, readyState: window.mbCanvas.readyState, dimensions: [window.mbCanvas.videoWidth, window.mbCanvas.videoHeight] }))
+ if (implementation.name === 'published-1.0.0' && ['stream', 'hls'].includes(input)) {
+ const messages = {
+ chromium: 'Failed to execute \'getReader\' on \'ReadableStream\': ReadableStreamDefaultReader constructor can only accept readable streams that are not yet locked to a reader',
+ firefox: 'ReadableStream.getReader: Cannot get a new reader for a readable stream already locked by another reader.',
+ webkit: 'ReadableStream is locked',
+ }
+ expect(loaded.error).toEqual({ code: 4, message: input === 'hls' ? 'Input has an unsupported or unrecognizable format.' : messages[browserName] })
+ expect(loaded.readyState).toBe(0)
+ expect(loaded.dimensions).toEqual([0, 0])
+ outcome = input === 'hls' ? 'historical-unsupported-hls-control' : 'historical-stream-lock-control'
+ }
+ else if (capabilities.AudioContext === 'undefined' && capabilities.webkitAudioContext === 'undefined') {
+ expect(browserName).toBe('webkit')
+ expect(capabilities).toEqual({ VideoDecoder: 'undefined', AudioDecoder: 'undefined', AudioContext: 'undefined', webkitAudioContext: 'undefined' })
+ expect(loaded.error).toEqual({ code: 4, message: 'undefined is not a constructor (evaluating \'new t\')' })
+ expect(loaded.readyState).toBeLessThan(4)
+ outcome = 'unsupported-capability-control'
+ }
+ else {
+ expect(loaded.error).toBeNull()
+ expect(loaded.readyState).toBe(4)
+ if (input === 'trackless') {
+ expect(loaded.dimensions).toEqual([0, 0])
+ expect(await page.evaluate(() => window.mbEvents.filter(item => item.name === 'video:loadedmetadata').length)).toBe(implementation.name === 'published-1.2.0' ? 2 : 1)
+ expect(await page.evaluate(() => window.mbEvents.filter(item => item.name === 'video:canplay').length)).toBe(1)
+ outcome = 'historical-trackless-readiness-control'
+ return
+ }
+ const readiness = await page.evaluate(() => window.mbEvents.map(item => item.name).filter(name => ['video:loadedmetadata', 'video:loadeddata', 'video:canplay', 'video:canplaythrough'].includes(name)))
+ const repeatedData = implementation.name === 'published-1.0.0' && input !== 'audio'
+ expect(readiness).toEqual(['video:loadedmetadata', 'video:loadeddata', ...(repeatedData ? ['video:loadeddata'] : []), 'video:canplay', 'video:canplaythrough'])
+ if (input === 'audio')
+ expect(loaded.dimensions).toEqual([0, 0])
+ else expect(loaded.dimensions[0]).toBeGreaterThan(0)
+ await page.click('#play')
+ await expect.poll(() => page.evaluate(() => window.mbCanvas.currentTime)).toBeGreaterThan(0.15)
+ if (['audio', 'hls'].includes(input)) {
+ expect(await page.evaluate(() => Boolean(window.mbCanvas.engine.audio.audioSink))).toBe(true)
+ expect(await page.evaluate(() => window.mbCanvas.engine.audio.queuedNodes.size)).toBeGreaterThan(0)
+ }
+ await page.evaluate(() => window.mbCanvas.pause())
+ await page.evaluate(async () => {
+ const canvas = window.mbCanvas
+ window.mbSeekEventsStart = window.mbEvents.length
+ window.mbFrameClockSamples = []
+ const video = canvas.engine.video
+ if (video.videoSink) {
+ const times = new WeakMap()
+ const canvases = video.videoSink.canvases.bind(video.videoSink)
+ video.videoSink.canvases = (...args) => {
+ const iterator = canvases(...args)
+ const next = iterator.next.bind(iterator)
+ iterator.next = async (...values) => {
+ const result = await next(...values)
+ if (!result.done && result.value)
+ times.set(result.value.canvas, result.value.timestamp)
+ return result
+ }
+ return iterator
+ }
+ const draw = video.ctx.drawImage.bind(video.ctx)
+ video.ctx.drawImage = (...args) => {
+ const result = draw(...args)
+ if (times.has(args[0]))
+ window.mbFrameClockSamples.push({ frame: times.get(args[0]), audioClock: canvas.engine.audio.currentTime, paused: canvas.paused })
+ return result
+ }
+ }
+ const seek = canvas.engine.seek.bind(canvas.engine)
+ canvas.engine.seek = (time) => {
+ window.mbSeek = seek(time)
+ return window.mbSeek
+ }
+ window.mbSeekTarget = Math.min(0.5, canvas.duration / 2)
+ canvas.currentTime = window.mbSeekTarget
+ await window.mbSeek
+ })
+ expect(await page.evaluate(() => window.mbCanvas.seeking)).toBe(false)
+ expect(await page.evaluate(() => window.mbCanvas.paused)).toBe(true)
+ expect(await page.evaluate(() => window.mbCanvas.currentTime)).toBeGreaterThan(0.2)
+ expect(await page.evaluate(() => window.mbCanvas.currentTime === window.mbSeekTarget)).toBe(true)
+ expect(await page.evaluate(() => window.mbEvents.slice(window.mbSeekEventsStart).map(item => item.name))).toEqual(['video:seeking', 'video:waiting', ...(repeatedData ? ['video:loadeddata'] : []), 'video:seeked'])
+ if (input !== 'audio') {
+ await page.click('#play')
+ await expect.poll(() => page.evaluate(() => window.mbFrameClockSamples.filter(sample => !sample.paused).length)).toBeGreaterThan(2)
+ await page.evaluate(() => window.mbCanvas.pause())
+ }
+ if (input === 'hls') {
+ const tracks = await page.evaluate(async () => {
+ const canvas = window.mbCanvas
+ const initial = await canvas.getM3u8State()
+ const low = initial.levels.find(level => level.height === 90)
+ await canvas.switchM3u8Quality(low.id)
+ const quality = await canvas.getM3u8State()
+ const french = quality.audios.find(track => track.lang === 'fr')
+ await canvas.switchM3u8Audio(french.id)
+ const audio = await canvas.getM3u8State()
+ window.mbTrackTransitions = { initial: initial.currentLevel.height, quality: quality.currentLevel.height, videoMode: quality.videoMode, language: audio.currentAudio.lang, audioMode: audio.audioMode }
+ canvas.src = '/test/pattern.mp4'
+ await window.mbLoad
+ window.mbTrackTransitions.afterSourceSwitch = await canvas.getM3u8State()
+ return window.mbTrackTransitions
+ })
+ expect(tracks).toEqual({ initial: 180, quality: 90, videoMode: 'manual', language: 'fr', audioMode: 'manual', afterSourceSwitch: null })
+ }
+ expect(await page.evaluate(() => window.mbActions)).toEqual([])
+ outcome = 'native-input-playback-and-seek'
+ }
+ }
+ finally {
+ const state = await page.evaluate(async () => {
+ const canvas = window.mbCanvas
+ if (!canvas)
+ return null
+ const hls = canvas.getM3u8State ? await canvas.getM3u8State().catch(error => ({ error: error.message })) : null
+ return { events: window.mbEvents, actions: window.mbActions, dimensions: [canvas.width, canvas.height, canvas.videoWidth, canvas.videoHeight], currentTime: canvas.currentTime, duration: canvas.duration, error: canvas.error, readyState: canvas.readyState, audioState: canvas.engine.audio.audioContext?.state, frameClockSamples: window.mbFrameClockSamples, tracks: window.mbTrackTransitions, hls: hls && { levels: hls.levels?.map(({ id, height }) => ({ id, height })), audios: hls.audios?.map(({ id, lang }) => ({ id, lang })), error: hls.error }, inputBytes: window.mbInputBytes }
+ }).catch(error => ({ error: error.message }))
+ await page.evaluate(() => {
+ window.mbContext = window.mbCanvas?.engine.audio.audioContext
+ window.mbHost?.emit('destroy')
+ })
+ await expect.poll(() => page.evaluate(() => window.mbContext?.state || 'not-created')).toMatch(/^(?:closed|not-created)$/)
+ expect(await page.evaluate(() => window.mbPendingFrames.size)).toBe(0)
+ const cleanup = await page.evaluate(() => ({ audioContext: window.mbContext?.state || 'not-created', pendingFrames: window.mbPendingFrames.size, streamCancelled: window.mbStreamCancelled || false }))
+ await testInfo.attach('mediabunny-native-input', { contentType: 'application/json', body: JSON.stringify({ implementation: implementation.name, sha256: hash(implementation.code), input, capabilities, outcome, state, cleanup, hlsManifest: input === 'hls' ? manifest : null, tracklessFixture: input === 'trackless' ? { parentSha256: hash(pattern), sha256: hash(trackless) } : null, scope: 'Actual published proxy with native browser media and controlled ArtPlayer host using actual core utilities/config; frame timestamps sampled against the SDK audio clock, not acoustic/long-run AV-sync acceptance. Cleanup checks settled playback, not pending-operation races.' }) })
+ }
+ })
+ }
+}
diff --git a/test/helpers/trackless-mp4.js b/test/helpers/trackless-mp4.js
new file mode 100644
index 000000000..0ea02cbc4
--- /dev/null
+++ b/test/helpers/trackless-mp4.js
@@ -0,0 +1,29 @@
+import assert from 'node:assert/strict'
+import { Buffer } from 'node:buffer'
+
+// Derive a trackless container from the small, repository-owned MP4 fixture.
+export function tracklessMp4(bytes) {
+ function boxes(bytes) {
+ const result = []
+ let offset = 0
+ while (offset < bytes.length) {
+ assert(offset + 8 <= bytes.length)
+ const size = bytes.readUInt32BE(offset)
+ assert(size >= 8 && offset + size <= bytes.length, 'Fixture requires bounded 32-bit boxes')
+ result.push({ type: bytes.toString('ascii', offset + 4, offset + 8), bytes: bytes.subarray(offset, offset + size) })
+ offset += size
+ }
+ return result
+ }
+ const top = boxes(bytes)
+ const ftyp = top.find(box => box.type === 'ftyp')
+ const moov = top.find(box => box.type === 'moov')
+ assert(ftyp && moov)
+ const children = boxes(moov.bytes.subarray(8))
+ assert(children.some(box => box.type === 'trak'))
+ const body = Buffer.concat(children.filter(box => box.type !== 'trak').map(box => box.bytes))
+ const header = Buffer.alloc(8)
+ header.writeUInt32BE(body.length + 8)
+ header.write('moov', 4)
+ return Buffer.concat([ftyp.bytes, header, body])
+}
diff --git a/test/mediabunny.test.js b/test/mediabunny.test.js
index 0cdde8907..6c087ecc5 100644
--- a/test/mediabunny.test.js
+++ b/test/mediabunny.test.js
@@ -3,6 +3,32 @@ import assert from 'node:assert/strict'
import test from 'node:test'
import { mbEnvironment, mbHistorical } from './helpers/mediabunny.js'
+function deferred() {
+ let resolve
+ let reject
+ const promise = new Promise((yes, no) => {
+ resolve = yes
+ reject = no
+ })
+ return { promise, resolve, reject }
+}
+
+function timedEnvironment(implementation, option) {
+ const timers = new Map()
+ let sequence = 0
+ const env = mbEnvironment(implementation, {
+ setTimeout(fn, delay) {
+ const id = sequence++
+ timers.set(id, { fn, delay })
+ return id
+ },
+ clearTimeout(id) { timers.delete(id) },
+ })
+ env.eventNames.push('playing')
+ const canvas = env.factory(option)(env.art)
+ return { ...env, canvas, engine: canvas.engine, timers }
+}
+
for (const implementation of await mbHistorical()) {
test(`MediaBunny historical ${implementation.name}: destroy still permits late load errors and scheduled events`, async () => {
const timers = new Map()
@@ -40,4 +66,137 @@ for (const implementation of await mbHistorical()) {
assert.deepEqual({ ...engine.error }, { code: 4, message: 'late controlled rejection' })
assert.equal(engine.networkState, 3)
})
+
+ test(`MediaBunny historical ${implementation.name}: pending play starts video after a newer pause`, async () => {
+ const { engine, emitted } = timedEnvironment(implementation)
+ const audio = deferred()
+ let starts = 0
+ engine.audio.play = () => audio.promise
+ engine.video.start = () => starts++
+ const playing = engine.play()
+ assert.equal(engine.paused, false)
+ engine.pause()
+ audio.resolve()
+ await playing
+ assert.equal(engine.paused, true)
+ assert.equal(starts, 1)
+ assert.deepEqual(emitted.map(item => item.name), ['video:pause', 'video:play', 'video:playing'])
+ })
+
+ test(`MediaBunny historical ${implementation.name}: pending play starts video after destroy`, async () => {
+ const { art, engine, emitted } = timedEnvironment(implementation)
+ const audio = deferred()
+ let starts = 0
+ engine.audio.play = () => audio.promise
+ engine.video.start = () => starts++
+ const playing = engine.play()
+ art.emit('destroy')
+ const cursor = emitted.length
+ audio.resolve()
+ await playing
+ assert.equal(starts, 1)
+ assert.deepEqual(emitted.slice(cursor).map(item => item.name), ['video:play', 'video:playing'])
+ assert.equal(engine.paused, true)
+ })
+
+ test(`MediaBunny historical ${implementation.name}: rejected audio play leaves false paused state and prevents retry`, async () => {
+ const { engine } = timedEnvironment(implementation)
+ const error = new Error('controlled audio resume rejection')
+ let attempts = 0
+ engine.audio.play = () => {
+ attempts++
+ return Promise.reject(error)
+ }
+ await assert.rejects(engine.play(), item => item === error)
+ assert.equal(engine.paused, false)
+ await engine.play()
+ assert.equal(attempts, 1)
+ })
+
+ test(`MediaBunny historical ${implementation.name}: pending seek emits and resumes playback after destroy`, async () => {
+ const { art, engine, canvas } = timedEnvironment(implementation)
+ const audio = deferred()
+ const events = []
+ for (const name of ['seeking', 'waiting', 'pause', 'seeked'])
+ canvas.events.addEventListener(name, () => events.push(name))
+ engine.paused = false
+ engine.audio.seek = () => audio.promise
+ engine.video.seek = () => Promise.resolve()
+ engine.play = () => {
+ events.push('resumed-after-destroy')
+ return Promise.resolve()
+ }
+ const seeking = engine.seek(1)
+ art.emit('destroy')
+ audio.resolve()
+ await seeking
+ assert.deepEqual(events, ['seeking', 'waiting', 'pause', 'seeked', 'resumed-after-destroy'])
+ assert.equal(engine.seeking, false)
+ })
+
+ test(`MediaBunny historical ${implementation.name}: successful load and destroy retain their timeout timer`, async () => {
+ const { art, engine, timers } = timedEnvironment(implementation, { loadTimeout: 1234 })
+ engine.performLoad = () => Promise.resolve()
+ await engine.load('controlled-input')
+ assert.equal(timers.size, 3)
+ assert.equal([...timers.values()].filter(item => item.delay === 1234).length, 1)
+ art.emit('destroy')
+ assert.equal(timers.size, 3)
+ for (const { fn } of timers.values()) fn()
+ timers.clear()
+ await Promise.resolve()
+ assert.equal(engine.error, null, 'Settled Promise.race observes the late timeout rejection without changing the successful result')
+ })
+
+ test(`MediaBunny historical ${implementation.name}: active timeout keeps its error when the underlying load rejects later`, async () => {
+ const { engine, timers } = timedEnvironment(implementation, { loadTimeout: 5678 })
+ const pending = deferred()
+ engine.performLoad = () => pending.promise
+ const loading = engine.load('controlled-input')
+ const timeout = [...timers.values()].find(item => item.delay === 5678)
+ timeout.fn()
+ await loading
+ assert.deepEqual({ ...engine.error }, { code: 4, message: 'Load timeout' })
+ const error = engine.error
+ pending.reject(new Error('late underlying rejection'))
+ await Promise.resolve()
+ await Promise.resolve()
+ assert.equal(engine.error, error)
+ timers.clear()
+ })
+
+ test(`MediaBunny historical ${implementation.name}: Range preflight rejects absent support, tolerates fetch errors and keeps its HLS version boundary`, async () => {
+ const { engine, canvas, globals } = timedEnvironment(implementation, { preflightRange: true })
+ const calls = []
+ const errors = []
+ const warnings = []
+ canvas.events.addEventListener('error', event => errors.push(event.detail.type))
+ globals.console = { ...console, warn: (...args) => warnings.push(args) }
+ globals.fetch = async (url, options) => {
+ calls.push({ url, options: { ...options } })
+ return { headers: { get: () => 'bytes' } }
+ }
+ assert.equal(await engine.video.preflight('https://example.invalid/media.mp4'), true)
+ assert.deepEqual(calls, [{ url: 'https://example.invalid/media.mp4', options: { method: 'HEAD' } }])
+ globals.fetch = async () => ({ headers: { get: () => null } })
+ assert.equal(await engine.video.preflight('https://example.invalid/media.mp4'), false)
+ assert.deepEqual(errors, ['RangeNotSupported'])
+ assert.equal(engine.error, null, 'Range refusal is an event, not engine.error state')
+ const failure = new Error('controlled HEAD rejection')
+ globals.fetch = async () => {
+ throw failure
+ }
+ assert.equal(await engine.video.preflight('https://example.invalid/media.mp4'), true)
+ assert.equal(warnings.length, 1)
+ assert.equal(warnings[0][1], failure)
+ let requests = 0
+ globals.fetch = async () => {
+ requests++
+ return { headers: { get: () => 'bytes' } }
+ }
+ assert.equal(await engine.video.preflight('https://example.invalid/media.m3u8'), true)
+ assert.equal(requests, implementation.name === 'published-1.0.0' ? 1 : 0)
+ assert.equal(await engine.video.preflight(new Blob([])), true)
+ assert.equal(requests, implementation.name === 'published-1.0.0' ? 1 : 0)
+ })
}