From 190fdb277600a1f19abf528ecef424d55dd70545 Mon Sep 17 00:00:00 2001 From: Harvey Zhao Date: Sat, 12 Sep 2026 22:11:27 +0800 Subject: [PATCH] test(mediabunny): [PKG-MB-09] verify native picture-in-picture checkpoint --- .../baselines/mb-native-pip-checkpoint.json | 1267 +++++++++++++++++ ...6-09-12-PKG-MB-09-native-pip-checkpoint.md | 44 + refactor/mb-validation.md | 9 + refactor/plan.md | 5 +- refactor/progress.md | 9 + refactor/risk-guide.md | 4 + refactor/risks.json | 14 +- refactor/tasks.json | 7 +- test/browser/mediabunny-dpip.spec.js | 113 ++ 9 files changed, 1466 insertions(+), 6 deletions(-) create mode 100644 refactor/baselines/mb-native-pip-checkpoint.json create mode 100644 refactor/changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md create mode 100644 test/browser/mediabunny-dpip.spec.js diff --git a/refactor/baselines/mb-native-pip-checkpoint.json b/refactor/baselines/mb-native-pip-checkpoint.json new file mode 100644 index 000000000..1c3abb938 --- /dev/null +++ b/refactor/baselines/mb-native-pip-checkpoint.json @@ -0,0 +1,1267 @@ +{ + "task": "PKG-MB-09", + "status": "doing", + "parentCommit": "fb9fb23f5366cba41b85eda2df38e37adac3277d", + "sourceSha256LF": { + "packages/artplayer-proxy-mediabunny/dist/artplayer-proxy-mediabunny.js": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.js": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "packages/artplayer-proxy-mediabunny/src/index.ts": "0c8f1318cf95152a4e1bcb57e60c97e2f3cb02fe6d9d4ff7dc5666159f87fbc2", + "packages/artplayer-proxy-mediabunny/src/VideoEngine.ts": "1c41d43e663b51319d25dccb08a16c7450703dcdffe15d686b4fa3f0a8c7a7e6", + "packages/artplayer-proxy-mediabunny/src/AudioEngine.ts": "4d58cc30148bb4d9e384ea4716a805b00dd9633e03130ba6aeac8d431dd72c43", + "packages/artplayer-plugin-document-pip/src/index.ts": "28ba9b809589f4c58acc7d36bc2bb11b75832e8e6e009487c741c5b47dc4a590", + "packages/artplayer-plugin-document-pip/src/window-session.ts": "cf6bc403caf22ecfea14da7bfa91ddb88a60ed0507d5485035abe48861e1ad17", + "test/browser/mediabunny-dpip.spec.js": "3b99591e0044021dc1f049a86e87d1c0d477f63766eb620ea3f30d3ce05ced4a" + }, + "browser": { + "total": 36, + "native": 24, + "unavailable": 12, + "records": [ + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.31999999999999995, + "draws": 8, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.31999999999999995, + "draws": 8, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.31999999999999995, + "draws": 8, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28800000000000003, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.32, + "draws": 8, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.2693333333333333, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.2693333333333333, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.26133333333333336, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "chromium", + "browser": "153.0.8010.12", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.2613333333333333, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.2906666666666667, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.272, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28800000000000003, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.28, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.26666666666666666, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.25866666666666666, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.27999999999999997, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.29066666666666663, + "draws": 7, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.32266666666666666, + "draws": 8, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true, + false + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "firefox", + "browser": "155.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-canvas-playback", + "before": { + "time": 0.32266666666666666, + "draws": 8, + "adopted": true, + "sameCanvas": true, + "distinctWindow": true, + "openerVisibility": "visible" + }, + "result": { + "events": [ + true + ], + "placeholders": 0, + "nativeWindowClosed": true + }, + "scope": "Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP." + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "video", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "core": "published", + "media": "hls", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "video", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "native-close", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + }, + { + "project": "webkit", + "browser": "26.6", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15", + "platform": "win32", + "coreSource": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "df495dd386d32ea96be5006e1bbfda1ea91cfeb32aa21758197b46a155ebe0dc", + "bytes": 378040 + }, + "core": "candidate", + "media": "hls", + "ending": "destroy", + "implementation": "candidate-artifact", + "sha256": "23ce59f86e7159eedd4c371219c5ed58db83341e1f3fa3c67dcb8f1259e243cb", + "dpipSha256": "56440aad3ed06be55ec3a57d781f7de239e9aecf40a067e88f2cffcd01a86d6a", + "outcome": "native-document-pip-unavailable", + "browserName": "webkit", + "supported": false + } + ], + "report": "refactor/.cache/mb09-native-pip-results/report.json", + "reportSha256": "c912a5a762bf21fb622a82faaa18a4ca4d2825f7fb0a3cc354b58c84e3c54c80", + "results": "refactor/.cache/mb09-native-pip-results/results" + }, + "checks": [ + { + "command": "yarn test:browser test/browser/mediabunny-dpip.spec.js", + "result": "pass", + "tests": 36 + }, + { + "command": "yarn ci:check", + "result": "pass", + "log": "refactor/.cache/mb09-native-ci-final.log", + "tests": 1418, + "repeatedContracts": 44, + "strictProductionTypeScriptFiles": 324, + "previousFailure": { + "log": "refactor/.cache/mb09-native-ci.log", + "reason": "MB-08 risk closure omitted required resolution fields after its passing CI. Fields repaired; validator unchanged." + } + } + ], + "limitations": [ + "Opener remained visible; no background throttling claim.", + "Native window tests use video-only MP4 and HLS with video/audio; these short runs do not prove long-run synchronization.", + "Twelve WebKit API-unavailable cases are not successful playback or physical Safari evidence.", + "Document PiP full video/Canvas/MediaBunny combinations remain PKG-DPIP-05.", + "Long playback, wider interactions and physical device/support work remain PKG-MB-09." + ] +} diff --git a/refactor/changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md b/refactor/changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md new file mode 100644 index 000000000..8c1876574 --- /dev/null +++ b/refactor/changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md @@ -0,0 +1,44 @@ +# PKG-MB-09 检查点:真实 Document PiP 组合 + +本任务保持doing;本检查点只完成原生画中画的首组组合验证,不代表长播放、设备与全部组合验收。 +执行环境为本机Windows,Playwright Chromium 153.0.8010.12、Firefox 155.0、WebKit 26.6。 +原生行为按实际API探测与运行结果记录,不由浏览器名称猜测,也不将WebKit称为真实Safari设备。 + +新增mediabunny-dpip.spec.js使用固定main产物、实际发布核心/候选核心和Document PiP产物。 +从真实button click调用requestWindow,未覆盖API,未使用iframe代替窗口。确认独立Window与 +Canvas/播放器节点迁移,迁移后实际drawImage及媒体时钟继续前进。 + +矩阵为2个核心×video-only/HLS音视频×插件close/原生window.close/destroy×3个引擎,共36项。 +Chromium/Firefox共24项完成真实窗口/Canvas播放;HLS另验证实际AudioBufferSourceNode调度, +插件close场景在PiP内切换到90P与French音轨后还原。关闭还原验证原parent/document、同一Canvas、 +占位符清零和原生窗口关闭;销毁验证引擎关闭且不再向销毁后的ArtPlayer发document-pip=false。 +WebKit共12项记录为Document PiP API不可用,未创建播放器或计作媒体播放成功。 + +此前dpip-helpers.js仍是受控requestWindow与真实iframe DOM测试;本文件有明确独立作用, +不能用本轮少数组合替换那些异常时序/部分setup失败回归,也不能把旧iframe证据重新标为原生。 +首轮12项(8原生/4不可用)及扩展36项均保留report.json和整个results目录。 + +验证命令:设置ARTPLAYER_MB_ARTIFACT和ARTPLAYER_DPIP_ARTIFACT指向各包已构建main后, +运行`yarn test:browser test/browser/mediabunny-dpip.spec.js`。源模式也能运行,但报告必须记录 +实际code hash和实施来源;产物验证不能默默降级为源构建。新用例已由默认浏览器文件发现机制纳入。 + +结果、产物/测试哈希、核心来源和浏览器版本见[原生窗口证据](../baselines/mb-native-pip-checkpoint.json)。 +当前没有生产源码或依赖变更。最终完整CI1418项和44重复契约通过,324生产TS;台账失败与修复均保留。 + +## 接续范围 + +- 生成可重复长AV媒体,独立运行真实持续播放与1×/2×、seek/quality/audio切换,记录逐帧与音频时钟偏差。 +- 跟踪在用音频节点、迭代器/RAF与destroy后清理,避免测试自身持有所有历史节点造成伪内存增长。 +- 验证PiP opener不可见、重复开关、恢复播放与更多键盘/焦点组合;本轮opener始终visible,不作后台节流保证。 +- 原生视频、Canvas proxy与完整Document PiP插件验收仍归PKG-DPIP-05,不能由本轮只测MediaBunny宣告完成。 +- 真实Safari/设备支持矩阵、长播放和完整分发/许可仍未关闭;MB-CAP-01、MB-LIFE-01、MB-LICENSE-01保持open。 + +FFmpeg已在D:\ffmpeg\bin\ffmpeg.exe可用,长媒体应由明确命令生成并保存版本/参数/哈希,不能把短视频 +若干次seek冒充长时间持续播放。本检查点不发布、不推送,不计作任务完成。 + +## CI台账修复 + +首轮完整CI在风险检查失败:MB-08验收后更新状态时,遗漏了MB-TYPE-01和MB-READY-01 +的resolutionEvidence/resolutionRationale。原关闭事实及证据不变,补齐台账要求字段, +保留失败日志mb09-native-ci.log,不放宽验证器。今后任务/风险状态与最终文档更新后, +还须执行plan --check、risk-register --check及风险测试,避免只检查状态更新前的快照。 diff --git a/refactor/mb-validation.md b/refactor/mb-validation.md index 22a7a7b14..4d9211dcb 100644 --- a/refactor/mb-validation.md +++ b/refactor/mb-validation.md @@ -101,3 +101,12 @@ video-only输入及替换无sink仍readyState=4;任务保持doing,下一步 [变更](changes/2026-09-12-PKG-MB-08-capability.md)和[证据](baselines/mb-capability-validation.json) 核对全部源码/产物/报告/安装文件哈希。MB-TYPE-01/MB-READY-01关闭;任务done并立即专用提交。 39个WebKit能力对照不是播放或物理Safari支持,长播放/设备/组合及分发许可仍由09/10接续。 + +## PKG-MB-09 原生画中画检查点(doing) + +36个新旧核心/媒体/关闭方式/浏览器场景通过,24项实际原生窗口中Canvas解码播放, +12项WebKit缺失API对照未计作播放。HLS在画中画中切换质量/音轨,关闭还原与销毁清理通过。 +本轮opener始终visible,未覆盖后台节流。完整CI1418与44重复契约通过;补齐MB-08风险 +关闭字段遗漏,失败日志保留。见[变更](changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md) +和[证据](baselines/mb-native-pip-checkpoint.json)。222项:105 done、8 doing、109 todo。 +MB-09仍doing;接续持续播放/AV同步/更多组合与设备,DPIP-05仍独立验收。 diff --git a/refactor/plan.md b/refactor/plan.md index 22c845d2a..e81de03c3 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 222 项,范围 22 个包及工作区/示例。 -状态:todo 110 / doing 7 / blocked 0 / done 105 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 109 / doing 8 / blocked 0 / done 105 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -337,7 +337,7 @@ | PKG-MB-06 | artplayer-proxy-mediabunny
整理音频解码、时钟与同步 | PKG-MB-04 | AudioEngine 时钟、缓冲和 AudioContext 归属 | AV sync、倍速、无音轨、静音/音量和暂停恢复通过 | H | done | | PKG-MB-07 | artplayer-proxy-mediabunny
整理 HLS 配对轨道与 selector | PKG-MB-05, PKG-MB-06, CORE-14 | m3u8 配对、质量/音频选择及拓扑清理 | 实际选择高亮、切到无轨道来源清理、无重复 readiness | H | done | | PKG-MB-08 | artplayer-proxy-mediabunny
完成 TS 与媒体能力声明 | PKG-MB-07, ENG-04, ENG-06 | 8 个自有 JS 模块迁移与 Result/shim 类型 | 解码器/Stream/DOM 类型清楚,旧 Option 和 art.mediabunny 使用保持 | H | done | -| PKG-MB-09 | artplayer-proxy-mediabunny
完成新旧核心和真实媒体组合 | PKG-MB-08, CORE-22 | 跨浏览器能力、长播放、DPiP、HLS 音轨/质量报告 | 资源释放、事件顺序、AV sync 与支持范围满足基线 | H | todo | +| PKG-MB-09 | artplayer-proxy-mediabunny
完成新旧核心和真实媒体组合 | PKG-MB-08, CORE-22 | 跨浏览器能力、长播放、DPiP、HLS 音轨/质量报告 | 资源释放、事件顺序、AV sync 与支持范围满足基线 | H | doing | | PKG-MB-10 | artplayer-proxy-mediabunny
完成分发和文档 | PKG-MB-09, ENG-07 | mediabunny.js、README、依赖版本、三产物和许可 | tarball 可消费、无意外依赖升级、旧调用与回退可用 | H | todo | ## 5 包迁移:artplayer-tool-iframe @@ -528,4 +528,5 @@ - PKG-MB-06: [记录](baselines/mb-audio-source.json) [记录](changes/2026-09-12-PKG-MB-06-audio.md) [记录](baselines/mb-audio-validation.json) - PKG-MB-07: [记录](baselines/mb-hls-source.json) [记录](changes/2026-09-12-PKG-MB-07-hls.md) [记录](baselines/mb-hls-validation.json) - PKG-MB-08: [记录](baselines/mb-entry-source.json) [记录](changes/2026-09-12-PKG-MB-08-entry-checkpoint.md) [记录](baselines/mb-entry-checkpoint.json) [记录](baselines/mb-capability-source.json) [记录](changes/2026-09-12-PKG-MB-08-capability.md) [记录](baselines/mb-capability-validation.json) +- PKG-MB-09: [记录](changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md) [记录](baselines/mb-native-pip-checkpoint.json) - PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md) diff --git a/refactor/progress.md b/refactor/progress.md index 9bd1166c7..4be39aaed 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,14 @@ # 进度与证据 +## PKG-MB-09 原生画中画检查点(doing) + +36个新旧核心/媒体/关闭方式/浏览器场景通过,24项实际原生窗口中Canvas解码播放, +12项WebKit缺失API对照未计作播放。HLS在画中画中切换质量/音轨,关闭还原与销毁清理通过。 +本轮opener始终visible,未覆盖后台节流。完整CI1418与44重复契约通过;补齐MB-08风险 +关闭字段遗漏,失败日志保留。见[变更](changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md) +和[证据](baselines/mb-native-pip-checkpoint.json)。222项:105 done、8 doing、109 todo。 +MB-09仍doing;接续持续播放/AV同步/更多组合与设备,DPIP-05仍独立验收。 + ## PKG-MB-08完成:严格TS、兼容声明与解码能力边界 全包34生产TS已迁移,默认可选工厂/精确Canvas兼容;显式媒体类型不泄漏SDK现代声明。 diff --git a/refactor/risk-guide.md b/refactor/risk-guide.md index 0c050b365..f13c0407e 100644 --- a/refactor/risk-guide.md +++ b/refactor/risk-guide.md @@ -54,3 +54,7 @@ yarn ci:check ``` 校验已包含在 test:baseline 中:保护既有基线发现、任务引用、证据路径、生成索引、包覆盖、依赖解析和内嵌文件指纹。负例覆盖漏项、错误任务、无证据关闭、越界路径、错误哈希和锁文件版本偏移。它不能自动发现所有新的第三方文件或判定许可证合规,新增资源仍须进入人工/AI 审查与包任务验收。 + +任务或风险验收后若再次更新状态/关闭字段,提交前须针对最终快照运行plan --check、 +risk-register --check与风险测试。resolved/accepted-with-scope必须填写resolutionEvidence +和resolutionRationale;不能仅在compatibleResolution或普通evidence中写关闭事实。 diff --git a/refactor/risks.json b/refactor/risks.json index 8d9b6bb54..05e72ea11 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -3690,7 +3690,12 @@ "refactor/baselines/mb-entry-checkpoint.json", "refactor/changes/2026-09-12-PKG-MB-08-capability.md", "refactor/baselines/mb-capability-validation.json" - ] + ], + "resolutionEvidence": [ + "refactor/changes/2026-09-12-PKG-MB-08-capability.md", + "refactor/baselines/mb-capability-validation.json" + ], + "resolutionRationale": "Preserved exact optional whole-factory and HTMLCanvasElement result; real VideoShim implements opt-in media/Player/HLS/synthetic-frame types without modern SDK declarations leaking to older compilers. Conditional ESM declarations and classic legacy resolution work. Runtime supports both historical default namespace and callable use without a required default property narrowing factory replacement. Final isolated installs of two frozen releases and candidate pass 17 compiler/runtime cases; seven candidate modes each reject fifteen invalid uses and check bidirectional assignments against actual frozen declaration bytes. Complete distribution/license/device gates remain separate." }, { "id": "MB-CAP-01", @@ -3729,7 +3734,12 @@ "refactor/baselines/mb-entry-checkpoint.json", "refactor/changes/2026-09-12-PKG-MB-08-capability.md", "refactor/baselines/mb-capability-validation.json" - ] + ], + "resolutionEvidence": [ + "refactor/changes/2026-09-12-PKG-MB-08-capability.md", + "refactor/baselines/mb-capability-validation.json" + ], + "resolutionRationale": "Coordinated metadata publishes once, trackless input rejects before decoder setup, and stale callbacks cannot publish. MB-08 additionally rejects existing but wholly undecodable tracks before metadata/data/canplay and before replacement success, preserving one usable audio/video track, SDK query errors and late-operation cancellation. Sixteen controlled Node cases and thirty added browser cases distinguish twelve controlled rejection cases, eight native partial-decoder playback cases and ten missing-API controls; the final 150-case media suite passes. Physical Safari/support-range work remains MB-CAP-01 rather than being claimed from these controls." } ] } diff --git a/refactor/tasks.json b/refactor/tasks.json index a137f8aeb..cb7fc8470 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -3570,11 +3570,14 @@ "PKG-MB-08", "CORE-22" ], - "status": "todo", + "status": "doing", "risk": "H", "deliverable": "跨浏览器能力、长播放、DPiP、HLS 音轨/质量报告", "acceptance": "资源释放、事件顺序、AV sync 与支持范围满足基线", - "evidence": [] + "evidence": [ + "changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md", + "baselines/mb-native-pip-checkpoint.json" + ] }, { "id": "PKG-MB-10", diff --git a/test/browser/mediabunny-dpip.spec.js b/test/browser/mediabunny-dpip.spec.js new file mode 100644 index 000000000..0a6edaa20 --- /dev/null +++ b/test/browser/mediabunny-dpip.spec.js @@ -0,0 +1,113 @@ +import assert from 'node:assert/strict' +import fs from 'node:fs' +import { hash } from '../../refactor/scripts/releases.mjs' +import { dpipCandidate } from '../helpers/dpip.js' +import { mbCandidate } from '../helpers/mediabunny.js' +import { expect, test } from './fixtures.js' + +const implementation = await mbCandidate() +const dpip = await dpipCandidate() +const manifest = JSON.parse(fs.readFileSync(new URL('./media/hls/manifest.json', import.meta.url))) +const hls = new Map(Object.entries(manifest.files).map(([name, expected]) => { + const bytes = fs.readFileSync(new URL(`./media/hls/${name}`, import.meta.url)) + assert.equal(hash(bytes), expected.sha256) + return [name, bytes] +})) +for (const core of ['published', 'candidate']) { + for (const media of ['video', 'hls']) { + for (const ending of ['close', 'native-close', 'destroy']) { + test(`MediaBunny ${implementation.name}: ${core} core native Document PiP ${media} ${ending}`, async ({ page, browserName }, testInfo) => { + await page.route('**/mb-dpip-hls/**', async (route) => { + const name = new URL(route.request().url()).pathname.split('/').at(-1) + const body = hls.get(name) + await route.fulfill({ status: body ? 200 : 404, body: body || 'Missing fixture', contentType: name.endsWith('.m3u8') ? 'application/vnd.apple.mpegurl' : 'video/mp2t' }) + }) + await page.goto(`/test/player.html?core=${core}`) + const supported = await page.evaluate(() => typeof window.documentPictureInPicture?.requestWindow === 'function') + if (!supported) { + await testInfo.attach('mediabunny-dpip', { contentType: 'application/json', body: JSON.stringify({ core, media, ending, implementation: implementation.name, sha256: hash(implementation.code), dpipSha256: hash(dpip.code), outcome: 'native-document-pip-unavailable', browserName, supported }) }) + return + } + for (const [code, global] of [[implementation.code, 'mbFactory'], [dpip.code, 'dpipFactory']]) { + await page.addScriptTag({ content: `(() => { const module = { exports: {} }; const exports = module.exports; ${code}; window.${global} = module.exports.default || module.exports; })();` }) + } + await page.evaluate((media) => { + window.mbDraws = 0 + window.mbPipEvents = [] + window.art = new window.Artplayer({ container: '.player', url: media === 'video' ? '/test/pattern.mp4' : '/mb-dpip-hls/master.m3u8', muted: true, proxy: window.mbFactory(), plugins: [window.dpipFactory({ fallbackToVideoPiP: false })] }) + window.mbCanvas = window.art.video + window.mbPlayer = window.art.template.$player + window.mbParent = window.mbPlayer.parentNode + window.mbPip = window.art.plugins.artplayerPluginDocumentPip + window.art.on('document-pip', value => window.mbPipEvents.push(value)) + const ctx = window.mbCanvas.getContext('2d') + const draw = ctx.drawImage.bind(ctx) + ctx.drawImage = (...args) => { + window.mbDraws++ + return draw(...args) + } + document.querySelector('#play').onclick = () => window.art.play() + const button = document.createElement('button') + button.id = 'open-native-pip' + button.textContent = 'Open native Document PiP' + button.onclick = () => { + window.mbOpening = window.mbPip.open() + } + document.body.append(button) + }, media) + let result + try { + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.click('#play') + await expect.poll(() => page.evaluate(() => window.mbCanvas.currentTime)).toBeGreaterThan(0.1) + await page.click('#open-native-pip') + await page.evaluate(() => window.mbOpening) + expect(await page.evaluate(() => window.mbPip.isActive)).toBe(true) + const before = await page.evaluate(() => ({ time: window.mbCanvas.currentTime, draws: window.mbDraws, adopted: window.mbPlayer.ownerDocument === window.documentPictureInPicture.window.document, sameCanvas: window.mbCanvas === window.art.video, distinctWindow: window.documentPictureInPicture.window !== window, openerVisibility: document.visibilityState })) + expect(before.adopted).toBe(true) + expect(before.sameCanvas).toBe(true) + expect(before.distinctWindow).toBe(true) + await expect.poll(() => page.evaluate(() => window.mbDraws)).toBeGreaterThan(before.draws + 2) + await expect.poll(() => page.evaluate(() => window.mbCanvas.currentTime)).toBeGreaterThan(before.time + 0.15) + if (media === 'hls') { + await expect.poll(() => page.evaluate(() => window.mbCanvas.engine.audio.queuedNodes.size)).toBeGreaterThan(0) + if (ending === 'close') { + await page.evaluate(async () => { + const state = await window.mbCanvas.getM3u8State() + await window.mbCanvas.switchM3u8Quality(state.levels.find(level => level.height === 90).id) + const next = await window.mbCanvas.getM3u8State() + await window.mbCanvas.switchM3u8Audio(next.audios.find(audio => audio.lang === 'fr').id) + }) + expect(await page.evaluate(async () => { + const state = await window.mbCanvas.getM3u8State() + return { height: state.currentLevel.height, language: state.currentAudio.lang, adopted: window.mbCanvas.ownerDocument === window.documentPictureInPicture.window.document } + })).toEqual({ height: 90, language: 'fr', adopted: true }) + } + } + if (ending !== 'destroy') { + if (ending === 'native-close') + await page.evaluate(() => window.documentPictureInPicture.window.close()) + else await page.evaluate(() => window.mbPip.close()) + await expect.poll(() => page.evaluate(() => window.mbPip.isActive)).toBe(false) + expect(await page.evaluate(() => window.mbPlayer.parentNode === window.mbParent && window.mbPlayer.ownerDocument === document && window.mbCanvas === window.art.video)).toBe(true) + } + else { + await page.evaluate(() => window.art.destroy(false)) + await expect.poll(() => page.evaluate(() => window.mbPip.isActive)).toBe(false) + expect(await page.evaluate(() => window.mbCanvas.engine.destroyed)).toBe(true) + } + result = await page.evaluate(() => ({ events: window.mbPipEvents, placeholders: document.querySelectorAll('.artplayer-document-pip-placeholder').length, nativeWindowClosed: !window.documentPictureInPicture.window || window.documentPictureInPicture.window.closed })) + expect(result).toEqual({ events: ending === 'destroy' ? [true] : [true, false], placeholders: 0, nativeWindowClosed: true }) + await testInfo.attach('mediabunny-dpip', { contentType: 'application/json', body: JSON.stringify({ core, media, ending, implementation: implementation.name, sha256: hash(implementation.code), dpipSha256: hash(dpip.code), outcome: 'native-document-pip-canvas-playback', before, result, scope: 'Actual requestWindow from a click, no iframe or API replacement; native Canvas decoding and window lifecycle. HLS includes native audio, and close cases change quality/audio inside PiP.' }) }) + } + finally { + await page.evaluate(() => { + if (!window.art.isDestroy) + window.art.destroy(false) + window.documentPictureInPicture.window?.close() + }) + } + }) + } + } +}