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()
+ })
+ }
+ })
+ }
+ }
+}