diff --git a/.gitattributes b/.gitattributes
index 35b817f6f..229901ecf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,5 +3,8 @@
test/browser/media/hls/*.m3u8 text eol=lf
test/browser/fixtures/hls-grouped.m3u8 text eol=lf
test/browser/media/hls/*.mpegts binary
+# Preserve generated XML whitespace and its frozen playback-input hashes.
+test/browser/media/dash/*.mpd text eol=lf whitespace=-blank-at-eol
+test/browser/media/dash/*.m4s binary
test/browser/media/*.m4a binary
refactor/baselines/core-vendor/*.txt text eol=lf
diff --git a/packages/artplayer-plugin-dash-control/ARCHITECTURE.md b/packages/artplayer-plugin-dash-control/ARCHITECTURE.md
index 190408dac..d2a37291b 100644
--- a/packages/artplayer-plugin-dash-control/ARCHITECTURE.md
+++ b/packages/artplayer-plugin-dash-control/ARCHITECTURE.md
@@ -114,10 +114,17 @@ tarballs offline outside the workspace, repeats a frozen install and checks all
public type modes without resolving any workspace source. It also verifies that
implementation files/config do not leak into the archive. This is type acceptance;
the full installed runtime and SDK release matrix still belongs to PKG-DASH-06/05.
-Browser tests exercise real old/new core DOM, menu clicks, native MP4 and cleanup,
+`dash-control.spec.js` tests exercise real old/new core DOM, menu clicks, native MP4 and cleanup,
with controlled SDK methods. They do not load dash.js or test MPD/ABR decoding.
PKG-DASH-05 must verify pinned dash.js 4.5.2 and 5.2.1 with real adaptive media and
review SDK-driven refresh/source events and the existing demo lifecycle. Physical
devices and installed package acceptance remain separate release gates.
+`dash-sdk.spec.js` now separately loads hash-pinned npm dash.js 4.5.2/5.2.1 and local
+multi-quality/multi-audio DASH segments. It covers decoding, explicit update after
+external selection, source topology replacement, retained callbacks and SDK ownership.
+It also includes a native SDK control without an ArtPlayer instance. Early SDK 4.5.2
+paused-seek stalls remain open; later passes do not resolve them. Unsupported MSE is
+recorded as a playback capability gap, not acceptance. This plugin currently refreshes
+on ready/restart/explicit update, not automatically on external SDK events.
See [refactor validation](../../refactor/dash-validation.md) for baseline failures
and [task plan](../../refactor/plan.md) for remaining type and release work.
diff --git a/refactor/baselines/dash-sdk-checkpoint.json b/refactor/baselines/dash-sdk-checkpoint.json
new file mode 100644
index 000000000..b446980a4
--- /dev/null
+++ b/refactor/baselines/dash-sdk-checkpoint.json
@@ -0,0 +1,1290 @@
+{
+ "schemaVersion": 1,
+ "task": "PKG-DASH-05",
+ "status": "doing",
+ "sourceCommit": "6840544e",
+ "date": "2026-09-12",
+ "command": "yarn test:browser test/browser/dash-sdk.spec.js --trace on",
+ "runs": [
+ {
+ "name": "first",
+ "directory": "refactor/.cache/dash05-first",
+ "stats": {
+ "startTime": "2026-09-11T21:23:28.530Z",
+ "duration": 45380.935999999994,
+ "expected": 10,
+ "skipped": 6,
+ "unexpected": 8,
+ "flaky": 0
+ },
+ "artifact": "source compiled by test helper",
+ "failures": [
+ {
+ "title": "dash.js 4.5.2: actual SDK reports MSE capabilities and version",
+ "engine": "chromium"
+ },
+ {
+ "title": "dash.js 5.2.1: actual SDK reports MSE capabilities and version",
+ "engine": "chromium"
+ },
+ {
+ "title": "candidate core / published DASH / 4.5.2: real MPD decoding and UI selection",
+ "engine": "chromium"
+ },
+ {
+ "title": "dash.js 4.5.2: actual SDK reports MSE capabilities and version",
+ "engine": "firefox"
+ },
+ {
+ "title": "dash.js 5.2.1: actual SDK reports MSE capabilities and version",
+ "engine": "firefox"
+ },
+ {
+ "title": "published core / candidate DASH / 4.5.2: real MPD decoding and UI selection",
+ "engine": "firefox"
+ },
+ {
+ "title": "dash.js 4.5.2: actual SDK reports MSE capabilities and version",
+ "engine": "webkit"
+ },
+ {
+ "title": "dash.js 5.2.1: actual SDK reports MSE capabilities and version",
+ "engine": "webkit"
+ }
+ ],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-first/report.json",
+ "sha256": "14825482d31042170b6d3d63498928b0aa042806d5047a6440c0fa96807ecb10",
+ "bytes": 1820001
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/.last-run.json",
+ "sha256": "e3be5a6e5ea95c5e20e5182ded8da3cc6eb64be8d3217026f4587d66584edffa",
+ "bytes": 439
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "3d80874382d171d7883c9c186067c4c48d4f9599c0db9ffbaa50df38be460050",
+ "bytes": 4274189
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "7b47f08451eecc9e46fcaf7f3eb298219a419b3d0d55ac5813ca5cb654921dfc",
+ "bytes": 3603769
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "27d279446cb193a7f0c456c0ed3b14f88c8e592616ac673996909701a19192d0",
+ "bytes": 265384
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "4702d4d0e49f3285d0d8414c1fbbb346bae1e170c058f497a63becd24b48246f",
+ "bytes": 3557013
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "961d639679f094de06f1db523d5f4295c536b9d0aa256c6a768a5eb238d5bce9",
+ "bytes": 3049811
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "956693fa62e6dbdf750c5195b6e24a19268ec17ef3e1d39f27b81a0bbe705cb5",
+ "bytes": 251383
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/error-context.md",
+ "sha256": "2e1bcc9cf408eb04c899623a78ebb5a0292cd3377d1a3b9d8435d4dcc3759eb2",
+ "bytes": 2810
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/test-failed-1.png",
+ "sha256": "3a1ce97130c1f0da97b4cd79b30d6a097a6913177d90625537e51cfbdc2556e6",
+ "bytes": 80172
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "425eb27be99a269151241bfc34fdc942954b7e8eb0e88e12d9ffd6aadb5b663c",
+ "bytes": 7467055
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "e52ee87fe65ca1de8e2d19790bb3ccb2284cec8245e13e4cd45f4cfa57b75c48",
+ "bytes": 3299530
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "0fe495d04865ab5f4e4a0e0765787f4dd5db10e9738c6abb4784f483ec483b8a",
+ "bytes": 251173
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-chromium/error-context.md",
+ "sha256": "58091d02ee04d0a1c77d21d58edf5da914b48b401a41a858729bc877a8f333f6",
+ "bytes": 10495
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-chromium/test-failed-1.png",
+ "sha256": "00256f25295d2029e1ce91f7cbe19aaba6e03f57e92714a41b1ba029c7e8146f",
+ "bytes": 5153
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-chromium/trace.zip",
+ "sha256": "b123ef1208f1ca7677f3805b794bdef0907024798486832ae380a4c1afe8dd08",
+ "bytes": 258491
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-firefox/error-context.md",
+ "sha256": "799e092c2e04954bbbf24c401fa9fc0e9645f6547fe9ba7cce2f82918ef5b7b1",
+ "bytes": 10499
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-firefox/test-failed-1.png",
+ "sha256": "b0d12c7349c9eb7c7f71119b1460e856453469d31713822ce21df819317dc29a",
+ "bytes": 6363
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-firefox/trace.zip",
+ "sha256": "90e5bf8dc52446a99c401b746b46a922963cd51219ff9681e20f25fb533e505f",
+ "bytes": 275714
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-webkit/error-context.md",
+ "sha256": "58091d02ee04d0a1c77d21d58edf5da914b48b401a41a858729bc877a8f333f6",
+ "bytes": 10495
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-webkit/test-failed-1.png",
+ "sha256": "62aa245946f6c75ea0e8ac25fc86b41e9a925475a10df980e8b9c9cc214767f8",
+ "bytes": 20271
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-webkit/trace.zip",
+ "sha256": "98acf67718dd71d6630233c96f6e2b26ecca6b30e6e7a42bc6d481a8b0d67542",
+ "bytes": 259079
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-chromium/error-context.md",
+ "sha256": "89110ab9c7268af86063105671ff0ead77f2e4804b703ef35a7f1e600071f963",
+ "bytes": 10495
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-chromium/test-failed-1.png",
+ "sha256": "00256f25295d2029e1ce91f7cbe19aaba6e03f57e92714a41b1ba029c7e8146f",
+ "bytes": 5153
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-chromium/trace.zip",
+ "sha256": "82231bdf2dfb60f31a7294454e25f3167e9b8a8d632eeb41cadc2b45dff7cb4b",
+ "bytes": 272726
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-firefox/error-context.md",
+ "sha256": "03981c59814d206ee0282f2467111d43df1d5835c2c395eb8da5a80dec7c045b",
+ "bytes": 10499
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-firefox/test-failed-1.png",
+ "sha256": "b0d12c7349c9eb7c7f71119b1460e856453469d31713822ce21df819317dc29a",
+ "bytes": 6363
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-firefox/trace.zip",
+ "sha256": "493eb973eef4bac84ec0197bb691f79d994849c274f4ac6b984ad039d511a335",
+ "bytes": 289032
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-webkit/error-context.md",
+ "sha256": "89110ab9c7268af86063105671ff0ead77f2e4804b703ef35a7f1e600071f963",
+ "bytes": 10495
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-webkit/test-failed-1.png",
+ "sha256": "62aa245946f6c75ea0e8ac25fc86b41e9a925475a10df980e8b9c9cc214767f8",
+ "bytes": 20271
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-webkit/trace.zip",
+ "sha256": "8c70b87e9a56313480b5cc0127c1005a05a7c3c101c6b1c1dffdac6b7f9eedeb",
+ "bytes": 273312
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "ad07bcdeb3ea4bdfd20602f00f8241f9850c3a004983f4e41879ffdf2fa895e7",
+ "bytes": 4471855
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "3cb300c152510a2eb33640c54a4e9c6391576b3e99f7bccb081c4ccd69fc09a1",
+ "bytes": 3648690
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "27a7688ea17a2ee2f17c2045ca2eb114d5550921b0a1ec3b52cebf529a15aa08",
+ "bytes": 264376
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "5fd783ac6b259e2f469b490716aef6c459c29ef63e142a7a280f757220608d4e",
+ "bytes": 3738469
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-firefox/error-context.md",
+ "sha256": "1e86b378477865e44d1c5486e31b9b3aab2062d7eb16cf3e80356aa272895e96",
+ "bytes": 2827
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-firefox/test-failed-1.png",
+ "sha256": "2aad9514ed44787a18dd5b49f12deede8af39bced0407fdbed50bb85bd584916",
+ "bytes": 114973
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "f3079fa77544b7cf65bbfe94067833d3b564b67d41712e8d111f06b1d0ecb920",
+ "bytes": 4867781
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "f1ec579cbd1911203fa6d242d8daf91f94983196fed4b7c99f1010801894c329",
+ "bytes": 250403
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "7503db8c2e8adfe12cc58344f6746532064a9b7732b3ee351005d4cb731b5e80",
+ "bytes": 3334004
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "4f90bdd4ffc085333da020572607b17d98bf3ed9db2331ac94808433b238e376",
+ "bytes": 3290328
+ },
+ {
+ "file": "refactor/.cache/dash05-first/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "c6d616d8fd0755c58ac8820ec01189dc97919716358f6583914145de388e8f88",
+ "bytes": 250483
+ }
+ ]
+ },
+ {
+ "name": "diagnostic",
+ "directory": "refactor/.cache/dash05-diagnostic",
+ "stats": {
+ "startTime": "2026-09-11T21:29:56.911Z",
+ "duration": 34596.876000000004,
+ "expected": 17,
+ "skipped": 6,
+ "unexpected": 1,
+ "flaky": 0
+ },
+ "artifact": "source compiled by test helper",
+ "failures": [
+ {
+ "title": "candidate core / published DASH / 4.5.2: real MPD decoding and UI selection",
+ "engine": "chromium"
+ }
+ ],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-diagnostic/report.json",
+ "sha256": "5b154584846aad1d08639c36c3fd23dac2f1fdc269b7ff138a74fe78aa6b7dbb",
+ "bytes": 2013068
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/.last-run.json",
+ "sha256": "588ae594105f2a249eccafe9a431e03cde8b797116851e13f027f3e68af66397",
+ "bytes": 96
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "632853e74a44399cf3e95e87a4510d7f21a2e94a3df5981f2c66ff048c25c553",
+ "bytes": 4459126
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "8461fdadc9f7462265c30b8454112d90bf8fa68c4fcdd68a69ab70546bbf4dfc",
+ "bytes": 3599912
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "dbb47181f0580ef45c39204b92866fbefd6b604f6dce0316f83d395d6a9b05c5",
+ "bytes": 265824
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "e6e6649ecd419428b7e844ab15c2e0bf8e4c27dc294713c9fc312a249dfd3e4b",
+ "bytes": 3360686
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "9e83edf3ba1f086448497d38998d0185b37edb72a5089dd5dd9c30e29863ea97",
+ "bytes": 3089092
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "4da3eff913f578d0759435cb310b2b50268cc48a95031335a829f2e219e387ea",
+ "bytes": 251933
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/error-context.md",
+ "sha256": "f16e331a18b1ac6a2f40d0ed971a47a52caa78c82091b46f303efc91f28fb58e",
+ "bytes": 2810
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/test-failed-1.png",
+ "sha256": "56fcdef1deaf5757242c52fa1159456c191c877637be9d3b2b899861a1789c71",
+ "bytes": 80158
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "b0fe6487d8333cd9ead7e7af9b0f839312024b2b5cc0bec9194414b5cdd6ec34",
+ "bytes": 7424512
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "753280b29471e12f7dccefe535438b214468ea728f83cdb659ecf6f1ab161cbf",
+ "bytes": 3118845
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "1e99b3b9ca4984181611e3d23f01580cd0c7b38840ddff12a1af9e2b1b9c8185",
+ "bytes": 251649
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-chromium/trace.zip",
+ "sha256": "af2ddf50d8d42bce01efd980a6af7b6cc4c858a005d1f22289d72ae9da0a7c50",
+ "bytes": 252006
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-firefox/trace.zip",
+ "sha256": "cdd04e39466b50ae5d4dd0850a98e4e6a16620cd68e4b6275b518dc16a6287bf",
+ "bytes": 266516
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-webkit/trace.zip",
+ "sha256": "218ead75bf92fb58cb65770162160f2afa62a2135fda5133caf934699f33ef5f",
+ "bytes": 252026
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-chromium/trace.zip",
+ "sha256": "507e3b0a45c39142090ff3fa6bccf64372ecf1d8ea191f2e32f1e99ce5995750",
+ "bytes": 266331
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-firefox/trace.zip",
+ "sha256": "ac92c6091598594264a485ff9e5ef6539fddd99fe96677fa8c6b4c71acb40fb0",
+ "bytes": 272317
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-webkit/trace.zip",
+ "sha256": "57a28d177fdd396056b0d49029c4e42a23a9f5d6ac87be0dd85211e45ea95f09",
+ "bytes": 265948
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "963fe7a496dee216bc58f76a16fbc8ac89b2a7b393cc4db56ac094bc15d0ab10",
+ "bytes": 4613455
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "4cc57cee9a88d1494bab5a0abb3fd213f96164be9f9036791d7b07f19b25a3d0",
+ "bytes": 3637998
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "daebb2630df464abe70829770fc2cd1b7be0ab3f1b08c8a4ea0adc52cc60172a",
+ "bytes": 264852
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "32165efc6b0d3b4fcbc6604cc743d632a954844e3d9d126a14f9979e84dc17cd",
+ "bytes": 3359710
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "3f819053e220a14493f2853f367260e30becdeec69114f26e086ed1609f43e10",
+ "bytes": 3295708
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "db1d3a59aece61c400a1a01294f4901e3b7116843d91ef3d6133bf08b799c39a",
+ "bytes": 250871
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "1bda090527753ddb3561a2abe15eeb48b0b95d173439e32ca88feeb21cc0e895",
+ "bytes": 3335475
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "ea296b37f61905d2eddd224bafee79032152deeafdf81609c000caabe74ea481",
+ "bytes": 3297461
+ },
+ {
+ "file": "refactor/.cache/dash05-diagnostic/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "9db35ccaf6f529166d9c4a89e282618fd96116f2666a0365f45399a68a36ef9f",
+ "bytes": 250609
+ }
+ ]
+ },
+ {
+ "name": "native",
+ "directory": "refactor/.cache/dash05-native",
+ "stats": {
+ "startTime": "2026-09-11T21:32:32.321Z",
+ "duration": 13006.276,
+ "expected": 4,
+ "skipped": 2,
+ "unexpected": 0,
+ "flaky": 0
+ },
+ "artifact": "source compiled by test helper",
+ "failures": [],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-native/report.json",
+ "sha256": "30761df24410e15b39e333943157171029156c364ad2d6775e670b8f2b305e8f",
+ "bytes": 152940
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/.last-run.json",
+ "sha256": "91d1c43004802cd49950d78eb11c8fa7d05da8ffffe219a8b13b2f561bc00903",
+ "bytes": 45
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-chromium/trace.zip",
+ "sha256": "8e5633f4ed1615aa8aa2db3a385df66b9b68a9e6586bf82dd329a6af605dd395",
+ "bytes": 1229955
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-firefox/trace.zip",
+ "sha256": "75a25bcdcd5fd8333c4570783ef07a4498b7ad7bb2cf3dd05696e12228bcbf7e",
+ "bytes": 1945063
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-webkit/trace.zip",
+ "sha256": "db5e42b57d48842f0ff1b6df0c9fd6134c1c842d36e891432d2a18df31d923b6",
+ "bytes": 252432
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-chromium/trace.zip",
+ "sha256": "f09005a9dc967d47353a8466ff679d10e74f70e35b4ef21b4430ac59651c5b24",
+ "bytes": 1323632
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-firefox/trace.zip",
+ "sha256": "9c12ab16b7d62ed34fa4de8a0d3430b8fcc7401bf310d8bbdaa48dcdfdc1a58b",
+ "bytes": 1471861
+ },
+ {
+ "file": "refactor/.cache/dash05-native/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-webkit/trace.zip",
+ "sha256": "39b6d2c618295bbad1ce2d42bd19f3afe7ea634030418f00c600f945449f3cc1",
+ "bytes": 266587
+ }
+ ]
+ },
+ {
+ "name": "native-boundary",
+ "directory": "refactor/.cache/dash05-native-boundary",
+ "stats": {
+ "startTime": "2026-09-11T21:34:04.737Z",
+ "duration": 16164.991000000002,
+ "expected": 4,
+ "skipped": 2,
+ "unexpected": 0,
+ "flaky": 0
+ },
+ "artifact": "source compiled by test helper",
+ "failures": [],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-native-boundary/report.json",
+ "sha256": "d937ff58b936f887d41df84cf9dc3fe777b7f9598cdf25ab3fc9230de90d387f",
+ "bytes": 150509
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/.last-run.json",
+ "sha256": "91d1c43004802cd49950d78eb11c8fa7d05da8ffffe219a8b13b2f561bc00903",
+ "bytes": 45
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-chromium/trace.zip",
+ "sha256": "33790a5dc264f308bbeaff379504c74b70de9151d017ed24d307bad3d9d39e05",
+ "bytes": 1577818
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-firefox/trace.zip",
+ "sha256": "27fa4bd6e2cc5cfc3737d3e0907127ee9bf0cca2660618b13fd1967e8e6b74b7",
+ "bytes": 1772434
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-webkit/trace.zip",
+ "sha256": "2997e6ebecb6eef446412e2067cdd07d4509d9d35c31bf7d9179ba98d38219d4",
+ "bytes": 252507
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-chromium/trace.zip",
+ "sha256": "c48ccdf60a7c3a2b4923f0a5ed6c2778cca5712e785a8904c3b0613c8a96d06e",
+ "bytes": 1672045
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-firefox/trace.zip",
+ "sha256": "bda6ece786ea2efd7a078df2f61634f53278eff8dd332f570b111842703ff4f5",
+ "bytes": 2047773
+ },
+ {
+ "file": "refactor/.cache/dash05-native-boundary/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-webkit/trace.zip",
+ "sha256": "1d8e3d778d705c8710155e965aa77b77017494f9e9d20fb0696d9d19604a0ca1",
+ "bytes": 266679
+ }
+ ]
+ },
+ {
+ "name": "combinations-first",
+ "directory": "refactor/.cache/dash05-combinations-first",
+ "stats": {
+ "startTime": "2026-09-11T21:36:12.855Z",
+ "duration": 29231.065,
+ "expected": 8,
+ "skipped": 8,
+ "unexpected": 8,
+ "flaky": 0
+ },
+ "artifact": "source compiled by test helper",
+ "failures": [
+ {
+ "title": "published core / DASH 4.5.2: actual source topology replacement and owned cleanup",
+ "engine": "chromium"
+ },
+ {
+ "title": "published core / DASH 5.2.1: actual source topology replacement and owned cleanup",
+ "engine": "chromium"
+ },
+ {
+ "title": "candidate core / DASH 4.5.2: actual source topology replacement and owned cleanup",
+ "engine": "chromium"
+ },
+ {
+ "title": "candidate core / DASH 5.2.1: actual source topology replacement and owned cleanup",
+ "engine": "chromium"
+ },
+ {
+ "title": "published core / DASH 4.5.2: actual source topology replacement and owned cleanup",
+ "engine": "firefox"
+ },
+ {
+ "title": "published core / DASH 5.2.1: actual source topology replacement and owned cleanup",
+ "engine": "firefox"
+ },
+ {
+ "title": "candidate core / DASH 4.5.2: actual source topology replacement and owned cleanup",
+ "engine": "firefox"
+ },
+ {
+ "title": "candidate core / DASH 5.2.1: actual source topology replacement and owned cleanup",
+ "engine": "firefox"
+ }
+ ],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-combinations-first/report.json",
+ "sha256": "75b79806f76f5a61be322e9cda122b33c77da9f6f2595ae69ee27ffd1fc7206d",
+ "bytes": 602807
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/.last-run.json",
+ "sha256": "fab406cd872706fe0cb34976ac52bbbe762421d8598194c303782eded3939ee9",
+ "bytes": 439
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-7b5c3-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "209de50f298e12ab28ab609ce5a81f965d3aded957fc627aa9bfbeed625c8b55",
+ "bytes": 2091973
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-7b5c3-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "0ebc03f939aeebbfa412083ab545475514d6b0effa4c73f41c2ecc101b0e7e52",
+ "bytes": 1746480
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-7b5c3-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "8926fefcc48cc147f4dd257543b6b9f625c7ef5493d879d2a2094317c3f1a432",
+ "bytes": 252707
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-chromium/error-context.md",
+ "sha256": "c461ca8f6f9155188473ab87aadb42b65e8394bb21cdb92b3e21ee01b999fc3c",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-chromium/test-failed-1.png",
+ "sha256": "269135a5fdfc69303629395e0a9a9adaa52006b9d962696db3e85e483aedb067",
+ "bytes": 132212
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "8ebd15995932922de5a96200bb4d47b0271bbc2696bdf17a5c65d488e74dfabc",
+ "bytes": 1664672
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-firefox/error-context.md",
+ "sha256": "c461ca8f6f9155188473ab87aadb42b65e8394bb21cdb92b3e21ee01b999fc3c",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-firefox/test-failed-1.png",
+ "sha256": "b04380b9cf7203192bddc4af3c959f1ccfd5c23ca188da7c967fc57d17966733",
+ "bytes": 180214
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "8d2c803f3054461db17ea0c2581ce3679fb5e974456fe3335ef8bba582a7b834",
+ "bytes": 1416086
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "477da1b094873017bace0227d0f8b7e9e9049a35813b4d2556705b1e890d753d",
+ "bytes": 266935
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-chromium/error-context.md",
+ "sha256": "f5fa461af46f5dba910922726f91046d70321eccee8cfea6dab5c6db8ee72aa5",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-chromium/test-failed-1.png",
+ "sha256": "69eb02f2a784199abd0108e978e43e76c4f1d19eb224a33ec93bef3317488ef3",
+ "bytes": 128345
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "dae9c84acd6ebbdfe467163e0c961d7029f75eae7cadb6854d1cd636b1e19213",
+ "bytes": 1469675
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-firefox/error-context.md",
+ "sha256": "f5fa461af46f5dba910922726f91046d70321eccee8cfea6dab5c6db8ee72aa5",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-firefox/test-failed-1.png",
+ "sha256": "d35f2e841c231148ce98f0fff85a5c06191813d1611a73cf64aeaeae6e7e9430",
+ "bytes": 180219
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "779bef58fb09b9b32bd7ff09540fb5961c9af6516e1acacfa095ed0c3b0a4cb8",
+ "bytes": 1098052
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "ebcf468dadf1a7c316e525c3a07179ac0e6e2316993726345d8158fb2cda16b1",
+ "bytes": 252721
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-f02ba-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "b99db62657c418664186bef8f17388a420c73aa8eabe3b5a0d3debeb6ba21971",
+ "bytes": 2969937
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-f02ba-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "60edd68926417fa40265959d2eccf4c75700433fdb7b835a2a158490ba2c651e",
+ "bytes": 2539426
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-candidate-core-DA-f02ba-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "6ad0ff0f65d74c2166d55e6ac9a2654eb6feb3b9aaafa87748ab939332af6d9c",
+ "bytes": 267257
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-chromium/error-context.md",
+ "sha256": "422cf8400a5ed967660d78c2007cea63b54b8c50d47e16df9786690065fc1a83",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-chromium/test-failed-1.png",
+ "sha256": "66e9ddf138980e158dd4bc6a6d74be2974dd9497e2d0fa23b923d60970a5a4a2",
+ "bytes": 128609
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "4c9602e9da9c595f6bca22d3a41ef376ee9c1ce4656993b6668e1c10a78c459a",
+ "bytes": 1776838
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-firefox/error-context.md",
+ "sha256": "422cf8400a5ed967660d78c2007cea63b54b8c50d47e16df9786690065fc1a83",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-firefox/test-failed-1.png",
+ "sha256": "b04380b9cf7203192bddc4af3c959f1ccfd5c23ca188da7c967fc57d17966733",
+ "bytes": 180214
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "5cc3004da43a676134d5f6710d7a526dd565f06560cd268345c21959c9513526",
+ "bytes": 1459150
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "da0f862cdfb5a2bf959a83c44e94a2f00ec870d886ec3fffd8e922c105a9ee4b",
+ "bytes": 266268
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-chromium/error-context.md",
+ "sha256": "7060f091999a736d1db860496b53718d9a826d3fe701a6208157ce00358b4595",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-chromium/test-failed-1.png",
+ "sha256": "66e9ddf138980e158dd4bc6a6d74be2974dd9497e2d0fa23b923d60970a5a4a2",
+ "bytes": 128609
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "28120ffc98953362c5f0d1be8ac78440dad8c643d9d1af0a9d91c0e7c1215d90",
+ "bytes": 1384711
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-firefox/error-context.md",
+ "sha256": "7060f091999a736d1db860496b53718d9a826d3fe701a6208157ce00358b4595",
+ "bytes": 9271
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-firefox/test-failed-1.png",
+ "sha256": "b04380b9cf7203192bddc4af3c959f1ccfd5c23ca188da7c967fc57d17966733",
+ "bytes": 180214
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "a39a45aeb8929966066a8e2c9ffcfa0b760dca77f3e017825cc7755af09bec92",
+ "bytes": 1275213
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "0e9180912b8d22421b795f4247cebd4eb734db435dd20cd323357965d677a708",
+ "bytes": 251731
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-b68b8-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "b152d9af3e5a034fb92db0b709b14d97aa972c71989890b5ea50441d79163076",
+ "bytes": 2943993
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-b68b8-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "5425ddec8b211d7761236687e1b4935e383af146996816b8f0279d2c925efab9",
+ "bytes": 2586113
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-b68b8-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "a1a5b9a13bdaa56b62121771ff1c06ec1d9a7dc6c68abaae0cd98989ada6300a",
+ "bytes": 265946
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-c4cfe-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "85c50fbd1c85acc2ae75d06f4368fb27befd3ce0d75fc7c948761cb59b08b342",
+ "bytes": 1862969
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-c4cfe-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "d3201b5a9aa3a812d4f51110e5b6f20fff9cf153131572a0216e6452e1b1732f",
+ "bytes": 1733648
+ },
+ {
+ "file": "refactor/.cache/dash05-combinations-first/results/dash-sdk-published-core-DA-c4cfe-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "a2b98b8fe3af110a8fea5eb806dd3f33667861f7b320b38cbc56446bc3e17db0",
+ "bytes": 252040
+ }
+ ]
+ },
+ {
+ "name": "source",
+ "directory": "refactor/.cache/dash05-source",
+ "stats": {
+ "startTime": "2026-09-11T21:37:23.356Z",
+ "duration": 14899.326,
+ "expected": 8,
+ "skipped": 4,
+ "unexpected": 0,
+ "flaky": 0
+ },
+ "artifact": "source compiled by test helper",
+ "failures": [],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-source/report.json",
+ "sha256": "35794007d774cb769066873447b24499a7a3129b833fad19f0aaf1c20f891d25",
+ "bytes": 342241
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/.last-run.json",
+ "sha256": "91d1c43004802cd49950d78eb11c8fa7d05da8ffffe219a8b13b2f561bc00903",
+ "bytes": 45
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "ff9dc89e4b19d8678955f0bd7c7f8cece6bc34f9797ceb0b47956a951a259007",
+ "bytes": 1543659
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "1b77aed1e08b2ea2d41b40ad8fcd16383ddfd37bd8649f851b6e4c8fc183ac4a",
+ "bytes": 1081773
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "43968813429d40608fd103807099f3133e989a3ebf5dcdd68d39a41e11d0254d",
+ "bytes": 267012
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "ab785cc539528980b0c73ca100221643aff8596b66635b436f75c93f502ae525",
+ "bytes": 1653472
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "4984acec2c0f1e7bcc7a9d6093c10855b8c1782505b5d30a9f1aad3f201e84d4",
+ "bytes": 1307142
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "bad9af83419b42d7e19dc0ed5b0991604a5106d65e81c2e631b37503cf04c019",
+ "bytes": 253136
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "9aa7afddced44ce51341357f49bd6f88773e351a1b4203ea669d915a566eb1fb",
+ "bytes": 1437329
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "427ca93ad73cc618e46b64aa9449c4004ccffb5f0e07654801f7c4efc6f5a23d",
+ "bytes": 1067311
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "a9949ca2a39441b18d5525d4c50055cdf25b904e57f05025be3f00873e8714c8",
+ "bytes": 266017
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "b6ab833695167bc4c358f243b38dd18fedb4bcb4e24a51c8c5da1bf36afeceb2",
+ "bytes": 1729596
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "1431132c7bf22af8183764dbdb0d60a6c46a6e58dfa0ba58ce6006dd98204a5d",
+ "bytes": 1305175
+ },
+ {
+ "file": "refactor/.cache/dash05-source/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "8c37f007c66f4b4bc19ec2fc1a891ca90fc760dd95681723ad4c6aeb20e9209c",
+ "bytes": 252156
+ }
+ ]
+ },
+ {
+ "name": "main",
+ "directory": "refactor/.cache/dash05-main",
+ "stats": {
+ "startTime": "2026-09-11T21:38:34.620Z",
+ "duration": 61712.778,
+ "expected": 36,
+ "skipped": 16,
+ "unexpected": 2,
+ "flaky": 0
+ },
+ "artifact": "packages/artplayer-plugin-dash-control/dist/artplayer-plugin-dash-control.js",
+ "failures": [
+ {
+ "title": "published core / published DASH / 4.5.2: real MPD decoding and UI selection",
+ "engine": "chromium"
+ },
+ {
+ "title": "candidate core / published DASH / 4.5.2: real MPD decoding and UI selection",
+ "engine": "chromium"
+ }
+ ],
+ "evidence": [
+ {
+ "file": "refactor/.cache/dash05-main/playing.png",
+ "sha256": "fc11f6238ac5e92b9238f2c59865cd973bfb55b3e3f884e3f926f30f566dea76",
+ "bytes": 80174
+ },
+ {
+ "file": "refactor/.cache/dash05-main/report.json",
+ "sha256": "2f18b940ffa8ee0a296cba98228382c22986bfa9cd49b02f8f6d28b44f89252b",
+ "bytes": 2682585
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/.last-run.json",
+ "sha256": "ed5339338a98f1795ffeec9a7fddb0d074bd7bc42eaf852630c3f68dd63bf4c9",
+ "bytes": 145
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "26eefc4b2c2c3312a9c8a9923b4e0e74268c7fd06ed493f770b150150490e245",
+ "bytes": 4485396
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "510c3428a7268e33a4c6ca9bd0459d9267751ad41d191b442527a0d6110311d2",
+ "bytes": 3619683
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-ca-1ab78-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "011a372f1e65685d5ec67e03a8f5ff5f47a626408fc4af7d99e4cfac569611ba",
+ "bytes": 266995
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "26fbd4de42667f3cf0a0148923f3c49c0694c34bfecd0bf32156537b4806d9eb",
+ "bytes": 3300891
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "0093da272aaa8911df531935a5b6bc1d264c343528736fec81029bbce3cf9341",
+ "bytes": 3330853
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-ca-69287-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "e069cea10f27310054d90fcf2c1657dc70dd566f54f3536bf1e29526e6cba5e9",
+ "bytes": 252992
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-7b5c3-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "c8f569d39304197ef765c86fb03f311ccf0e26c7efbede9cdd977929207eb249",
+ "bytes": 1902903
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-7b5c3-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "0524dc3b5db02037d9fc994e3b2a8ed36429cc47747f7d7cc6bd45b4946972bf",
+ "bytes": 1909542
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-7b5c3-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "99a0bbc8ccca344f42681ab5a01d78b6bef85f465d3a095308e1eeb5a32fa8cb",
+ "bytes": 252792
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "a1c5e87a2d46ea832c1a338cb988bb66d758184d7661a6ad03b16d9d4d34c651",
+ "bytes": 1372332
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "c00c30402010406c540f98d359553980023ac8236aeeaa54d859babeb4f2eacc",
+ "bytes": 1044781
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-8cadd-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "5a3baa549e9c89c59769241e48a9090f574cb54e316eee28db503efea11c34f5",
+ "bytes": 267049
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "6d00dff0b0e76bd301a682c592490844a082aa9986c7f4db5f32e86ef1f516a4",
+ "bytes": 1358972
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "ade8a92a2106cdc1bc79b621dda24fc950d4d195750925a355778995d24ea2a3",
+ "bytes": 1019160
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-e80c4-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "de65bb017fa38dec69e3a795e482b6c23043e5dc0bbc94a12f41676a3b3b3b74",
+ "bytes": 252817
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-f02ba-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "6abc9321763cb750e321d07c2a26a108fa313f22f2c29854f179eaea1885ef99",
+ "bytes": 3261114
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-f02ba-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "bf41202adba189dc784b0686a2523c9b2dc6d7091ae2383c919cdc2d1e3173ea",
+ "bytes": 2644624
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-DA-f02ba-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "2a32602adee253e0b371bf12c3d9d3cbaa46de797ccca455d1e2ebe68aa8c555",
+ "bytes": 267022
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/error-context.md",
+ "sha256": "7a2854771fb7571593f9c0e554905acfe524b84a78b1fdb2f09e552ff2fccb14",
+ "bytes": 2810
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/test-failed-1.png",
+ "sha256": "5b0e203837ed48a3860b1044029d8ba735cd246f024ab18adf21abf0abb3e987",
+ "bytes": 80105
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "9e893aae1ba04409d6735aa8759a8af82c25b88f6c17c0abb0778a250ea4e1c7",
+ "bytes": 7438449
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "8369f69b74e7c35e2f66c061a28585078aa600866249d534278c3930809a95c6",
+ "bytes": 3297224
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-candidate-core-pu-83e89-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "b361d3ce314e912e12461f63b76b6498bb38b736f978ab230413ffb6391ef0d2",
+ "bytes": 252803
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-chromium/trace.zip",
+ "sha256": "2b44b642e155d49c2ae17e04e5cd6ba3c8be90ad5f9804184fcd7893a6f073ac",
+ "bytes": 253119
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-firefox/trace.zip",
+ "sha256": "e6f2991a376bb8a3c209adfc8c3b7c5711152ab341726e69699cac75387ebe82",
+ "bytes": 266958
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-4-5-2-act-c6992-SE-capabilities-and-version-webkit/trace.zip",
+ "sha256": "9a3077a384ed1f59cc2a40237ff1327af532e370f64288d4b1c373915bea4dd7",
+ "bytes": 253232
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-chromium/trace.zip",
+ "sha256": "252a05c03cc7359cd5de3c96496e53425a61fd0f491fbe0b6864c2239bb29fb5",
+ "bytes": 1565252
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-firefox/trace.zip",
+ "sha256": "54b2d3c1f56b3840e5fcd990ce4b8fc44c1c5b252caa06e43a8592e441d18519",
+ "bytes": 1724882
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-4-5-2-nat-cf307-used-seek-without-ArtPlayer-webkit/trace.zip",
+ "sha256": "ce9e3a84bc37a6af05f183df8723b628b4c3399bd34145661677d6d62d68c674",
+ "bytes": 252728
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-chromium/trace.zip",
+ "sha256": "6ee002e3a4c1fe5d9ab30e0ac1f434cf5e34ef14689e9fcb004f0fbb651afe44",
+ "bytes": 266996
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-firefox/trace.zip",
+ "sha256": "150a6f7d0879eac8a5047a9646eb06238dec43cca1691af92eb052c1d96695c0",
+ "bytes": 276403
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-5-2-1-act-883cc-SE-capabilities-and-version-webkit/trace.zip",
+ "sha256": "e4789c9fc2e37c718d541b2b38df0b2f170a73bb929c8dddccbfdfcd5145d664",
+ "bytes": 267111
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-chromium/trace.zip",
+ "sha256": "2beefa71661c4e74284c2cece3bb5784fe720ff382b15b2c4115e57fa598f6b4",
+ "bytes": 1574506
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-firefox/trace.zip",
+ "sha256": "55d2c92d8916b73f8216566a33f3f078908a93f00cf98050bab77ed9fe794313",
+ "bytes": 2011707
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-dash-js-5-2-1-nat-95d9f-used-seek-without-ArtPlayer-webkit/trace.zip",
+ "sha256": "4e9283944e4da79bad78230361e6eb55e051e0ee4bd64e93d0976dff42f88e13",
+ "bytes": 267006
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "0b37cf5644cc36750ef9bb6baeee7a94bd76c183af3a75933dbc40927295074e",
+ "bytes": 4472437
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "d5661e32c865ac82bc682ddbea757c4bb2ad10dbce48233aae64bddec6051486",
+ "bytes": 3580624
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-ca-3f438-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "06daa9a4c1407007d43792a9c0f5b4caa0c0027ac35a67958ded2ac1a6e43cf9",
+ "bytes": 266013
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "79a1bcc6ef21038bb1b1c4a1c9618b6f0bf1114ea8e2b54220ba13659feeb333",
+ "bytes": 3355737
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "75195c41be7fefc561e5fdf64dd6bbc633fc80c1cc27c4f07f7cd70ccd643493",
+ "bytes": 3321783
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-ca-870f4-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "70b7854e4bf5265a0802c3e47394f9630b935d6531b47da1f9fa549f9b8c6e3e",
+ "bytes": 251773
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "0468e7529a7077c17cb9ede7c2599934fe3a0f73a8c2c309339b2616ded58619",
+ "bytes": 1413885
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "16033b302ff389160b227246e8d04f8f37f7b025218a148d017ecd1b03b14e3d",
+ "bytes": 1086946
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-8dce6-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "0f9d74d664bfd85833cdf6cfe0007ce6f578b1ae508c807cf86762883a5d2f7d",
+ "bytes": 266028
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-chromium/trace.zip",
+ "sha256": "b796e303bf665947b05b4f0f7ec0ecc597f5b24de5bc12b2328fe938eb4c2275",
+ "bytes": 1439379
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-firefox/trace.zip",
+ "sha256": "533b6477abfb6ef77f05f49a166431156924ee7bce3f0307da8ef7d49d9729ab",
+ "bytes": 1065514
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-8fe62-placement-and-owned-cleanup-webkit/trace.zip",
+ "sha256": "2e55b9e007f799eb2cca50249c2b3183b2e6670ffaf7b62b64788403761b22ae",
+ "bytes": 251797
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-b68b8-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "0faa73792612f7ef37a240d6d50515765d9718a6f1baa863cdb720b56aa962a1",
+ "bytes": 2945252
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-b68b8-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "46ecbb18d6cfe1cdd10c95ac8aad17cd5fff3514a88b793c701ada1085707fc8",
+ "bytes": 3098106
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-b68b8-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "e9409eb5d8d744c6553f73d40a507bf500d58499812e83c501ce4da69319afaf",
+ "bytes": 266251
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-c4cfe-ects-external-SDK-selection-chromium/trace.zip",
+ "sha256": "9b5a54a778645ad3b3e1f9983e5f91cf7092037742be2a3752695a48c9d36086",
+ "bytes": 1819285
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-c4cfe-ects-external-SDK-selection-firefox/trace.zip",
+ "sha256": "cca0a2686f0aac00e70ace9b4a6148c25f701d5d3d8b17967328b7603fe243e3",
+ "bytes": 1888534
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-DA-c4cfe-ects-external-SDK-selection-webkit/trace.zip",
+ "sha256": "2fa1173b45778de979ef20b1036d7a81788acc3012f11b7ff2a1c5def5c3a4b5",
+ "bytes": 251788
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-chromium/error-context.md",
+ "sha256": "4d1aed77f8bede30d1a99e279884c170c32fca1ef8d0da60a8d360db6825d2e7",
+ "bytes": 2810
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-chromium/test-failed-1.png",
+ "sha256": "1de9df3492034276035b6b78bf78915ef3959c9bd173a692606b975a2dca589b",
+ "bytes": 80235
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-chromium/trace.zip",
+ "sha256": "92a2258177a1a2a3fbceeec035352771de340e487f9b8898bb05439c929ac99f",
+ "bytes": 7685020
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-firefox/trace.zip",
+ "sha256": "a7d6293f9437c42683e6f3f991b55d7495e820d24c7daa91ea33ffcfb1aa8d71",
+ "bytes": 3304657
+ },
+ {
+ "file": "refactor/.cache/dash05-main/results/dash-sdk-published-core-pu-c466c-D-decoding-and-UI-selection-webkit/trace.zip",
+ "sha256": "aff116e32737b78f7a6e04c5b41b9780cf9ba82c381d313e14ddaa26d64a77ad",
+ "bytes": 251780
+ }
+ ]
+ }
+ ],
+ "inputs": [
+ {
+ "file": ".gitattributes",
+ "algorithm": "sha256-lf",
+ "sha256": "f75e6a6d6bf3b500d3665a9957fbe62412750f9e96c3bc7689b9de2d79d14aee"
+ },
+ {
+ "file": "test/browser/dash-sdk.spec.js",
+ "algorithm": "sha256-lf",
+ "sha256": "eeb0750d490bf41c931291d3889477d09aa687856660c1efa76373e332ba10aa"
+ },
+ {
+ "file": "scripts/generate-dash-fixture.mjs",
+ "algorithm": "sha256-lf",
+ "sha256": "2ebd7d4c44dee528778e0d95452d408804becd4e5092a23fac8ce63d0c1452ce"
+ },
+ {
+ "file": "refactor/scripts/dash-sdk.test.mjs",
+ "algorithm": "sha256-lf",
+ "sha256": "2fdb9e7c4a8dbc4f2119629631b9b2ee7f73ddf26dbe70879229a9dd441a308a"
+ },
+ {
+ "file": "refactor/baselines/dash-sdk.json",
+ "algorithm": "sha256-lf",
+ "sha256": "215f63e5b4fd0d4eee74517e155211676309dd92c0f6dda34a6351ca10d7bb99"
+ },
+ {
+ "file": "test/browser/media/dash/manifest.json",
+ "algorithm": "sha256-lf",
+ "sha256": "72438762905eadca3c08e7e152c7895483743cb6264eba158fd7547d00dfa9b1"
+ },
+ {
+ "file": "packages/artplayer-plugin-dash-control/dist/artplayer-plugin-dash-control.js",
+ "algorithm": "sha256-lf",
+ "sha256": "9ae800d1e8b3179d5c89baa567b5990cc1e9abd1b9d1cc6ee5c67a8e74e764fd"
+ }
+ ],
+ "baselineTests": {
+ "passed": 2,
+ "command": "node --test refactor/scripts/dash-sdk.test.mjs"
+ },
+ "ci": {
+ "command": "yarn ci:check",
+ "exitCode": 0,
+ "tests": 717,
+ "unit": 661,
+ "engineering": 14,
+ "baseline": 42,
+ "strictProductionTS": 261,
+ "log": "refactor/.cache/dash05-ci-check.log",
+ "sha256": "1c66b9b3ad5730f03cd2bc60133c79e825ab303bc74a4084c537d0e3a2543e66",
+ "note": "Node/engineering/type gates only; does not turn failed browser SDK tests into passing acceptance."
+ },
+ "generatorReproduction": {
+ "directory": "refactor/.cache/dash05-generated-check",
+ "resources": 31,
+ "changedBytes": 0,
+ "sameCommand": true,
+ "note": "Same local FFmpeg build and host, not a cross-platform bitwise reproduction claim."
+ },
+ "visualReview": {
+ "file": "refactor/.cache/dash05-main/playing.png",
+ "sha256": "fc11f6238ac5e92b9238f2c59865cd973bfb55b3e3f884e3f926f30f566dea76",
+ "observation": "Candidate core/candidate main SDK 5.2.1 Chromium: visible decoded test pattern at 6s, Auto/fr selectors, no overlapping control text."
+ },
+ "limitations": [
+ "DASH-SEEK-01 remains open: paused seek to 6s stalls at buffered end 5.999999; no next video request. Teardown AbortError is subsequent, not proven cause.",
+ "Native control passes with matched approximate buffered endpoint do not resolve integrated failures or prove an ArtPlayer cause.",
+ "Windows WebKit reports no MSE; dynamic skips are capability gaps, not playback acceptance.",
+ "External SDK changes are tested with explicit synchronous plugin.update; automatic SDK event refresh has not been implemented or accepted.",
+ "Actual SDK declaration consumers, legacy SDK matrix, devices, 8082 demo and complete installed distribution remain outstanding.",
+ "Reports and all traces remain local cache; hashes are committed but cache files are not uploaded."
+ ]
+}
diff --git a/refactor/baselines/dash-sdk.json b/refactor/baselines/dash-sdk.json
new file mode 100644
index 000000000..45d5d8cb0
--- /dev/null
+++ b/refactor/baselines/dash-sdk.json
@@ -0,0 +1,41 @@
+{
+ "schemaVersion": 1,
+ "task": "PKG-DASH-05",
+ "sdks": [
+ {
+ "metadataUrl": "https://registry.npmjs.org/dashjs/4.5.2",
+ "codeMember": "package/dist/dash.all.min.js",
+ "release": {
+ "name": "dashjs",
+ "version": "4.5.2",
+ "tarball": "https://registry.npmjs.org/dashjs/-/dashjs-4.5.2.tgz",
+ "integrity": "sha512-WXPk0lPDSaHjiSVoVRh2jQPiMmB1alKUH8hV2CVmaI0vPUeT1wIY7madVE38SthfOmwS9IJViv1RrxrxdGjElg==",
+ "sha256": "9a0944c48deb0fd8f92b0eea436c5b0d0aea9237c7da0078c0310f1430d0a31f",
+ "files": {
+ "package/package.json": "62b2295c4a92ec996ff066f7e5739893c46fce44d80c940c61ced9d5710226d1",
+ "package/LICENSE.md": "f7cc4ba24850cc564766c75923d07c3d22fa27f304285f4d25ecffeaec964e28",
+ "package/index.d.ts": "13e6bd0a3c77e2db9378e355915929ed3dda5d8de9c48f446c9d3e9fb7154dbd",
+ "package/dist/dash.all.min.js": "17849c05872997095a63d74bde3fed6f79c14c6a48cdf904833d880b93a476da"
+ }
+ }
+ },
+ {
+ "metadataUrl": "https://registry.npmjs.org/dashjs/5.2.1",
+ "codeMember": "package/dist/modern/umd/dash.all.min.js",
+ "release": {
+ "name": "dashjs",
+ "version": "5.2.1",
+ "tarball": "https://registry.npmjs.org/dashjs/-/dashjs-5.2.1.tgz",
+ "integrity": "sha512-axcJmLeJCTJMLUfQRErUJB1KOiU5iHF+DMLBc3FKeox1HPYtGUQlC6Xm5Mm6vhBUR3CHHLIPOqw0JDIqMtP+Dw==",
+ "sha256": "4eacb0cc3525276666ca3f084611cdabb5a2264d128dfe0750fe106fbddd088f",
+ "files": {
+ "package/package.json": "f89fa389855d2a21b380fa69c84735da25bd93e3b9d7c39bd0d634493425fd8c",
+ "package/LICENSE.md": "f7cc4ba24850cc564766c75923d07c3d22fa27f304285f4d25ecffeaec964e28",
+ "package/index.d.ts": "03b420509a480f893bf8253232cfd28428dc0be5f254fefe99a91e65847c010e",
+ "package/dist/modern/umd/dash.all.min.js": "3a22b1f4576ab294f41e56f156cec7972a5f83edda379416778293ff22d2eb49"
+ }
+ }
+ }
+ ],
+ "note": "Pinned SDK archives are test-only. Selected member hashes and whole-archive integrity; no production dependency or blanket SDK-version support claim."
+}
diff --git a/refactor/changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md b/refactor/changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md
new file mode 100644
index 000000000..db3a4dd47
--- /dev/null
+++ b/refactor/changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md
@@ -0,0 +1,66 @@
+# PKG-DASH-05:真实 DASH SDK 与本地媒体验证检查点
+
+起点 `6840544e`。本批新增真实 SDK/媒体测试与来源证据,没有修改生产实现、公开声明、
+依赖或版本。05 保持 doing,不把浏览器能力缺口或尚未解释的播放停滞计为完成。
+
+## 输入与执行
+
+- 固定实际 npm dash.js 4.5.2 与 5.2.1,归档 SHA512 integrity/SHA256,保存运行脚本、
+ package.json、原始声明和 BSD-3-Clause 许可证成员指纹。SDK 仅供测试,未复制进生产包。
+- 新增 `scripts/generate-dash-fixture.mjs`:FFmpeg 合成 12 秒、90p/180p、英语 440 Hz/
+ 法语 880 Hz AAC 的本地 DASH。三种 MPD 分别为双画质双音轨、纯视频、单画质纯视频。
+ 31 个资源逐字节校验,生成器拒绝覆盖已有目录;MPD 强制 LF,m4s 作为二进制。
+ MPD 保留生成时移除音轨/画质节点留下的空白节点,Git 对此类夹具关闭行尾空白提示,
+ 不手改已运行的 XML 字节或重新写指纹;此例外不适用于源码与其他文件。
+- `test/browser/dash-sdk.spec.js` 加载真实 SDK、发布插件或候选插件、新旧核心,在真实
+ Chromium/Firefox/WebKit 执行。测试控制栏选择、Auto、实际解码视频尺寸与时钟、
+ 外部 SDK 选择后的同步 update、换源菜单拓扑、旧回调与调用方 SDK 销毁所有权。
+- 原生对照不创建 ArtPlayer/插件实例,直接用同一 SDK、video、媒体、缓冲配置执行
+ 画质/音轨与暂停 seek。页面仍加载核心脚本,另断言 Artplayer.instances 为零。
+- 每例附 SDK/插件/媒体来源、输入指纹、能力、轨道/画质、媒体缓冲区、事件时间、片段请求
+ 和浏览器 trace。报告与整个 results 目录在下一次套件前归档到独立缓存。
+
+## 失败原因与证据边界
+
+首轮 24 项:10 通过、8 失败、6 跳过。6 个能力探针的失败来自测试主动 destroy 未 initialize
+的 SDK:实际 4.5.2 源码 destroy → reset → attachSource(null),后者要求已初始化。
+探针只读取版本/能力,不创建媒体资源;已移除错误的未初始化销毁,实际播放用例仍验证销毁。
+
+其余两项分别出现在 Chromium 候选核心/发布插件与 Firefox 发布核心/候选插件的 SDK 4.5.2
+组合:暂停后 seek 到 6 秒无法推进。trace 证明 AbortError 在测试超时后的销毁才出现,
+不能把它当成停滞起因。补充诊断后 24 项为 17 通过、1 失败、6 跳过;Chromium 停滞复现:
+视频缓冲终点 5.999999 秒,time=6、paused=false、seeking=true、readyState=1,未请求
+下一段视频,SDK 错误列表为空。SDK 音轨 rendered 事件已先于 seeking 到达,不能简单
+归因为“没有等音轨切完”。DASH-SEEK-01 保持 open。
+
+原生初始对照、增加缓冲终点接近 6 秒的前提后各 6 项为 4 通过、2 跳过,均没有复现停滞。
+这些通过不能证明 ArtPlayer 是根因,也不能关闭此前新旧核心组合的失败。后续应继续比较
+SourceBuffer 与 video.buffered 的范围、SDK 调度和暂停/seek 顺序;不得仅增大超时、偏移
+seek 目标或吞掉未处理异常来制造通过。
+
+外部 update 与换源首轮 24 项为 8 通过、8 失败、8 跳过。8 个换源失败源于测试保留了
+registry 的可变 option 对象;Component.update 会 Object.assign 修改它,调用到的是新
+回调。改为在换源前保存实际函数和旧 selector item;定向重跑 12 项为 8 通过、4 跳过。
+验证真实 SDK 连续切到无音轨、单画质、原拓扑,旧回调不改变新 SDK,四次 SDK 生命周期
+由调用方恰好销毁四次。没有据此修改生产组件更新语义。
+
+正式 main 整套 54 项为 36 通过、2 失败、16 跳过;两个失败是 Chromium 新旧核心/发布插件
+的同类 SDK 4.5.2 seek 停滞。候选组合本轮通过不能关闭首轮 Firefox 候选插件失败。
+完整 `yarn ci:check` 717 项通过(661 单元、14 工程、42 基线),261 个生产 TS 严格检查通过;
+它不包含该浏览器套件,不能把本地工程检查通过表述为全部浏览器通过。生成器整理参数后
+在新目录重建,31 个资源与冻结字节全部相同;只证明同一 FFmpeg/主机下本次重建。
+已查看候选核心/main/SDK 5.2.1 的 Chromium 播放截图,6 秒画面和 Auto/fr 控件显示正常。
+
+最终 main 执行和 CI 摘要见 [机器证据](../baselines/dash-sdk-checkpoint.json)。所有早期报告、
+trace 和结果目录均保留;本地缓存未上传,换机器应重新执行。后续通过不覆盖开放失败。
+
+## 后续范围与回退
+
+当前 217 项:74 done、4 doing、139 todo。DASH-05 仍需完成停滞排查、实际 SDK 类型消费者、
+SDK 驱动状态刷新/错误和播放组合、legacy 正式产物与有效 MSE/设备环境验证。
+原有同步 update 已通过实际 SDK 对照;当前插件不会自动订阅 SDK 状态变化,自动刷新是否
+增强及其订阅/重入/销毁规则需单独验证,不能从显式 update 的通过推导自动同步已实现。
+06 继续实际 8082 示例生命周期与完整隔离分发,版本升级和全项目发布复盘按总计划执行。
+
+本批为独立本地 checkpoint,不推送、不发布。回退只移除这批测试、合成媒体、生成器和记录,
+保留 01~04 已完成的源码、兼容声明与验证。新增基线测试纳入已有 test:baseline/ci:check。
diff --git a/refactor/dash-validation.md b/refactor/dash-validation.md
index db04b490f..d47c9af39 100644
--- a/refactor/dash-validation.md
+++ b/refactor/dash-validation.md
@@ -19,6 +19,13 @@
TS 4.3.5/5.9.3、五种模块模式、八条非法用法及实际 npm 旧声明的消费者对照。
- `yarn test:dash-types-package`:Yarn 打包核心/DASH、工作区外离线安装与冻结锁重装,
检查五种模式、CommonJS callable/命名空间、每模式八条非法调用,并拒绝解析回工作区。
+- `yarn test:browser test/browser/dash-sdk.spec.js --trace on`:真实 npm dash.js 4.5.2/5.2.1,
+ 本地多画质/多音轨 MPD,新旧核心/插件、外部同步 update、连续换源和 SDK 原生对照。
+ `ARTPLAYER_DASH_ARTIFACT` 可选择正式 main/legacy;未指定则测试源码构建。
+ 无 MSE 的引擎只通过能力探针,播放用例明确跳过,不计为该引擎 DASH 验收。
+- `node --test refactor/scripts/dash-sdk.test.mjs`:SDK 归档/成员/许可证来源、媒体指纹与拓扑。
+ 如需重新合成诊断媒体,用 `node scripts/generate-dash-fixture.mjs refactor/.cache/new-dash-media`,
+ 输出目录必须不存在;可通过 `ARTPLAYER_FFMPEG` 指定 FFmpeg,不覆盖已冻结输入。
Node helper 分别加载当前源码、固定 Git 提交的旧工作区 UMD、实际 npm main/legacy/module。
Git 内容以 LF 指纹核对,发布归档与成员以原始字节指纹核对。`ARTPLAYER_TEST_DASH` 可指定
@@ -29,10 +36,12 @@ Git 内容以 LF 指纹核对,发布归档与成员以原始字节指纹核对
原始轨道身份、调用顺序、错误身份、ABR 配置保留、换 SDK、多实例和关闭后的引用。
真实旧实现的缺陷观察保持冻结;候选生命周期新增正确行为断言,不把历史缺陷当作兼容要求。
-浏览器使用真实发布/候选 ArtPlayer DOM、真实发布/候选插件和本地原生 MP4。SDK 方法可控,
+`dash-control.spec.js` 使用真实发布/候选 ArtPlayer DOM、真实发布/候选插件和本地原生 MP4。SDK 方法可控,
断言真实点击触发的参数及控制栏/设置同步,再通过真实播放按钮验证视频时钟推进、无媒体错误。
**没有加载 dash.js,没有验证 MPD、ABR 自动切换或自适应流解码。** 这些仍是 05 必须完成的
-固定 dash.js 4.5.2 / 5.2.1 集成验证。`ARTPLAYER_DASH_ARTIFACT` 可替换插件脚本;02 未设置,
+固定 dash.js 4.5.2 / 5.2.1 集成验证。独立 `dash-sdk.spec.js` 已开始真实验证,状态以
+[05 检查点](changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md) 为准;不覆盖早期停滞失败。
+`ARTPLAYER_DASH_ARTIFACT` 可替换插件脚本;02 未设置,
03 分别使用正式 main 与 legacy 文件。核心仍按服务端 manifest 加载发布/候选源码构建。
## 02 首次失败与证据
diff --git a/refactor/plan.md b/refactor/plan.md
index b7820431d..9d9592e08 100644
--- a/refactor/plan.md
+++ b/refactor/plan.md
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 217 项,范围 22 个包及工作区/示例。
-状态:todo 140 / doing 3 / blocked 0 / done 74 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
+状态:todo 139 / doing 4 / blocked 0 / done 74 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -205,7 +205,7 @@
| PKG-DASH-02 | artplayer-plugin-dash-control
建立特有行为与错误测试 | PKG-DASH-01, ENG-03, ENG-05 | 保留已有 5 项稳定 ID 回归,补发布版 SDK 4.x/当前 5.x、音轨/空列表/过滤/换源与关闭引用 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-DASH-03 | artplayer-plugin-dash-control
整理内部职责与资源 | PKG-DASH-02, CORE-11, CORE-14 | 能力适配保留 SDK 4.x 与 5.x,稳定 ID 映射、ABR 状态、UI 清理和生命周期职责分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-DASH-04 | artplayer-plugin-dash-control
迁移自有源码和公开类型 | PKG-DASH-03, ENG-04, ENG-06, CORE-07 | dash.js adapter、selector 和回调类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
-| PKG-DASH-05 | artplayer-plugin-dash-control
验证新旧核心和组合 | PKG-DASH-04, CORE-22 | 固定 dash.js 4.5.2/5.2.1 与本地 DASH 实际清晰度/音轨、高亮、Auto 和换源组合 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
+| PKG-DASH-05 | artplayer-plugin-dash-control
验证新旧核心和组合 | PKG-DASH-04, CORE-22 | 固定 dash.js 4.5.2/5.2.1 与本地 DASH 实际清晰度/音轨、高亮、Auto 和换源组合 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | doing |
| PKG-DASH-06 | artplayer-plugin-dash-control
验证分发并同步文档 | PKG-DASH-05, ENG-07 | dash.control.js、支持的 dash.js 版本与产物 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
## 5 包迁移:artplayer-plugin-multiple-subtitles
@@ -483,3 +483,4 @@
- PKG-DASH-02: [记录](changes/2026-09-12-PKG-DASH-02-tests.md) [记录](dash-validation.md) [记录](baselines/dash-validation.json)
- PKG-DASH-03: [记录](changes/2026-09-12-PKG-DASH-03-runtime.md) [记录](baselines/dash-runtime.json) [记录](dash-validation.md)
- PKG-DASH-04: [记录](changes/2026-09-12-PKG-DASH-04-types.md) [记录](baselines/dash-types-validation.json) [记录](dash-validation.md)
+- PKG-DASH-05: [记录](changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md) [记录](baselines/dash-sdk.json) [记录](baselines/dash-sdk-checkpoint.json) [记录](dash-validation.md)
diff --git a/refactor/progress.md b/refactor/progress.md
index 9c9a14479..73445b85a 100644
--- a/refactor/progress.md
+++ b/refactor/progress.md
@@ -1,5 +1,24 @@
# 进度与证据
+## 当前实施:DASH-05 真实 SDK 与 MPD 检查点
+
+已固定 npm dash.js 4.5.2/5.2.1 归档/成员/许可证指纹,新增本地双画质双音轨 DASH、
+纯视频和单画质拓扑,真实 Chromium/Firefox/WebKit 测试及不创建 ArtPlayer 的 SDK 对照。
+正式 main 共 54 项:36 通过、2 失败、16 因 Windows WebKit 无 MSE 跳过,不算播放验收。
+外部 SDK 选择后的同步 update、连续换源/菜单清理、旧回调及调用方 SDK 销毁所有权通过。
+
+两个 main 失败均为 SDK 4.5.2/发布插件的暂停 seek:新旧核心都可在 5.999999 秒缓冲
+终点 seek 到 6 秒后停滞。DASH-SEEK-01 保持 open;AbortError 是超时后销毁的结果,
+不能当作起因。原生对照通过不足以定位或关闭它,首次 Firefox/候选插件失败也仍保留。
+已修正能力探针错误销毁未初始化 SDK、以及换源测试误保留可变 option 对象两个测试问题。
+完整本地工程 CI 717 项通过、261 个生产 TS 严格检查通过;该 CI 不含上述失败的 SDK 浏览器套件。
+生成器在同一 FFmpeg/主机的新目录重建 31 个资源,全部字节一致,已查看实际播放截图。
+
+当前 217 项:74 done、4 doing、139 todo。DASH-05 尚未完成;实际 SDK 类型、自动状态
+刷新/错误、legacy SDK 矩阵、设备和完整分发继续推进。此次没有修改生产源码、依赖或版本。
+详见 [本批记录](changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md)、
+[执行证据](baselines/dash-sdk-checkpoint.json)。以下各节为对应阶段当时的历史状态。
+
## 最新完成:DASH-04 严格 TS、公开类型和编辑器迁移
DASH 五个自有模块全部 TS 化,源码/公开工厂可互相赋值;默认字段和自定义 SDK 泛型准确,
diff --git a/refactor/risk-table.md b/refactor/risk-table.md
index b90cd192c..578a339ac 100644
--- a/refactor/risk-table.md
+++ b/refactor/risk-table.md
@@ -140,3 +140,4 @@
| DASH-STATE-01 | open / 已复现 | DASH 当前项高亮使用真值 ID、音轨身份和标签去重,边界待核实 | PKG-DASH-02, PKG-DASH-03, PKG-DASH-05 |
| DASH-TYPE-01 | resolved / 源码/产物事实 | DASH 类型未表达默认工厂参数、SDK 回调对象和现代模块入口 | PKG-DASH-04 |
| DASH-DEMO-01 | open / 源码/产物事实 | DASH 示例仅新 SDK 且重复安装会累积销毁回调 | PKG-DASH-06 |
+| DASH-SEEK-01 | open / 已复现 | 真实 dash.js 4.5.2 暂停 seek 到缓冲片段边界后可能持续 waiting | PKG-DASH-05, REVIEW-02 |
diff --git a/refactor/risks.json b/refactor/risks.json
index c18399a63..72c39d78d 100644
--- a/refactor/risks.json
+++ b/refactor/risks.json
@@ -2850,7 +2850,8 @@
"test/dash-contract.test.js",
"refactor/dash-validation.md",
"test/dash-lifecycle.test.js",
- "refactor/baselines/dash-runtime.json"
+ "refactor/baselines/dash-runtime.json",
+ "refactor/baselines/dash-sdk-checkpoint.json"
],
"compatibleResolution": "按方法能力适配两代已存在用法,保留 v5 稳定 ID,不能要求旧消费者改用新 SDK。",
"closureCriteria": "归档旧用法、v4/v5 受控及实际媒体矩阵通过,清晰度键不混用。"
@@ -2903,7 +2904,8 @@
"test/dash-contract.test.js",
"refactor/dash-validation.md",
"test/dash-lifecycle.test.js",
- "refactor/baselines/dash-runtime.json"
+ "refactor/baselines/dash-runtime.json",
+ "refactor/baselines/dash-sdk-checkpoint.json"
],
"compatibleResolution": "验证零 ID、重复标签和克隆音轨当前项,在保持原展示语义时按实际可选项定位高亮。",
"closureCriteria": "有受控和真实 SDK 证据说明选中的 representation/track 与 UI 一致。"
@@ -2950,6 +2952,23 @@
],
"compatibleResolution": "验证真实 SDK 销毁和示例重载路径,对齐 v4/v5 文档与示例,不让旧监听误操作新实例。",
"closureCriteria": "真实 8082 demo、旧/新 SDK 路径与 tarball 产物一致,监听和 SDK 所有权可验证。"
+ },
+ {
+ "id": "DASH-SEEK-01",
+ "title": "真实 dash.js 4.5.2 暂停 seek 到缓冲片段边界后可能持续 waiting",
+ "confirmation": "reproduced",
+ "status": "open",
+ "owners": [
+ "PKG-DASH-05",
+ "REVIEW-02"
+ ],
+ "evidence": [
+ "test/browser/dash-sdk.spec.js",
+ "refactor/baselines/dash-sdk-checkpoint.json",
+ "refactor/changes/2026-09-12-PKG-DASH-05-sdk-checkpoint.md"
+ ],
+ "compatibleResolution": "先比较实际 SDK、SourceBuffer/video 缓冲与暂停 seek 调度;不偏移公开 seek 目标,不吞异常或增加超时伪造通过。",
+ "closureCriteria": "原失败的新旧核心/插件组合有确定根因与对应修复/可验证环境边界;原生对照及原顺序、原目标回归成立,后续偶然通过不能关闭。"
}
]
}
diff --git a/refactor/scripts/dash-sdk.test.mjs b/refactor/scripts/dash-sdk.test.mjs
new file mode 100644
index 000000000..33c399af5
--- /dev/null
+++ b/refactor/scripts/dash-sdk.test.mjs
@@ -0,0 +1,51 @@
+import assert from 'node:assert/strict'
+import fs from 'node:fs'
+import path from 'node:path'
+// eslint-disable-next-line test/no-import-node-test -- Verify frozen real SDK and media inputs.
+import test from 'node:test'
+import { ensureArchive, hash, readMember, refactorDir } from './releases.mjs'
+
+test('DASH real SDK releases retain exact versions, executable members, declarations and license provenance', async () => {
+ const baseline = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/dash-sdk.json')))
+ assert.equal(baseline.task, 'PKG-DASH-05')
+ assert.deepEqual(baseline.sdks.map(sdk => sdk.release.version), ['4.5.2', '5.2.1'])
+ for (const sdk of baseline.sdks) {
+ const archive = await ensureArchive(sdk.release)
+ assert.equal(sdk.release.name, 'dashjs')
+ assert.equal(sdk.metadataUrl, `https://registry.npmjs.org/dashjs/${sdk.release.version}`)
+ assert(sdk.release.files[sdk.codeMember])
+ assert(sdk.release.files['package/index.d.ts'])
+ assert(sdk.release.files['package/LICENSE.md'])
+ for (const [member, expected] of Object.entries(sdk.release.files))
+ assert.equal(hash(readMember(archive, member)), expected, member)
+ const manifest = JSON.parse(readMember(archive, 'package/package.json'))
+ assert.equal(manifest.version, sdk.release.version)
+ assert.equal(manifest.name, 'dashjs')
+ assert.equal(manifest.license, 'BSD-3-Clause')
+ }
+})
+
+test('DASH media bytes and topology remain reproducible inputs rather than remote stream assumptions', () => {
+ const directory = path.join(refactorDir, '../test/browser/media/dash')
+ const manifest = JSON.parse(fs.readFileSync(path.join(directory, 'manifest.json')))
+ assert.equal(manifest.kind, 'generated-dash-media')
+ assert.equal(manifest.duration, 12)
+ assert.deepEqual(manifest.videoHeights, [90, 180])
+ assert.deepEqual(manifest.audio, [{ lang: 'en', frequency: 440 }, { lang: 'fr', frequency: 880 }])
+ assert.deepEqual(fs.readdirSync(directory).filter(name => name !== 'manifest.json').sort(), Object.keys(manifest.files).sort())
+ for (const [name, expected] of Object.entries(manifest.files)) {
+ assert(/^[\w.-]+$/.test(name))
+ const bytes = fs.readFileSync(path.join(directory, name))
+ assert.equal(hash(bytes), expected.sha256, name)
+ assert.equal(bytes.length, expected.bytes, name)
+ }
+ const read = name => fs.readFileSync(path.join(directory, name), 'utf8')
+ assert.equal([...read('master.mpd').matchAll(/contentType="audio"/g)].length, 2)
+ assert.equal([...read('master.mpd').matchAll(/]+contentType="audio"[\s\S]*?<\/AdaptationSet>/g
+assert.equal([...master.matchAll(audioSets)].length, 2)
+const videoOnly = master.replace(audioSets, '')
+assert(!videoOnly.includes('contentType="audio"'))
+fs.writeFileSync(path.join(output, 'video-only.mpd'), videoOnly)
+const single = videoOnly.replace(/]+id="1"[\s\S]*?<\/Representation>/, '')
+assert.equal([...single.matchAll(/ [name, { sha256: hash(fs.readFileSync(path.join(output, name))), bytes: fs.statSync(path.join(output, name)).size }]))
+fs.writeFileSync(path.join(output, 'manifest.json'), `${JSON.stringify({ kind: 'generated-dash-media', version, duration: 12, videoHeights: [90, 180], audio: [{ lang: 'en', frequency: 440 }, { lang: 'fr', frequency: 880 }], commands: [args], files }, null, 2)}\n`)
+console.log(`Generated ${Object.keys(files).length} DASH files in ${output}`)
diff --git a/test/browser/dash-sdk.spec.js b/test/browser/dash-sdk.spec.js
new file mode 100644
index 000000000..bdb2b9302
--- /dev/null
+++ b/test/browser/dash-sdk.spec.js
@@ -0,0 +1,307 @@
+import assert from 'node:assert/strict'
+import fs from 'node:fs'
+import process from 'node:process'
+import { ensureArchive, hash, readMember } from '../../refactor/scripts/releases.mjs'
+import { compilePackage } from '../helpers/load.js'
+import { expect, test } from './fixtures.js'
+
+const sdks = new Map()
+const media = new Map()
+let candidate
+let published
+let mediaManifest
+let pluginRelease
+
+test.beforeAll(async () => {
+ const baseline = JSON.parse(fs.readFileSync(new URL('../../refactor/baselines/dash-sdk.json', import.meta.url)))
+ for (const sdk of baseline.sdks) {
+ const archive = await ensureArchive(sdk.release)
+ const bytes = readMember(archive, sdk.codeMember)
+ assert.equal(hash(bytes), sdk.release.files[sdk.codeMember])
+ sdks.set(sdk.release.version, { ...sdk, code: bytes.toString() })
+ }
+ pluginRelease = JSON.parse(fs.readFileSync(new URL('../../refactor/baselines/dash-control-release.json', import.meta.url))).release
+ const bytes = readMember(await ensureArchive(pluginRelease), 'package/dist/artplayer-plugin-dash-control.js')
+ assert.equal(hash(bytes), pluginRelease.files['package/dist/artplayer-plugin-dash-control.js'])
+ published = bytes.toString()
+ candidate = process.env.ARTPLAYER_DASH_ARTIFACT ? fs.readFileSync(process.env.ARTPLAYER_DASH_ARTIFACT, 'utf8') : await compilePackage('artplayer-plugin-dash-control', 'umd')
+ mediaManifest = JSON.parse(fs.readFileSync(new URL('./media/dash/manifest.json', import.meta.url)))
+ for (const [name, expected] of Object.entries(mediaManifest.files)) {
+ assert(/^[\w.-]+$/.test(name))
+ const bytes = fs.readFileSync(new URL(`./media/dash/${name}`, import.meta.url))
+ assert.equal(hash(bytes), expected.sha256)
+ assert.equal(bytes.length, expected.bytes)
+ media.set(name, bytes)
+ }
+})
+
+test.afterEach(async ({ page }, testInfo) => {
+ const state = await page.evaluate(() => {
+ const art = window.art
+ const dash = art?.dash || window.nativeDash
+ let tracks
+ let levels
+ try {
+ tracks = dash?.getTracksFor('audio').map(track => ({ id: track.id, index: track.index, lang: track.lang }))
+ levels = (dash?.getRepresentationsByType?.('video') || dash?.getBitrateInfoListFor?.('video'))?.map(level => ({ id: level.id, qualityIndex: level.qualityIndex, height: level.height }))
+ }
+ catch (error) {
+ levels = { error: error.message }
+ }
+ const video = art?.video || window.nativeVideo
+ const buffered = video ? Array.from({ length: video.buffered.length }, (_, index) => [video.buffered.start(index), video.buffered.end(index)]) : []
+ return { errors: window.sdkErrors, events: window.sdkEvents, mediaEvents: window.mediaEvents, nativePlay: window.nativePlay, tracks, levels, buffered, paused: video?.paused, seeking: video?.seeking, time: video?.currentTime, ready: art?.isReady, width: video?.videoWidth, height: video?.videoHeight, error: video?.error?.code, readyState: video?.readyState, destroyed: window.sdkDestroyed }
+ }).catch(error => ({ error: error.message }))
+ await testInfo.attach('dash-sdk-state', { contentType: 'application/json', body: JSON.stringify(state) })
+ if (!page.isClosed()) {
+ await page.evaluate(() => {
+ if (window.art && !window.art.isDestroy)
+ window.art.destroy()
+ window.nativeDash?.destroy()
+ })
+ }
+})
+
+async function loadSDK(page, version, core, testInfo) {
+ const sdk = sdks.get(version)
+ await page.goto(`/test/player.html?core=${core}`)
+ await page.addScriptTag({ content: sdk.code })
+ const capability = await page.evaluate(() => ({ sdk: window.dashjs.supportsMediaSource(), mse: typeof window.MediaSource, managed: typeof window.ManagedMediaSource, avc: Boolean(window.MediaSource?.isTypeSupported('video/mp4; codecs="avc1.42c01e"')), aac: Boolean(window.MediaSource?.isTypeSupported('audio/mp4; codecs="mp4a.40.2"')) }))
+ await testInfo.attach('dash-sdk-inputs', { contentType: 'application/json', body: JSON.stringify({ sdk: sdk.release, codeMember: sdk.codeMember, pluginRelease, candidateSHA256: hash(candidate), candidate: process.env.ARTPLAYER_DASH_ARTIFACT || 'workspace source build', media: mediaManifest, capability }) })
+ return capability
+}
+
+async function openDash(page, version, core, plugin, testInfo) {
+ const capability = await loadSDK(page, version, core, testInfo)
+ test.skip(!capability.sdk, 'Actual SDK reports no MediaSource support; this engine has no DASH playback acceptance')
+ await routeMedia(page)
+ await page.addScriptTag({ content: plugin === 'published' ? published : candidate })
+ await page.evaluate(() => {
+ window.sdkErrors = []
+ window.sdkEvents = []
+ window.mediaEvents = []
+ window.sdkDestroyed = 0
+ window.art = new window.Artplayer({
+ container: '.player',
+ url: '/dash-fixture/master.mpd',
+ muted: true,
+ setting: true,
+ plugins: [window.artplayerPluginDashControl({ quality: { control: true, setting: true }, audio: { control: true, setting: true } })],
+ customType: { mpd(video, url, art) {
+ if (art.dash) {
+ art.dash.destroy()
+ window.sdkDestroyed++
+ }
+ const dash = window.dashjs.MediaPlayer().create()
+ art.dash = dash
+ dash.updateSettings({ debug: { logLevel: 0 }, streaming: { abr: { initialBitrate: { video: 150 } }, buffer: { fastSwitchEnabled: true, bufferTimeDefault: 2, bufferTimeAtTopQuality: 2 } } })
+ const events = window.dashjs.MediaPlayer.events
+ dash.on(events.ERROR, event => window.sdkErrors.push({ code: event.error?.code, message: event.error?.message, event: event.type }))
+ for (const name of ['STREAM_INITIALIZED', 'QUALITY_CHANGE_REQUESTED', 'QUALITY_CHANGE_RENDERED', 'TRACK_CHANGE_RENDERED', 'STREAM_TEARDOWN_COMPLETE', 'BUFFER_LEVEL_STATE_CHANGED', 'FRAGMENT_LOADING_COMPLETED', 'PLAYBACK_SEEKING', 'PLAYBACK_SEEKED']) {
+ if (events[name])
+ dash.on(events[name], event => window.sdkEvents.push({ name, at: performance.now(), mediaType: event.mediaType, oldQuality: event.oldQuality, newQuality: event.newQuality, state: event.state, url: event.request?.url, time: video.currentTime }))
+ }
+ dash.initialize(video, url, false)
+ } },
+ })
+ const art = window.art
+ for (const name of ['play', 'playing', 'pause', 'seeking', 'seeked', 'waiting', 'emptied', 'loadedmetadata', 'loadeddata', 'canplay', 'error']) {
+ art.video.addEventListener(name, () => window.mediaEvents.push({ name, at: performance.now(), time: art.video.currentTime, paused: art.video.paused, readyState: art.video.readyState, buffered: Array.from({ length: art.video.buffered.length }, (_, index) => [art.video.buffered.start(index), art.video.buffered.end(index)]) }))
+ }
+ art.on('destroy', () => {
+ art.dash.destroy()
+ window.sdkDestroyed++
+ })
+ document.querySelector('#play').onclick = () => art.play()
+ document.querySelector('#pause').onclick = () => art.pause()
+ })
+}
+
+async function routeMedia(page) {
+ await page.route('**/dash-fixture/**', async (route) => {
+ const name = new URL(route.request().url()).pathname.split('/').at(-1)
+ const bytes = media.get(name)
+ await route.fulfill({ status: bytes ? 200 : 503, body: bytes || 'Intentional DASH fixture failure', contentType: name.endsWith('.mpd') ? 'application/dash+xml' : 'video/mp4' })
+ })
+}
+
+for (const version of ['4.5.2', '5.2.1']) {
+ test(`dash.js ${version}: actual SDK reports MSE capabilities and version`, async ({ page }, testInfo) => {
+ const capability = await loadSDK(page, version, 'candidate', testInfo)
+ // This capability probe creates no media resources; destroy requires initialize.
+ const actual = await page.evaluate(() => window.dashjs.MediaPlayer().create().getVersion())
+ expect(actual).toBe(version)
+ if (capability.mse === 'undefined' && capability.managed === 'undefined')
+ expect(capability.sdk).toBe(false)
+ else
+ expect(capability.sdk).toBe(true)
+ })
+}
+
+for (const core of ['published', 'candidate']) {
+ for (const [plugin, version] of [['published', '4.5.2'], ['candidate', '4.5.2'], ['candidate', '5.2.1']]) {
+ test(`${core} core / ${plugin} DASH / ${version}: real MPD decoding and UI selection`, async ({ page }, testInfo) => {
+ await openDash(page, version, core, plugin, testInfo)
+ await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
+ await page.locator('#play').click()
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.3)
+ expect(await page.evaluate(() => window.art.dash.getTracksFor('audio').map(track => track.lang))).toEqual(['en', 'fr'])
+ expect(await page.evaluate(() => window.art.video.getVideoPlaybackQuality().totalVideoFrames)).toBeGreaterThan(0)
+ const control = page.locator('.art-control-dash-quality')
+ await control.hover()
+ await control.locator('.art-selector-item').filter({ hasText: /^180p$/ }).click()
+ await expect.poll(() => page.evaluate(() => ({ auto: window.art.dash.getSettings().streaming.abr.autoSwitchBitrate.video, height: window.art.video.videoHeight }))).toEqual({ auto: false, height: 180 })
+ await control.hover()
+ await control.locator('.art-selector-item').filter({ hasText: /^Auto$/ }).click()
+ expect(await page.evaluate(() => window.art.dash.getSettings().streaming.abr.autoSwitchBitrate.video)).toBe(true)
+ const audio = page.locator('.art-control-dash-audio')
+ await audio.hover()
+ await audio.locator('.art-selector-item').filter({ hasText: /^fr$/ }).click()
+ await expect.poll(() => page.evaluate(() => window.art.dash.getCurrentTrackFor('audio').lang)).toBe('fr')
+ await expect(audio.locator('.art-selector-value')).toHaveText('fr')
+ expect(await page.evaluate(() => window.art.setting.find('dash-audio').tooltip)).toBe('fr')
+ await page.locator('#pause').click()
+ expect(await page.evaluate(() => window.art.video.paused)).toBe(true)
+ await page.evaluate(() => {
+ window.art.seek = 6
+ })
+ await page.locator('#play').click()
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(6.2)
+ expect(await page.evaluate(() => window.sdkErrors)).toEqual([])
+ await testInfo.attach('dash-sdk-playing', { contentType: 'image/png', body: await page.screenshot() })
+ })
+ }
+}
+
+for (const version of ['4.5.2', '5.2.1']) {
+ test(`dash.js ${version}: native SDK track switch and paused seek without ArtPlayer`, async ({ page }, testInfo) => {
+ const capability = await loadSDK(page, version, 'candidate', testInfo)
+ test.skip(!capability.sdk, 'Actual SDK reports no MediaSource support; no native DASH playback acceptance')
+ await routeMedia(page)
+ await page.evaluate(() => {
+ const video = document.createElement('video')
+ window.nativeVideo = video
+ video.muted = true
+ document.querySelector('.player').append(video)
+ const dash = window.dashjs.MediaPlayer().create()
+ window.nativeDash = dash
+ window.sdkEvents = []
+ window.sdkErrors = []
+ window.mediaEvents = []
+ dash.updateSettings({ debug: { logLevel: 0 }, streaming: { abr: { initialBitrate: { video: 150 } }, buffer: { fastSwitchEnabled: true, bufferTimeDefault: 2, bufferTimeAtTopQuality: 2 } } })
+ const events = window.dashjs.MediaPlayer.events
+ dash.on(events.ERROR, event => window.sdkErrors.push({ code: event.error?.code, message: event.error?.message }))
+ for (const name of ['FRAGMENT_LOADING_COMPLETED', 'TRACK_CHANGE_RENDERED', 'QUALITY_CHANGE_RENDERED', 'BUFFER_LEVEL_STATE_CHANGED', 'PLAYBACK_SEEKING', 'PLAYBACK_SEEKED']) {
+ dash.on(events[name], event => window.sdkEvents.push({ name, at: performance.now(), mediaType: event.mediaType, state: event.state, url: event.request?.url, time: video.currentTime }))
+ }
+ for (const name of ['play', 'playing', 'pause', 'seeking', 'seeked', 'waiting']) {
+ video.addEventListener(name, () => window.mediaEvents.push({ name, at: performance.now(), time: video.currentTime, paused: video.paused, readyState: video.readyState, buffered: Array.from({ length: video.buffered.length }, (_, index) => [video.buffered.start(index), video.buffered.end(index)]) }))
+ }
+ dash.initialize(video, '/dash-fixture/master.mpd', false)
+ document.querySelector('#play').onclick = () => {
+ window.nativePlay = 'pending'
+ video.play().then(() => {
+ window.nativePlay = 'fulfilled'
+ }, (error) => {
+ window.nativePlay = `${error.name}: ${error.message}`
+ })
+ }
+ document.querySelector('#pause').onclick = () => video.pause()
+ })
+ await expect.poll(() => page.evaluate(() => window.nativeVideo.readyState)).toBeGreaterThanOrEqual(2)
+ await page.locator('#play').click()
+ await expect.poll(() => page.evaluate(() => window.nativeVideo.currentTime)).toBeGreaterThan(0.3)
+ await page.evaluate(() => {
+ const dash = window.nativeDash
+ dash.updateSettings({ streaming: { abr: { autoSwitchBitrate: { video: false } } } })
+ if (dash.setQualityFor)
+ dash.setQualityFor('video', 1, true)
+ else
+ dash.setRepresentationForTypeById('video', '1', true)
+ })
+ await expect.poll(() => page.evaluate(() => window.nativeVideo.videoHeight)).toBe(180)
+ // Match the failed integrated run: video data ends at the next seek target.
+ await expect.poll(() => page.evaluate(() => window.nativeVideo.buffered.end(window.nativeVideo.buffered.length - 1))).toBeCloseTo(6, 4)
+ await page.evaluate(() => {
+ const dash = window.nativeDash
+ dash.updateSettings({ streaming: { abr: { autoSwitchBitrate: { video: true } } } })
+ dash.setCurrentTrack(dash.getTracksFor('audio').find(track => track.lang === 'fr'))
+ })
+ await expect.poll(() => page.evaluate(() => window.nativeDash.getCurrentTrackFor('audio').lang)).toBe('fr')
+ await page.locator('#pause').click()
+ await page.evaluate(() => {
+ window.nativeVideo.currentTime = 6
+ })
+ await page.locator('#play').click()
+ await expect.poll(() => page.evaluate(() => window.nativeVideo.currentTime)).toBeGreaterThan(6.2)
+ expect(await page.evaluate(() => window.nativePlay)).toBe('fulfilled')
+ expect(await page.evaluate(() => window.sdkErrors)).toEqual([])
+ expect(await page.evaluate(() => window.Artplayer.instances.length)).toBe(0)
+ })
+}
+
+for (const core of ['published', 'candidate']) {
+ for (const version of ['4.5.2', '5.2.1']) {
+ test(`${core} core / DASH ${version}: explicit update reflects external SDK selection`, async ({ page }, testInfo) => {
+ await openDash(page, version, core, 'candidate', testInfo)
+ await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
+ await page.locator('#play').click()
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.3)
+ await page.evaluate(() => {
+ const dash = window.art.dash
+ dash.updateSettings({ streaming: { abr: { autoSwitchBitrate: { video: false } } } })
+ if (dash.setQualityFor)
+ dash.setQualityFor('video', 1)
+ else
+ dash.setRepresentationForTypeById('video', '1')
+ dash.setCurrentTrack(dash.getTracksFor('audio').find(track => track.lang === 'fr'))
+ })
+ await expect.poll(() => page.evaluate(() => window.art.video.videoHeight)).toBe(180)
+ await page.evaluate(() => window.art.plugins.artplayerPluginDashControl.update())
+ await expect(page.locator('.art-control-dash-quality .art-selector-value')).toHaveText('180p')
+ await expect(page.locator('.art-control-dash-audio .art-selector-value')).toHaveText('fr')
+ expect(await page.evaluate(() => ({ quality: window.art.setting.find('dash-quality').tooltip, audio: window.art.setting.find('dash-audio').tooltip }))).toEqual({ quality: '180p', audio: 'fr' })
+ await page.evaluate(() => {
+ window.art.dash.updateSettings({ streaming: { abr: { autoSwitchBitrate: { video: true } } } })
+ window.art.plugins.artplayerPluginDashControl.update()
+ })
+ await expect(page.locator('.art-control-dash-quality .art-selector-value')).toHaveText('Auto')
+ expect(await page.evaluate(() => window.sdkErrors)).toEqual([])
+ })
+
+ test(`${core} core / DASH ${version}: actual source topology replacement and owned cleanup`, async ({ page }, testInfo) => {
+ await openDash(page, version, core, 'candidate', testInfo)
+ await expect(page.locator('.art-control-dash-audio .art-selector-value')).toHaveText('en')
+ await page.locator('#play').click()
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.3)
+ await page.evaluate(() => {
+ const quality = window.art.controls.cache.get('dash-quality').option
+ const audio = window.art.setting.find('dash-audio')
+ // Registry update mutates the option object; retain the actual old callback.
+ window.retainedQuality = { onSelect: quality.onSelect, item: quality.selector[0] }
+ window.retainedAudio = { onSelect: audio.onSelect, item: audio.selector[1] }
+ })
+ await page.evaluate(() => window.art.switchUrl('/dash-fixture/video-only.mpd'))
+ await expect(page.locator('.art-control-dash-audio')).toHaveCount(0)
+ expect(await page.evaluate(() => Boolean(window.art.setting.find('dash-audio')))).toBe(false)
+ expect(await page.evaluate(() => window.art.dash.getTracksFor('audio'))).toEqual([])
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.3)
+ await page.evaluate(() => {
+ window.retainedQuality.onSelect(window.retainedQuality.item)
+ window.retainedAudio.onSelect(window.retainedAudio.item)
+ })
+ expect(await page.evaluate(() => window.art.dash.getSettings().streaming.abr.autoSwitchBitrate.video)).toBe(true)
+ await page.evaluate(() => window.art.switchUrl('/dash-fixture/single.mpd'))
+ await expect(page.locator('.art-control-dash-quality .art-selector-item')).toHaveText(['90p', 'Auto'])
+ await expect.poll(() => page.evaluate(() => window.art.video.videoHeight)).toBe(90)
+ await page.evaluate(() => window.art.switchUrl('/dash-fixture/master.mpd'))
+ await expect(page.locator('.art-control-dash-audio .art-selector-value')).toHaveText('en')
+ await expect(page.locator('.art-control-dash-quality .art-selector-item')).toHaveText(['180p', '90p', 'Auto'])
+ expect(await page.evaluate(() => window.sdkDestroyed)).toBe(3)
+ expect(await page.evaluate(() => window.sdkErrors)).toEqual([])
+ await page.evaluate(() => window.art.destroy(false))
+ expect(await page.evaluate(() => window.sdkDestroyed)).toBe(4)
+ await expect(page.locator('.art-control-dash-quality, .art-control-dash-audio')).toHaveCount(0)
+ })
+ }
+}
diff --git a/test/browser/media/dash/chunk-0-00001.m4s b/test/browser/media/dash/chunk-0-00001.m4s
new file mode 100644
index 000000000..3bba9b751
Binary files /dev/null and b/test/browser/media/dash/chunk-0-00001.m4s differ
diff --git a/test/browser/media/dash/chunk-0-00002.m4s b/test/browser/media/dash/chunk-0-00002.m4s
new file mode 100644
index 000000000..2fe0f663e
Binary files /dev/null and b/test/browser/media/dash/chunk-0-00002.m4s differ
diff --git a/test/browser/media/dash/chunk-0-00003.m4s b/test/browser/media/dash/chunk-0-00003.m4s
new file mode 100644
index 000000000..dacfd8a45
Binary files /dev/null and b/test/browser/media/dash/chunk-0-00003.m4s differ
diff --git a/test/browser/media/dash/chunk-0-00004.m4s b/test/browser/media/dash/chunk-0-00004.m4s
new file mode 100644
index 000000000..300c53f30
Binary files /dev/null and b/test/browser/media/dash/chunk-0-00004.m4s differ
diff --git a/test/browser/media/dash/chunk-0-00005.m4s b/test/browser/media/dash/chunk-0-00005.m4s
new file mode 100644
index 000000000..f537411df
Binary files /dev/null and b/test/browser/media/dash/chunk-0-00005.m4s differ
diff --git a/test/browser/media/dash/chunk-0-00006.m4s b/test/browser/media/dash/chunk-0-00006.m4s
new file mode 100644
index 000000000..5431107ea
Binary files /dev/null and b/test/browser/media/dash/chunk-0-00006.m4s differ
diff --git a/test/browser/media/dash/chunk-1-00001.m4s b/test/browser/media/dash/chunk-1-00001.m4s
new file mode 100644
index 000000000..d6d4c5e51
Binary files /dev/null and b/test/browser/media/dash/chunk-1-00001.m4s differ
diff --git a/test/browser/media/dash/chunk-1-00002.m4s b/test/browser/media/dash/chunk-1-00002.m4s
new file mode 100644
index 000000000..661237b50
Binary files /dev/null and b/test/browser/media/dash/chunk-1-00002.m4s differ
diff --git a/test/browser/media/dash/chunk-1-00003.m4s b/test/browser/media/dash/chunk-1-00003.m4s
new file mode 100644
index 000000000..e8ebe1df2
Binary files /dev/null and b/test/browser/media/dash/chunk-1-00003.m4s differ
diff --git a/test/browser/media/dash/chunk-1-00004.m4s b/test/browser/media/dash/chunk-1-00004.m4s
new file mode 100644
index 000000000..562188ec8
Binary files /dev/null and b/test/browser/media/dash/chunk-1-00004.m4s differ
diff --git a/test/browser/media/dash/chunk-1-00005.m4s b/test/browser/media/dash/chunk-1-00005.m4s
new file mode 100644
index 000000000..9bb58d078
Binary files /dev/null and b/test/browser/media/dash/chunk-1-00005.m4s differ
diff --git a/test/browser/media/dash/chunk-1-00006.m4s b/test/browser/media/dash/chunk-1-00006.m4s
new file mode 100644
index 000000000..5c22671ec
Binary files /dev/null and b/test/browser/media/dash/chunk-1-00006.m4s differ
diff --git a/test/browser/media/dash/chunk-2-00001.m4s b/test/browser/media/dash/chunk-2-00001.m4s
new file mode 100644
index 000000000..9fd0e0ed5
Binary files /dev/null and b/test/browser/media/dash/chunk-2-00001.m4s differ
diff --git a/test/browser/media/dash/chunk-2-00002.m4s b/test/browser/media/dash/chunk-2-00002.m4s
new file mode 100644
index 000000000..40b1362d4
Binary files /dev/null and b/test/browser/media/dash/chunk-2-00002.m4s differ
diff --git a/test/browser/media/dash/chunk-2-00003.m4s b/test/browser/media/dash/chunk-2-00003.m4s
new file mode 100644
index 000000000..372dd371a
Binary files /dev/null and b/test/browser/media/dash/chunk-2-00003.m4s differ
diff --git a/test/browser/media/dash/chunk-2-00004.m4s b/test/browser/media/dash/chunk-2-00004.m4s
new file mode 100644
index 000000000..2d14c0ceb
Binary files /dev/null and b/test/browser/media/dash/chunk-2-00004.m4s differ
diff --git a/test/browser/media/dash/chunk-2-00005.m4s b/test/browser/media/dash/chunk-2-00005.m4s
new file mode 100644
index 000000000..23050a405
Binary files /dev/null and b/test/browser/media/dash/chunk-2-00005.m4s differ
diff --git a/test/browser/media/dash/chunk-2-00006.m4s b/test/browser/media/dash/chunk-2-00006.m4s
new file mode 100644
index 000000000..c124a7c8a
Binary files /dev/null and b/test/browser/media/dash/chunk-2-00006.m4s differ
diff --git a/test/browser/media/dash/chunk-3-00001.m4s b/test/browser/media/dash/chunk-3-00001.m4s
new file mode 100644
index 000000000..6b8a81c2b
Binary files /dev/null and b/test/browser/media/dash/chunk-3-00001.m4s differ
diff --git a/test/browser/media/dash/chunk-3-00002.m4s b/test/browser/media/dash/chunk-3-00002.m4s
new file mode 100644
index 000000000..afc3ac16a
Binary files /dev/null and b/test/browser/media/dash/chunk-3-00002.m4s differ
diff --git a/test/browser/media/dash/chunk-3-00003.m4s b/test/browser/media/dash/chunk-3-00003.m4s
new file mode 100644
index 000000000..f43397911
Binary files /dev/null and b/test/browser/media/dash/chunk-3-00003.m4s differ
diff --git a/test/browser/media/dash/chunk-3-00004.m4s b/test/browser/media/dash/chunk-3-00004.m4s
new file mode 100644
index 000000000..1529c4ae0
Binary files /dev/null and b/test/browser/media/dash/chunk-3-00004.m4s differ
diff --git a/test/browser/media/dash/chunk-3-00005.m4s b/test/browser/media/dash/chunk-3-00005.m4s
new file mode 100644
index 000000000..7027176bc
Binary files /dev/null and b/test/browser/media/dash/chunk-3-00005.m4s differ
diff --git a/test/browser/media/dash/chunk-3-00006.m4s b/test/browser/media/dash/chunk-3-00006.m4s
new file mode 100644
index 000000000..4aa3dbcc4
Binary files /dev/null and b/test/browser/media/dash/chunk-3-00006.m4s differ
diff --git a/test/browser/media/dash/init-0.m4s b/test/browser/media/dash/init-0.m4s
new file mode 100644
index 000000000..7454bebc8
Binary files /dev/null and b/test/browser/media/dash/init-0.m4s differ
diff --git a/test/browser/media/dash/init-1.m4s b/test/browser/media/dash/init-1.m4s
new file mode 100644
index 000000000..ceaecc43f
Binary files /dev/null and b/test/browser/media/dash/init-1.m4s differ
diff --git a/test/browser/media/dash/init-2.m4s b/test/browser/media/dash/init-2.m4s
new file mode 100644
index 000000000..deab9dc46
Binary files /dev/null and b/test/browser/media/dash/init-2.m4s differ
diff --git a/test/browser/media/dash/init-3.m4s b/test/browser/media/dash/init-3.m4s
new file mode 100644
index 000000000..deab9dc46
Binary files /dev/null and b/test/browser/media/dash/init-3.m4s differ
diff --git a/test/browser/media/dash/manifest.json b/test/browser/media/dash/manifest.json
new file mode 100644
index 000000000..010abb238
--- /dev/null
+++ b/test/browser/media/dash/manifest.json
@@ -0,0 +1,222 @@
+{
+ "kind": "generated-dash-media",
+ "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
+ "duration": 12,
+ "videoHeights": [
+ 90,
+ 180
+ ],
+ "audio": [
+ {
+ "lang": "en",
+ "frequency": 440
+ },
+ {
+ "lang": "fr",
+ "frequency": 880
+ }
+ ],
+ "commands": [
+ [
+ "-hide_banner",
+ "-loglevel",
+ "error",
+ "-n",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=160x90:rate=24",
+ "-f",
+ "lavfi",
+ "-i",
+ "testsrc2=size=320x180:rate=24",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=440:sample_rate=48000",
+ "-f",
+ "lavfi",
+ "-i",
+ "sine=frequency=880:sample_rate=48000",
+ "-t",
+ "12",
+ "-map",
+ "0:v",
+ "-map",
+ "1:v",
+ "-map",
+ "2:a",
+ "-map",
+ "3:a",
+ "-c:v",
+ "libx264",
+ "-pix_fmt",
+ "yuv420p",
+ "-profile:v",
+ "baseline",
+ "-level:v",
+ "3.0",
+ "-b:v:0",
+ "150k",
+ "-b:v:1",
+ "350k",
+ "-g",
+ "48",
+ "-keyint_min",
+ "48",
+ "-sc_threshold",
+ "0",
+ "-c:a",
+ "aac",
+ "-b:a",
+ "48k",
+ "-ac",
+ "2",
+ "-metadata:s:a:0",
+ "language=en",
+ "-metadata:s:a:1",
+ "language=fr",
+ "-f",
+ "dash",
+ "-seg_duration",
+ "2",
+ "-use_template",
+ "1",
+ "-use_timeline",
+ "1",
+ "-adaptation_sets",
+ "id=0,streams=0,1 id=1,streams=2 id=2,streams=3",
+ "-init_seg_name",
+ "init-$RepresentationID$.m4s",
+ "-media_seg_name",
+ "chunk-$RepresentationID$-$Number%05d$.m4s",
+ "master.mpd"
+ ]
+ ],
+ "files": {
+ "chunk-0-00001.m4s": {
+ "sha256": "0bc9f5c9bfc50526dfdc0241ac5d2da2332097d738450a41887bceb8d0b1f305",
+ "bytes": 32029
+ },
+ "chunk-0-00002.m4s": {
+ "sha256": "a3baefa3f68381a844419beabdee422dc4298c102a7b45a9da16d89b74f461fc",
+ "bytes": 41742
+ },
+ "chunk-0-00003.m4s": {
+ "sha256": "f2540e0a1871967a910e25567aa19ce9aaef002bba84f8cdda8ca9bbc8abd40e",
+ "bytes": 36346
+ },
+ "chunk-0-00004.m4s": {
+ "sha256": "21905f15e90b22cd868d55924d44723b9a02a7b1132384a60b526e49646e9e07",
+ "bytes": 41226
+ },
+ "chunk-0-00005.m4s": {
+ "sha256": "9d0cb0486da40f3a4e6819a5964d4db945305d328cce6ce2c21a60a57c413f42",
+ "bytes": 35119
+ },
+ "chunk-0-00006.m4s": {
+ "sha256": "f52fd4ecf9d0276261b183c6e44096ad2f28267a5f2a0a15ac65cec8705b605f",
+ "bytes": 38357
+ },
+ "chunk-1-00001.m4s": {
+ "sha256": "389d6f02741679ed7ef43f529bbec746b5e1b62a97519ca80be16f114e76845c",
+ "bytes": 72180
+ },
+ "chunk-1-00002.m4s": {
+ "sha256": "5cc737843b84a064acb65d985b2ea7ff151c26937f5bf48cacdf0f39c9e60122",
+ "bytes": 94545
+ },
+ "chunk-1-00003.m4s": {
+ "sha256": "2a1b56d88858f3d9b6070ab8645d878b12f8baa29c567b038d190f89c2f863e6",
+ "bytes": 84303
+ },
+ "chunk-1-00004.m4s": {
+ "sha256": "be7198ae2b2d04e27748fcbe8669734a7ead3a51c25fb7f1c9d981740bf5f92d",
+ "bytes": 95672
+ },
+ "chunk-1-00005.m4s": {
+ "sha256": "502e3dd1ce6ca85c442ba849e605a1b0cb1ca23472af6fe6e0dacaea8a38d5dc",
+ "bytes": 82244
+ },
+ "chunk-1-00006.m4s": {
+ "sha256": "34d6e27576dc3c834d0aff9e5925581a899c354c4fdd34fc639cc63f9807c62f",
+ "bytes": 90139
+ },
+ "chunk-2-00001.m4s": {
+ "sha256": "23eaaffa433ed1808f57b95e14b85fba15b2d7e8eea6c51fd02ce409dbccf7de",
+ "bytes": 12437
+ },
+ "chunk-2-00002.m4s": {
+ "sha256": "f40e15cb8d377dcd4eeac508493694e4a131fd4a0d970ff2636b1b40fc728f0a",
+ "bytes": 12641
+ },
+ "chunk-2-00003.m4s": {
+ "sha256": "e1a1f49359d23f460f9b0a32df5f5da7ba6d234fe59cc4a9c0a5f7e201fed643",
+ "bytes": 12663
+ },
+ "chunk-2-00004.m4s": {
+ "sha256": "a5b0625a33a62cf2b73414c92b7c9f6ac945650d3ff6dadaff26705d10920bf6",
+ "bytes": 12657
+ },
+ "chunk-2-00005.m4s": {
+ "sha256": "ed446e2eb99474765e9b0eb40728bd5d79eba79e74b5fa688a0dbddfb3f4b82a",
+ "bytes": 12682
+ },
+ "chunk-2-00006.m4s": {
+ "sha256": "6b969d834a87836f84eac8769fba2962c8303aacbb832f4710e642a371c6e38e",
+ "bytes": 13008
+ },
+ "chunk-3-00001.m4s": {
+ "sha256": "9171ffc0421c4dc0f874eb8801c2df0b4bf312981a8841455b13081cca1b0feb",
+ "bytes": 12453
+ },
+ "chunk-3-00002.m4s": {
+ "sha256": "da7a827ad08e9b48647f2bc6c90d5db1b53ef15965575d38b7e9facbddd37fc1",
+ "bytes": 12644
+ },
+ "chunk-3-00003.m4s": {
+ "sha256": "3d5f9fd99a21ce3d59f11416936d79252a12bc95560988f1abe4ccf802733ebc",
+ "bytes": 12643
+ },
+ "chunk-3-00004.m4s": {
+ "sha256": "eeca9b9a3f91c8491ad663cb5d686b168c530dc771d46c35ff5919b3a8b4ee37",
+ "bytes": 12678
+ },
+ "chunk-3-00005.m4s": {
+ "sha256": "747526362131944d696b09059ba0a19c106e363a30fa07cf7ec86081c4e277e8",
+ "bytes": 12582
+ },
+ "chunk-3-00006.m4s": {
+ "sha256": "5234fd26fd201536c839a1740d3bd57a5fe8c86e3e180f7f1e4c70cc41f30072",
+ "bytes": 13077
+ },
+ "init-0.m4s": {
+ "sha256": "d0a16341c48647e27452db83de88f88209dbec7e539e159e5057469d28980881",
+ "bytes": 827
+ },
+ "init-1.m4s": {
+ "sha256": "3e814e958e68e98f947883a2b7511a36fb06db127ea074ccd569af0200839948",
+ "bytes": 828
+ },
+ "init-2.m4s": {
+ "sha256": "866460ae9e8465b1473c3dbbc63f38416815d75d906790109575cf1de8332423",
+ "bytes": 764
+ },
+ "init-3.m4s": {
+ "sha256": "866460ae9e8465b1473c3dbbc63f38416815d75d906790109575cf1de8332423",
+ "bytes": 764
+ },
+ "master.mpd": {
+ "sha256": "6a4cb0a956861dee9aff1c592525c41fb4cf660be86b4c3892a91a46aeec53ef",
+ "bytes": 2986
+ },
+ "single.mpd": {
+ "sha256": "bdbd8a027281cefec1d4021d7e5a2731875188eb331612bc35eef75f265a700b",
+ "bytes": 1227
+ },
+ "video-only.mpd": {
+ "sha256": "b7f8d37c023810ecc38a2564d4644eda4b5a0b0dd2d10dfd39f70a4b49be0566",
+ "bytes": 1622
+ }
+ }
+}
diff --git a/test/browser/media/dash/master.mpd b/test/browser/media/dash/master.mpd
new file mode 100644
index 000000000..0ae2c7dd3
--- /dev/null
+++ b/test/browser/media/dash/master.mpd
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/browser/media/dash/single.mpd b/test/browser/media/dash/single.mpd
new file mode 100644
index 000000000..cd548f566
--- /dev/null
+++ b/test/browser/media/dash/single.mpd
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/browser/media/dash/video-only.mpd b/test/browser/media/dash/video-only.mpd
new file mode 100644
index 000000000..c0d3107fd
--- /dev/null
+++ b/test/browser/media/dash/video-only.mpd
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+