diff --git a/docs/assets/ts/artplayer-plugin-hls-control.d.ts b/docs/assets/ts/artplayer-plugin-hls-control.d.ts index f047513e8..03360e3f9 100644 --- a/docs/assets/ts/artplayer-plugin-hls-control.d.ts +++ b/docs/assets/ts/artplayer-plugin-hls-control.d.ts @@ -1,17 +1,43 @@ -interface Config { - control?: boolean - setting?: boolean - title?: string - auto?: string - getName?: (level: object) => string +// Generated from the package public declaration by yarn build:ts. Do not edit. +/* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */ +declare namespace artplayerPluginHlsControlDefinitions { + export interface QualityLevel { + height: number + name?: string + } + export interface AudioTrack { + id: number + name: string + lang?: string + language?: string + } + export interface Config { + control?: boolean + setting?: boolean + title?: string + auto?: string + /** Plain callback; current-label calls omit index. SDK objects retain their identity. */ + getName?: (item: Item, index?: number) => string + } + export interface Option { + quality?: Config + audio?: Config + } + export interface Result { + name: 'artplayerPluginHlsControl' + update: () => void + } + export function artplayerPluginHlsControl(option?: Option): (art: Artplayer) => Result + // Keep the required last signature for historical Parameters[0] consumers. + export function artplayerPluginHlsControl(option: Option): (art: Artplayer) => Result } - -declare const artplayerPluginHlsControl: (option: { quality?: Config, audio?: Config }) => (art: Artplayer) => { - name: 'artplayerPluginHlsControl' - update: () => void +declare const artplayerPluginHlsControl: typeof artplayerPluginHlsControlDefinitions.artplayerPluginHlsControl +declare namespace artplayerPluginHlsControl { + export type QualityLevel = artplayerPluginHlsControlDefinitions.QualityLevel + export type AudioTrack = artplayerPluginHlsControlDefinitions.AudioTrack + export type Config = artplayerPluginHlsControlDefinitions.Config + export type Option = artplayerPluginHlsControlDefinitions.Option + export type Result = artplayerPluginHlsControlDefinitions.Result } - -export default artplayerPluginHlsControl - export = artplayerPluginHlsControl export as namespace artplayerPluginHlsControl; diff --git a/docs/compiled/artplayer-plugin-hls-control.js b/docs/compiled/artplayer-plugin-hls-control.js index 176558e93..6cb978e5d 100644 --- a/docs/compiled/artplayer-plugin-hls-control.js +++ b/docs/compiled/artplayer-plugin-hls-control.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,n,l,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&l(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&g?.hls===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&l(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:n,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return n=>{const{$video:l}=n.template,{errorHandle:i}=n.constructor.utils;let r,c,s=!1,u=0,a=()=>{},f=0;const d=new WeakSet,h=t=>!s&&!d.has(t)&&n.hls===t&&t.media===l,m=e(n,"hls-quality","currentLevel",'',h,v),g=e(n,"hls-audio","audioTrack",'',h,v);function v(t){f++;let e=!1;try{const o=t();return e=!0,o}finally{if(f--,!f){const t=c;c=void 0,e&&t&&p(t,!1)}}}function p(e,n){if(!h(e))return;const l=++u,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?l(r):n,s=t(e.levels.map((t,e)=>({html:l(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:n,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!h(e)||l!==u)return;if(m.update(e,i,r,n),!h(e)||l!==u)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?l(i):n,c=t(e.audioTracks.map((t,o)=>({html:l(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);h(e)&&l===u&&g.update(e,c,s,n)}function y(){if(s)return;const t=n.hls;if(i(t?.media===l,'Cannot find instance of HLS from "art.hls"'),!d.has(t)){if(r!==t){a(),r=t;try{a=function(t,e,o){const n=t.constructor?.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const l=[];let i=!0;function r(){if(i){i=!1;for(const[e,o]of l)t.off(e,o);l.length=0}}try{for(const r of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const c=n[r];if("string"!==typeof c||l.some(([t])=>t===c))continue;const s=()=>{i&&("DESTROYING"===r?o():e())};l.push([c,s]),t.on(c,s)}}catch(c){throw r(),c}return r}(t,()=>{f?c=t:p(t,!1)},()=>{d.add(t),a(),r===t&&(r=void 0,s||(m.clear(),g.clear()))})}catch(e){throw r=void 0,e}}p(t,!0)}}return n.on("ready",y),n.on("restart",y),n.on("destroy",function t(){s||(s=!0,u++,c=void 0,m.invalidate(),g.invalidate(),a(),n.off("ready",y),n.off("restart",y),n.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:y}}}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,n,l,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&l(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&g?.hls===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&l(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:n,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return n=>{const l=n,{$video:i}=l.template,{errorHandle:r}=l.constructor.utils;let c,s,u=!1,a=0,f=()=>{},d=0;const h=new WeakSet,m=t=>!u&&!h.has(t)&&l.hls===t&&t.media===i,g=e(l,"hls-quality","currentLevel",'',m,p),v=e(l,"hls-audio","audioTrack",'',m,p);function p(t){d++;let e=!1;try{const o=t();return e=!0,o}finally{if(d--,!d){const t=s;s=void 0,e&&t&&y(t,!1)}}}function y(e,n){if(!m(e))return;const l=++a,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?l(r):n,s=t(e.levels.map((t,e)=>({html:l(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:n,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!m(e)||l!==a)return;if(g.update(e,i,r,n),!m(e)||l!==a)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?l(i):n,c=t(e.audioTracks.map((t,o)=>({html:l(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);m(e)&&l===a&&v.update(e,c,s,n)}function T(){if(u)return;const t=l.hls;if(r(t?.media===i,'Cannot find instance of HLS from "art.hls"'),!h.has(t)){if(c!==t){f(),c=t;try{f=function(t,e,o){const n=t.constructor?.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const l=t,i=[];let r=!0;function c(){if(r){r=!1;for(const[t,e]of i)l.off(t,e);i.length=0}}try{for(const t of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const c=n[t];if("string"!==typeof c||i.some(([t])=>t===c))continue;const s=()=>{r&&("DESTROYING"===t?o():e())};i.push([c,s]),l.on(c,s)}}catch(s){throw c(),s}return c}(t,()=>{d?s=t:y(t,!1)},()=>{h.add(t),f(),c===t&&(c=void 0,u||(g.clear(),v.clear()))})}catch(e){throw c=void 0,e}}y(t,!0)}}return l.on("ready",T),l.on("restart",T),l.on("destroy",function t(){u||(u=!0,a++,s=void 0,g.invalidate(),v.invalidate(),f(),l.off("ready",T),l.off("restart",T),l.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:T}}}}); diff --git a/docs/compiled/artplayer-plugin-hls-control.legacy.js b/docs/compiled/artplayer-plugin-hls-control.legacy.js index 56bf50dd2..1e53f1cde 100644 --- a/docs/compiled/artplayer-plugin-hls-control.legacy.js +++ b/docs/compiled/artplayer-plugin-hls-control.legacy.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,l,n,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&n(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&(null==g?void 0:g.hls)===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&n(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:l,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return l=>{const{$video:n}=l.template,{errorHandle:i}=l.constructor.utils;let r,c,s=!1,u=0,a=()=>{},f=0;const d=new WeakSet,h=t=>!s&&!d.has(t)&&l.hls===t&&t.media===n,m=e(l,"hls-quality","currentLevel",'',h,v),g=e(l,"hls-audio","audioTrack",'',h,v);function v(t){f++;let e=!1;try{const o=t();return e=!0,o}finally{if(f--,!f){const t=c;c=void 0,e&&t&&p(t,!1)}}}function p(e,l){if(!h(e))return;const n=++u,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?n(r):l,s=t(e.levels.map((t,e)=>({html:n(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:l,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!h(e)||n!==u)return;if(m.update(e,i,r,l),!h(e)||n!==u)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?n(i):l,c=t(e.audioTracks.map((t,o)=>({html:n(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);h(e)&&n===u&&g.update(e,c,s,l)}function y(){if(s)return;const t=l.hls;if(i((null==t?void 0:t.media)===n,'Cannot find instance of HLS from "art.hls"'),!d.has(t)){if(r!==t){a(),r=t;try{a=function(t,e,o){var l;const n=null==(l=t.constructor)?void 0:l.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const i=[];let r=!0;function c(){if(r){r=!1;for(const[e,o]of i)t.off(e,o);i.length=0}}try{for(const l of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const c=n[l];if("string"!==typeof c||i.some(([t])=>t===c))continue;const s=()=>{r&&("DESTROYING"===l?o():e())};i.push([c,s]),t.on(c,s)}}catch(s){throw c(),s}return c}(t,()=>{f?c=t:p(t,!1)},()=>{d.add(t),a(),r===t&&(r=void 0,s||(m.clear(),g.clear()))})}catch(e){throw r=void 0,e}}p(t,!0)}}return l.on("ready",y),l.on("restart",y),l.on("destroy",function t(){s||(s=!0,u++,c=void 0,m.invalidate(),g.invalidate(),a(),l.off("ready",y),l.off("restart",y),l.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:y}}}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,l,n,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&n(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&(null==g?void 0:g.hls)===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&n(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:l,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return l=>{const n=l,{$video:i}=n.template,{errorHandle:r}=n.constructor.utils;let c,s,u=!1,a=0,f=()=>{},d=0;const h=new WeakSet,m=t=>!u&&!h.has(t)&&n.hls===t&&t.media===i,g=e(n,"hls-quality","currentLevel",'',m,p),v=e(n,"hls-audio","audioTrack",'',m,p);function p(t){d++;let e=!1;try{const o=t();return e=!0,o}finally{if(d--,!d){const t=s;s=void 0,e&&t&&y(t,!1)}}}function y(e,l){if(!m(e))return;const n=++a,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?n(r):l,s=t(e.levels.map((t,e)=>({html:n(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:l,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!m(e)||n!==a)return;if(g.update(e,i,r,l),!m(e)||n!==a)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?n(i):l,c=t(e.audioTracks.map((t,o)=>({html:n(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);m(e)&&n===a&&v.update(e,c,s,l)}function T(){if(u)return;const t=n.hls;if(r((null==t?void 0:t.media)===i,'Cannot find instance of HLS from "art.hls"'),!h.has(t)){if(c!==t){f(),c=t;try{f=function(t,e,o){var l;const n=null==(l=t.constructor)?void 0:l.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const i=t,r=[];let c=!0;function s(){if(c){c=!1;for(const[t,e]of r)i.off(t,e);r.length=0}}try{for(const t of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const l=n[t];if("string"!==typeof l||r.some(([t])=>t===l))continue;const s=()=>{c&&("DESTROYING"===t?o():e())};r.push([l,s]),i.on(l,s)}}catch(u){throw s(),u}return s}(t,()=>{d?s=t:y(t,!1)},()=>{h.add(t),f(),c===t&&(c=void 0,u||(g.clear(),v.clear()))})}catch(e){throw c=void 0,e}}y(t,!0)}}return n.on("ready",T),n.on("restart",T),n.on("destroy",function t(){u||(u=!0,a++,s=void 0,g.invalidate(),v.invalidate(),f(),n.off("ready",T),n.off("restart",T),n.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:T}}}}); diff --git a/docs/compiled/artplayer-plugin-hls-control.mjs b/docs/compiled/artplayer-plugin-hls-control.mjs index fa68a04f7..a31dc0596 100644 --- a/docs/compiled/artplayer-plugin-hls-control.mjs +++ b/docs/compiled/artplayer-plugin-hls-control.mjs @@ -129,6 +129,7 @@ function subscribeHls(hls, refresh, destroyed) { if (!events || typeof hls.on !== "function" || typeof hls.off !== "function") return () => { }; + const source = hls; const subscriptions = []; let active = true; function release() { @@ -136,7 +137,7 @@ function subscribeHls(hls, refresh, destroyed) { return; active = false; for (const [event, callback] of subscriptions) - hls.off(event, callback); + source.off(event, callback); subscriptions.length = 0; } try { @@ -153,7 +154,7 @@ function subscribeHls(hls, refresh, destroyed) { refresh(); }; subscriptions.push([event, callback]); - hls.on(event, callback); + source.on(event, callback); } } catch (error) { release(); @@ -162,7 +163,8 @@ function subscribeHls(hls, refresh, destroyed) { return release; } function artplayerPluginHlsControl(option = {}) { - return (art) => { + return (player) => { + const art = player; const { $video } = art.template; const { errorHandle } = art.constructor.utils; let closed = false; diff --git a/packages/artplayer-plugin-hls-control/ARCHITECTURE.md b/packages/artplayer-plugin-hls-control/ARCHITECTURE.md index 697f12c55..c7e3b1525 100644 --- a/packages/artplayer-plugin-hls-control/ARCHITECTURE.md +++ b/packages/artplayer-plugin-hls-control/ARCHITECTURE.md @@ -1,21 +1,48 @@ # HLS control maintenance -The public entry remains `src/index.js`: `artplayerPluginHlsControl(option = {})` returns a +The source entry is `src/index.ts`: `artplayerPluginHlsControl(option = {})` returns a synchronous ArtPlayer plugin with `{ name: 'artplayerPluginHlsControl', update }`. `update()` returns undefined. The consumer creates, attaches and destroys `art.hls`; this plugin does not -import Hls.js or own its media engine. Public declarations are still in `types/` pending the -separate TypeScript migration (PKG-HLS-04). +import Hls.js or own its media engine. Public declarations are authored in `types/`; implementation +imports their configuration/result types so there is one public contract. All five self-owned +modules are strict TypeScript, with unchecked indexed access enabled and no emitted compiler files. | Module | Responsibility | | --- | --- | -| `src/index.js` | Core ready/restart/destroy hooks, current engine identity, refresh generation, selection event barrier | -| `src/mapping.js` | Quality/audio labels, duplicate groups, selected item and Auto policy; no ArtPlayer/DOM dependencies | -| `src/menu.js` | Existing controls/setting update/remove/check APIs, current callback ownership and stable menu reuse | -| `src/sdk-events.js` | Optional SDK event capabilities, six subscriptions, setup rollback and listener release | +| `src/index.ts` | Core ready/restart/destroy hooks, current engine identity, refresh generation, selection event barrier | +| `src/mapping.ts` | Quality/audio labels, duplicate groups, selected item and Auto policy; no ArtPlayer/DOM dependencies | +| `src/menu.ts` | Existing controls/setting update/remove/check APIs, current callback ownership and stable menu reuse | +| `src/sdk-events.ts` | Optional SDK event capabilities, six subscriptions, setup rollback and listener release | +| `src/types.ts` | Internal SDK capabilities, menu models and the narrow host surface; no runtime code | The entry depends on these three modules; they do not import the entry or each other. SVG icons remain local build inputs. There is no cross-instance cache, timer, worker or fetch. +## Public types and editor generation + +`types/artplayer-plugin-hls-control.d.ts` retains the historical path and TS 4.3.5 syntax. +Conditional `.d.cts`/`.d.mts` bridges preserve callable CommonJS/default ESM imports and named types; +legacy keeps the same JavaScript file and adds a `typesVersions` fallback for older resolution. +Do not change these runtime paths or add a runtime dependency on the Hls SDK to obtain its types. + +Default `QualityLevel`/`AudioTrack` fields provide useful formatter inference. `Option` +also accepts caller-supplied SDK types, including inference from an annotated callback. A formatter +still accepts the original object and optional index, returns a string and runs as a plain callback. +The optional factory overload permits omitted/undefined configuration. The required last overload +deliberately preserves old `Parameters[0]['quality']` consumers; +do not remove it as redundant. `update()` stays synchronous and returns void. + +The single ArtPlayer-to-Host assertion represents the externally attached SDK surface. `update` +still uses the historical errorHandle/media identity guard. The SDK subscription assertion follows +actual on/off function checks; guarded selector indices follow an equal-length check. These limited +boundaries are not proof that arbitrary external objects implement Hls. Keep runtime contract tests. + +`scripts/plugin-editor-types.mjs` generates the HLS Monaco declaration from the authored public file. +It creates private definitions plus a callable global/named-type bridge, rejecting unsupported +imports/exports. `yarn build:ts` semantically checks that output with both compilers before writing it; +never hand-edit `docs/assets/ts/artplayer-plugin-hls-control.d.ts`. The generic defaults and both +overloads must survive generation. Other unconverted plugins still use their existing generator path. + ## Refresh and selection Registration does not require an Hls instance yet. The first ready/restart/manual update checks @@ -65,8 +92,11 @@ Use the repository's pinned Node and Yarn: ```sh node --test test/hls-control.test.js +node --test refactor/scripts/hls-types.test.mjs yarn test:browser hls-control.spec.js +yarn test:browser hls-editor-types.spec.js yarn build artplayer-plugin-hls-control +yarn build:ts yarn ci:check ``` @@ -79,3 +109,8 @@ Windows Playwright WebKit lacks MSE; explicit capability/error cleanup runs ther cases are marked skipped. Safari/native HLS, SDK workers, grouped track changes, SDK version range, updated example and isolated package verification remain PKG-HLS-05/06 work. See [refactor validation](../../refactor/hls-validation.md). Keep these gaps visible in release reviews. + +Actual Hls.js 1.5.17 declaration consumers pass TS 5.9.3. TS 4.3.5 reports two existing SDK DOM type +errors (MediaDecodingConfiguration and MediaCapabilitiesDecodingInfo), reproduced with the SDK alone. +The plugin introduces no additional errors; do not hide those SDK diagnostics with skipLibCheck or +claim every SDK/compiler combination passes. Standalone plugin consumers pass both compilers. diff --git a/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.js b/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.js index 176558e93..6cb978e5d 100644 --- a/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.js +++ b/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,n,l,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&l(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&g?.hls===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&l(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:n,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return n=>{const{$video:l}=n.template,{errorHandle:i}=n.constructor.utils;let r,c,s=!1,u=0,a=()=>{},f=0;const d=new WeakSet,h=t=>!s&&!d.has(t)&&n.hls===t&&t.media===l,m=e(n,"hls-quality","currentLevel",'',h,v),g=e(n,"hls-audio","audioTrack",'',h,v);function v(t){f++;let e=!1;try{const o=t();return e=!0,o}finally{if(f--,!f){const t=c;c=void 0,e&&t&&p(t,!1)}}}function p(e,n){if(!h(e))return;const l=++u,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?l(r):n,s=t(e.levels.map((t,e)=>({html:l(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:n,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!h(e)||l!==u)return;if(m.update(e,i,r,n),!h(e)||l!==u)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?l(i):n,c=t(e.audioTracks.map((t,o)=>({html:l(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);h(e)&&l===u&&g.update(e,c,s,n)}function y(){if(s)return;const t=n.hls;if(i(t?.media===l,'Cannot find instance of HLS from "art.hls"'),!d.has(t)){if(r!==t){a(),r=t;try{a=function(t,e,o){const n=t.constructor?.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const l=[];let i=!0;function r(){if(i){i=!1;for(const[e,o]of l)t.off(e,o);l.length=0}}try{for(const r of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const c=n[r];if("string"!==typeof c||l.some(([t])=>t===c))continue;const s=()=>{i&&("DESTROYING"===r?o():e())};l.push([c,s]),t.on(c,s)}}catch(c){throw r(),c}return r}(t,()=>{f?c=t:p(t,!1)},()=>{d.add(t),a(),r===t&&(r=void 0,s||(m.clear(),g.clear()))})}catch(e){throw r=void 0,e}}p(t,!0)}}return n.on("ready",y),n.on("restart",y),n.on("destroy",function t(){s||(s=!0,u++,c=void 0,m.invalidate(),g.invalidate(),a(),n.off("ready",y),n.off("restart",y),n.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:y}}}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,n,l,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&l(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&g?.hls===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&l(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:n,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return n=>{const l=n,{$video:i}=l.template,{errorHandle:r}=l.constructor.utils;let c,s,u=!1,a=0,f=()=>{},d=0;const h=new WeakSet,m=t=>!u&&!h.has(t)&&l.hls===t&&t.media===i,g=e(l,"hls-quality","currentLevel",'',m,p),v=e(l,"hls-audio","audioTrack",'',m,p);function p(t){d++;let e=!1;try{const o=t();return e=!0,o}finally{if(d--,!d){const t=s;s=void 0,e&&t&&y(t,!1)}}}function y(e,n){if(!m(e))return;const l=++a,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?l(r):n,s=t(e.levels.map((t,e)=>({html:l(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:n,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!m(e)||l!==a)return;if(g.update(e,i,r,n),!m(e)||l!==a)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const n=o.auto||"Auto",l=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?l(i):n,c=t(e.audioTracks.map((t,o)=>({html:l(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);m(e)&&l===a&&v.update(e,c,s,n)}function T(){if(u)return;const t=l.hls;if(r(t?.media===i,'Cannot find instance of HLS from "art.hls"'),!h.has(t)){if(c!==t){f(),c=t;try{f=function(t,e,o){const n=t.constructor?.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const l=t,i=[];let r=!0;function c(){if(r){r=!1;for(const[t,e]of i)l.off(t,e);i.length=0}}try{for(const t of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const c=n[t];if("string"!==typeof c||i.some(([t])=>t===c))continue;const s=()=>{r&&("DESTROYING"===t?o():e())};i.push([c,s]),l.on(c,s)}}catch(s){throw c(),s}return c}(t,()=>{d?s=t:y(t,!1)},()=>{h.add(t),f(),c===t&&(c=void 0,u||(g.clear(),v.clear()))})}catch(e){throw c=void 0,e}}y(t,!0)}}return l.on("ready",T),l.on("restart",T),l.on("destroy",function t(){u||(u=!0,a++,s=void 0,g.invalidate(),v.invalidate(),f(),l.off("ready",T),l.off("restart",T),l.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:T}}}}); diff --git a/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.legacy.js b/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.legacy.js index 56bf50dd2..1e53f1cde 100644 --- a/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.legacy.js +++ b/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.legacy.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,l,n,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&n(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&(null==g?void 0:g.hls)===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&n(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:l,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return l=>{const{$video:n}=l.template,{errorHandle:i}=l.constructor.utils;let r,c,s=!1,u=0,a=()=>{},f=0;const d=new WeakSet,h=t=>!s&&!d.has(t)&&l.hls===t&&t.media===n,m=e(l,"hls-quality","currentLevel",'',h,v),g=e(l,"hls-audio","audioTrack",'',h,v);function v(t){f++;let e=!1;try{const o=t();return e=!0,o}finally{if(f--,!f){const t=c;c=void 0,e&&t&&p(t,!1)}}}function p(e,l){if(!h(e))return;const n=++u,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?n(r):l,s=t(e.levels.map((t,e)=>({html:n(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:l,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!h(e)||n!==u)return;if(m.update(e,i,r,l),!h(e)||n!==u)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?n(i):l,c=t(e.audioTracks.map((t,o)=>({html:n(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);h(e)&&n===u&&g.update(e,c,s,l)}function y(){if(s)return;const t=l.hls;if(i((null==t?void 0:t.media)===n,'Cannot find instance of HLS from "art.hls"'),!d.has(t)){if(r!==t){a(),r=t;try{a=function(t,e,o){var l;const n=null==(l=t.constructor)?void 0:l.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const i=[];let r=!0;function c(){if(r){r=!1;for(const[e,o]of i)t.off(e,o);i.length=0}}try{for(const l of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const c=n[l];if("string"!==typeof c||i.some(([t])=>t===c))continue;const s=()=>{r&&("DESTROYING"===l?o():e())};i.push([c,s]),t.on(c,s)}}catch(s){throw c(),s}return c}(t,()=>{f?c=t:p(t,!1)},()=>{d.add(t),a(),r===t&&(r=void 0,s||(m.clear(),g.clear()))})}catch(e){throw r=void 0,e}}p(t,!0)}}return l.on("ready",y),l.on("restart",y),l.on("destroy",function t(){s||(s=!0,u++,c=void 0,m.invalidate(),g.invalidate(),a(),l.off("ready",y),l.off("restart",y),l.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:y}}}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginHlsControl=e(),define(function(){return t.artplayerPluginHlsControl})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginHlsControl=e()}(this,function(){"use strict";function t(t){const e=new Map;return t.filter(t=>{if(void 0===t.html)return!0;const o=e.get(t.html);return o?(t.default&&(o.default=!0,o.value=t.value),!1):(e.set(t.html,t),!0)})}function e(t,e,o,l,n,i){let r;const c={control:!1,setting:!1};function s(o){c[o]&&(c[o]=!1,t["control"===o?"controls":"setting"].remove(e))}function u(){r=void 0,s("control"),s("setting")}function a(e,o){for(const t of e.model.selector)t.default=t===o;e.config.control&&t.controls.check(o),e===r&&n(e.hls)&&e.config.setting&&t.setting.check(o)}return{update:function(f,d,h,m){if(!h)return void u();const g=r,v=h.selector.findIndex(t=>t.default);if(!m&&(null==g?void 0:g.hls)===f&&g.model.title===h.title&&(-1!==v||!g.model.selector.some(t=>t.default)&&g.model.html===h.html)&&c.control===Boolean(d.control)&&c.setting===Boolean(d.setting)&&g.model.selector.length===h.selector.length&&g.model.selector.every((t,e)=>t.html===h.selector[e].html&&t.value===h.selector[e].value)){g.config=d;const t=g.model.selector[v];return void(!t||t.default&&g.model.html===h.html||(g.model.html=h.html,a(g,t)))}const p={hls:f,config:d,model:h};r=p;const y=()=>r===p&&n(f),T=e=>i(()=>y()?(f[o]=e.value,y()?(h.html=e.html,t.notice.show=`${h.title}: ${e.html}`,y()&&a(p,e),e.html):e.html):e.html);d.control?(c.control=!0,t.controls.update({name:e,position:"right",html:h.html,style:{padding:"0 10px"},selector:h.selector,onSelect:T})):s("control"),y()&&(d.setting?(c.setting=!0,t.setting.update({name:e,tooltip:h.html,html:h.title,icon:l,width:200,selector:h.selector,onSelect:T})):s("setting"))},clear:u,invalidate:function(){r=void 0}}}return function(o={}){return l=>{const n=l,{$video:i}=n.template,{errorHandle:r}=n.constructor.utils;let c,s,u=!1,a=0,f=()=>{},d=0;const h=new WeakSet,m=t=>!u&&!h.has(t)&&n.hls===t&&t.media===i,g=e(n,"hls-quality","currentLevel",'',m,p),v=e(n,"hls-audio","audioTrack",'',m,p);function p(t){d++;let e=!1;try{const o=t();return e=!0,o}finally{if(d--,!d){const t=s;s=void 0,e&&t&&y(t,!1)}}}function y(e,l){if(!m(e))return;const n=++a,i=o.quality||{},r=function(e,o){if(!e.levels.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||`${t.height}P`),i=function(t){return!0===t.autoLevelEnabled?-1:t.currentLevel}(e),r=e.levels[i],c=r?n(r):l,s=t(e.levels.map((t,e)=>({html:n(t,e),value:e,default:i===e}))).sort((t,e)=>e.value-t.value);return s.push({html:l,value:-1,default:-1===i}),{html:c,title:o.title||"Quality",selector:s}}(e,i);if(!m(e)||n!==a)return;if(g.update(e,i,r,l),!m(e)||n!==a)return;const c=o.audio||{},s=function(e,o){if(!e.audioTracks.length)return null;const l=o.auto||"Auto",n=o.getName||(t=>t.name||t.lang||t.language),i=e.audioTracks[e.audioTrack],r=i?n(i):l,c=t(e.audioTracks.map((t,o)=>({html:n(t,o),value:t.id,default:e.audioTrack===t.id})));return{html:r,title:o.title||"Audio",selector:c}}(e,c);m(e)&&n===a&&v.update(e,c,s,l)}function T(){if(u)return;const t=n.hls;if(r((null==t?void 0:t.media)===i,'Cannot find instance of HLS from "art.hls"'),!h.has(t)){if(c!==t){f(),c=t;try{f=function(t,e,o){var l;const n=null==(l=t.constructor)?void 0:l.Events;if(!n||"function"!==typeof t.on||"function"!==typeof t.off)return()=>{};const i=t,r=[];let c=!0;function s(){if(c){c=!1;for(const[t,e]of r)i.off(t,e);r.length=0}}try{for(const t of["MANIFEST_PARSED","LEVELS_UPDATED","LEVEL_SWITCHED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHED","DESTROYING"]){const l=n[t];if("string"!==typeof l||r.some(([t])=>t===l))continue;const s=()=>{c&&("DESTROYING"===t?o():e())};r.push([l,s]),i.on(l,s)}}catch(u){throw s(),u}return s}(t,()=>{d?s=t:y(t,!1)},()=>{h.add(t),f(),c===t&&(c=void 0,u||(g.clear(),v.clear()))})}catch(e){throw c=void 0,e}}y(t,!0)}}return n.on("ready",T),n.on("restart",T),n.on("destroy",function t(){u||(u=!0,a++,s=void 0,g.invalidate(),v.invalidate(),f(),n.off("ready",T),n.off("restart",T),n.off("destroy",t))}),{name:"artplayerPluginHlsControl",update:T}}}}); diff --git a/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.mjs b/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.mjs index fa68a04f7..a31dc0596 100644 --- a/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.mjs +++ b/packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.mjs @@ -129,6 +129,7 @@ function subscribeHls(hls, refresh, destroyed) { if (!events || typeof hls.on !== "function" || typeof hls.off !== "function") return () => { }; + const source = hls; const subscriptions = []; let active = true; function release() { @@ -136,7 +137,7 @@ function subscribeHls(hls, refresh, destroyed) { return; active = false; for (const [event, callback] of subscriptions) - hls.off(event, callback); + source.off(event, callback); subscriptions.length = 0; } try { @@ -153,7 +154,7 @@ function subscribeHls(hls, refresh, destroyed) { refresh(); }; subscriptions.push([event, callback]); - hls.on(event, callback); + source.on(event, callback); } } catch (error) { release(); @@ -162,7 +163,8 @@ function subscribeHls(hls, refresh, destroyed) { return release; } function artplayerPluginHlsControl(option = {}) { - return (art) => { + return (player) => { + const art = player; const { $video } = art.template; const { errorHandle } = art.constructor.utils; let closed = false; diff --git a/packages/artplayer-plugin-hls-control/package.json b/packages/artplayer-plugin-hls-control/package.json index 4f660f8b3..cfa076b00 100644 --- a/packages/artplayer-plugin-hls-control/package.json +++ b/packages/artplayer-plugin-hls-control/package.json @@ -19,19 +19,36 @@ ], "exports": { ".": { - "types": "./types/artplayer-plugin-hls-control.d.ts", - "import": "./dist/artplayer-plugin-hls-control.mjs", - "require": "./dist/artplayer-plugin-hls-control.js" + "import": { + "types": "./types/artplayer-plugin-hls-control.d.mts", + "default": "./dist/artplayer-plugin-hls-control.mjs" + }, + "require": { + "types": "./types/artplayer-plugin-hls-control.d.cts", + "default": "./dist/artplayer-plugin-hls-control.js" + } }, "./legacy": { - "types": "./types/artplayer-plugin-hls-control.d.ts", - "import": "./dist/artplayer-plugin-hls-control.legacy.js", - "require": "./dist/artplayer-plugin-hls-control.legacy.js" + "import": { + "types": "./types/artplayer-plugin-hls-control.d.cts", + "default": "./dist/artplayer-plugin-hls-control.legacy.js" + }, + "require": { + "types": "./types/artplayer-plugin-hls-control.d.cts", + "default": "./dist/artplayer-plugin-hls-control.legacy.js" + } } }, "main": "./dist/artplayer-plugin-hls-control.js", "module": "./dist/artplayer-plugin-hls-control.mjs", "types": "./types/artplayer-plugin-hls-control.d.ts", "legacy": "./dist/artplayer-plugin-hls-control.legacy.js", - "browserslist": "last 1 Chrome version" + "browserslist": "last 1 Chrome version", + "typesVersions": { + "*": { + "legacy": [ + "types/artplayer-plugin-hls-control.d.ts" + ] + } + } } diff --git a/packages/artplayer-plugin-hls-control/src/index.js b/packages/artplayer-plugin-hls-control/src/index.ts similarity index 73% rename from packages/artplayer-plugin-hls-control/src/index.js rename to packages/artplayer-plugin-hls-control/src/index.ts index db43a43b4..a0e76a2e0 100644 --- a/packages/artplayer-plugin-hls-control/src/index.js +++ b/packages/artplayer-plugin-hls-control/src/index.ts @@ -1,25 +1,30 @@ +import type Artplayer from 'artplayer' +import type { AudioTrack, Option, QualityLevel, Result } from '../types/artplayer-plugin-hls-control' +import type { Cleanup, Hls, Host } from './types' import $audio from './audio.svg?raw' import { audioModel, qualityModel } from './mapping' import { createMenu } from './menu' import $quality from './quality.svg?raw' import { subscribeHls } from './sdk-events' -export default function artplayerPluginHlsControl(option = {}) { - return (art) => { +export default function artplayerPluginHlsControl(option: Option = {}) { + return (player: Artplayer): Result => { + // The consumer owns the optional SDK; update validates its media identity before use. + const art = player as unknown as Host const { $video } = art.template const { errorHandle } = art.constructor.utils let closed = false let revision = 0 - let engine - let unsubscribe = () => {} + let engine: Hls | undefined + let unsubscribe: Cleanup = () => {} let selecting = 0 - let pending + let pending: Hls | undefined const retired = new WeakSet() - const active = hls => !closed && !retired.has(hls) && art.hls === hls && hls.media === $video + const active = (hls: Hls) => !closed && !retired.has(hls) && art.hls === hls && hls.media === $video const quality = createMenu(art, 'hls-quality', 'currentLevel', $quality, active, select) const audio = createMenu(art, 'hls-audio', 'audioTrack', $audio, active, select) - function select(callback) { + function select(callback: () => T): T { selecting++ let succeeded = false try { @@ -38,7 +43,7 @@ export default function artplayerPluginHlsControl(option = {}) { } } - function refresh(hls, force) { + function refresh(hls: Hls, force: boolean): void { if (!active(hls)) return const version = ++revision @@ -55,10 +60,10 @@ export default function artplayerPluginHlsControl(option = {}) { audio.update(hls, audioConfig, audioView, force) } - function update() { + function update(): void { if (closed) return - const hls = art.hls + const hls = art.hls! errorHandle(hls?.media === $video, 'Cannot find instance of HLS from "art.hls"') if (retired.has(hls)) return @@ -91,7 +96,7 @@ export default function artplayerPluginHlsControl(option = {}) { refresh(hls, true) } - function destroy() { + function destroy(): void { if (closed) return closed = true diff --git a/packages/artplayer-plugin-hls-control/src/mapping.js b/packages/artplayer-plugin-hls-control/src/mapping.ts similarity index 59% rename from packages/artplayer-plugin-hls-control/src/mapping.js rename to packages/artplayer-plugin-hls-control/src/mapping.ts index c3f0cc611..73f793cac 100644 --- a/packages/artplayer-plugin-hls-control/src/mapping.js +++ b/packages/artplayer-plugin-hls-control/src/mapping.ts @@ -1,5 +1,8 @@ -function uniqueLabels(items) { - const seen = new Map() +import type { Config } from '../types/artplayer-plugin-hls-control' +import type { AudioFields, Hls, LevelFields, MenuModel, SelectorItem } from './types' + +function uniqueLabels(items: SelectorItem[]): SelectorItem[] { + const seen = new Map() return items.filter((item) => { if (item.html === undefined) return true @@ -16,15 +19,15 @@ function uniqueLabels(items) { }) } -export function qualitySelection(hls) { +export function qualitySelection(hls: Pick): number { return hls.autoLevelEnabled === true ? -1 : hls.currentLevel } -export function qualityModel(hls, config) { +export function qualityModel(hls: Pick, 'levels' | 'currentLevel' | 'autoLevelEnabled'>, config: Config): MenuModel | null { if (!hls.levels.length) return null const auto = config.auto || 'Auto' - const getName = config.getName || (level => level.name || `${level.height}P`) + const getName = config.getName || ((level: LevelFields) => level.name || `${level.height}P`) const selected = qualitySelection(hls) const level = hls.levels[selected] const html = level ? getName(level) : auto @@ -34,11 +37,11 @@ export function qualityModel(hls, config) { return { html, title: config.title || 'Quality', selector } } -export function audioModel(hls, config) { +export function audioModel(hls: Pick, 'audioTracks' | 'audioTrack'>, config: Config): MenuModel | null { if (!hls.audioTracks.length) return null const auto = config.auto || 'Auto' - const getName = config.getName || (track => track.name || track.lang || track.language) + const getName = config.getName || ((track: AudioFields) => track.name || track.lang || track.language) const track = hls.audioTracks[hls.audioTrack] const html = track ? getName(track) : auto const selector = uniqueLabels(hls.audioTracks.map((item, index) => ({ html: getName(item, index), value: item.id, default: hls.audioTrack === item.id }))) diff --git a/packages/artplayer-plugin-hls-control/src/menu.js b/packages/artplayer-plugin-hls-control/src/menu.ts similarity index 72% rename from packages/artplayer-plugin-hls-control/src/menu.js rename to packages/artplayer-plugin-hls-control/src/menu.ts index 3abdb6f9a..1b32a54f1 100644 --- a/packages/artplayer-plugin-hls-control/src/menu.js +++ b/packages/artplayer-plugin-hls-control/src/menu.ts @@ -1,21 +1,23 @@ -export function createMenu(art, name, field, icon, active, select) { - let current +import type { DisplayConfig, MenuHost, MenuModel, MenuState, SelectorItem } from './types' + +export function createMenu(art: MenuHost, name: string, field: 'currentLevel' | 'audioTrack', icon: string, active: (hls: Engine) => boolean, select: (callback: () => T) => T) { + let current: MenuState | undefined const owned = { control: false, setting: false } - function remove(surface) { + function remove(surface: 'control' | 'setting'): void { if (!owned[surface]) return owned[surface] = false art[surface === 'control' ? 'controls' : 'setting'].remove(name) } - function clear() { + function clear(): void { current = undefined remove('control') remove('setting') } - function check(state, item) { + function check(state: MenuState, item: SelectorItem): void { for (const entry of state.model.selector) entry.default = entry === item if (state.config.control) @@ -26,18 +28,19 @@ export function createMenu(art, name, field, icon, active, select) { art.setting.check(item) } - function update(hls, config, model, force) { + function update(hls: Engine, config: DisplayConfig, model: MenuModel | null, force: boolean): void { if (!model) { clear() return } const previous = current const selectedIndex = model.selector.findIndex(item => item.default) + // Equal lengths below protect the same-index reads in the comparison. const reusable = !force && previous?.hls === hls && previous.model.title === model.title && (selectedIndex !== -1 || (!previous.model.selector.some(item => item.default) && previous.model.html === model.html)) && owned.control === Boolean(config.control) && owned.setting === Boolean(config.setting) && previous.model.selector.length === model.selector.length - && previous.model.selector.every((item, index) => item.html === model.selector[index].html && item.value === model.selector[index].value) + && previous.model.selector.every((item, index) => item.html === model.selector[index]!.html && item.value === model.selector[index]!.value) if (reusable) { previous.config = config const target = previous.model.selector[selectedIndex] @@ -50,7 +53,7 @@ export function createMenu(art, name, field, icon, active, select) { const state = { hls, config, model } current = state const valid = () => current === state && active(hls) - const onSelect = item => select(() => { + const onSelect = (item: SelectorItem) => select(() => { if (!valid()) return item.html hls[field] = item.value @@ -80,7 +83,7 @@ export function createMenu(art, name, field, icon, active, select) { } } - function invalidate() { + function invalidate(): void { current = undefined } return { update, clear, invalidate } diff --git a/packages/artplayer-plugin-hls-control/src/sdk-events.js b/packages/artplayer-plugin-hls-control/src/sdk-events.ts similarity index 64% rename from packages/artplayer-plugin-hls-control/src/sdk-events.js rename to packages/artplayer-plugin-hls-control/src/sdk-events.ts index fb7c156a6..b9faf9695 100644 --- a/packages/artplayer-plugin-hls-control/src/sdk-events.js +++ b/packages/artplayer-plugin-hls-control/src/sdk-events.ts @@ -1,19 +1,23 @@ -export function subscribeHls(hls, refresh, destroyed) { +import type { Cleanup, Hls, SdkEvent } from './types' + +export function subscribeHls(hls: Hls, refresh: Cleanup, destroyed: Cleanup): Cleanup { const events = hls.constructor?.Events if (!events || typeof hls.on !== 'function' || typeof hls.off !== 'function') return () => {} - const subscriptions = [] + // Keep the checked SDK object so method calls retain their original receiver. + const source = hls as Hls & Required> + const subscriptions: [string, Cleanup][] = [] let active = true - function release() { + function release(): void { if (!active) return active = false for (const [event, callback] of subscriptions) - hls.off(event, callback) + source.off(event, callback) subscriptions.length = 0 } try { - for (const key of ['MANIFEST_PARSED', 'LEVELS_UPDATED', 'LEVEL_SWITCHED', 'AUDIO_TRACKS_UPDATED', 'AUDIO_TRACK_SWITCHED', 'DESTROYING']) { + for (const key of ['MANIFEST_PARSED', 'LEVELS_UPDATED', 'LEVEL_SWITCHED', 'AUDIO_TRACKS_UPDATED', 'AUDIO_TRACK_SWITCHED', 'DESTROYING'] satisfies SdkEvent[]) { const event = events[key] if (typeof event !== 'string' || subscriptions.some(([name]) => name === event)) continue @@ -26,7 +30,7 @@ export function subscribeHls(hls, refresh, destroyed) { refresh() } subscriptions.push([event, callback]) - hls.on(event, callback) + source.on(event, callback) } } catch (error) { diff --git a/packages/artplayer-plugin-hls-control/src/types.ts b/packages/artplayer-plugin-hls-control/src/types.ts new file mode 100644 index 000000000..c543c49cc --- /dev/null +++ b/packages/artplayer-plugin-hls-control/src/types.ts @@ -0,0 +1,79 @@ +import type { Config } from '../types/artplayer-plugin-hls-control' + +export interface LevelFields { + height?: number + name?: string +} + +export interface AudioFields { + id: number + name?: string + lang?: string + language?: string +} + +export type SdkEvent = 'MANIFEST_PARSED' | 'LEVELS_UPDATED' | 'LEVEL_SWITCHED' | 'AUDIO_TRACKS_UPDATED' | 'AUDIO_TRACK_SWITCHED' | 'DESTROYING' +export type Cleanup = () => void + +export interface Hls { + media: object | null + levels: (Level & LevelFields)[] + audioTracks: (Track & AudioFields)[] + currentLevel: number + audioTrack: number + autoLevelEnabled?: boolean + constructor?: { Events?: Partial> } + on?: (event: string, callback: Cleanup) => unknown + off?: (event: string, callback: Cleanup) => unknown +} + +export interface SelectorItem { + html: string | undefined + value: number + default: boolean +} + +export interface MenuModel { + html: string | undefined + title: string + selector: SelectorItem[] +} + +export interface MenuOption { + name: string + html: string | undefined + selector: SelectorItem[] + onSelect: (item: SelectorItem) => string | undefined + position?: 'right' + style?: { padding: string } + tooltip?: string + icon?: string + width?: number +} + +export interface Registry { + update: (option: MenuOption) => unknown + remove: (name: string) => unknown + check: (item: SelectorItem) => unknown +} + +export interface MenuHost { + controls: Registry + setting: Registry + notice: { show: string } +} + +export interface Host extends MenuHost { + template: { $video: object } + constructor: { utils: { errorHandle: (condition: unknown, message: string) => void } } + hls?: Hls + on: (event: 'ready' | 'restart' | 'destroy', callback: Cleanup) => unknown + off: (event: 'ready' | 'restart' | 'destroy', callback: Cleanup) => unknown +} + +export type DisplayConfig = Pick +export interface MenuState { + hls: Engine + config: DisplayConfig + model: MenuModel +} diff --git a/packages/artplayer-plugin-hls-control/tsconfig.json b/packages/artplayer-plugin-hls-control/tsconfig.json new file mode 100644 index 000000000..bba301755 --- /dev/null +++ b/packages/artplayer-plugin-hls-control/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { "allowJs": false }, + "include": ["src/**/*.ts", "types/**/*.d.ts", "types/**/*.d.mts", "types/**/*.d.cts", "../../types/assets.d.ts"] +} diff --git a/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts b/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts new file mode 100644 index 000000000..a39464606 --- /dev/null +++ b/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts @@ -0,0 +1,14 @@ +/* eslint-disable ts/no-redeclare -- CommonJS callable export and named-type namespace intentionally merge. */ +import type * as Definition from './artplayer-plugin-hls-control.js' + +declare const artplayerPluginHlsControl: typeof Definition.default + +declare namespace artplayerPluginHlsControl { + type QualityLevel = Definition.QualityLevel + type AudioTrack = Definition.AudioTrack + type Config = Definition.Config + type Option = Definition.Option + type Result = Definition.Result +} + +export = artplayerPluginHlsControl diff --git a/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.mts b/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.mts new file mode 100644 index 000000000..1f351b4f5 --- /dev/null +++ b/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.mts @@ -0,0 +1,2 @@ +export { default } from './artplayer-plugin-hls-control.cjs' +export type { AudioTrack, Config, Option, QualityLevel, Result } from './artplayer-plugin-hls-control.js' diff --git a/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts b/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts index b5c3191ca..4f750138b 100644 --- a/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts +++ b/packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts @@ -1,16 +1,38 @@ import type Artplayer from 'artplayer' -interface Config { +export interface QualityLevel { + height: number + name?: string +} + +export interface AudioTrack { + id: number + name: string + lang?: string + language?: string +} + +export interface Config { control?: boolean setting?: boolean title?: string auto?: string - getName?: (level: object) => string + /** Plain callback; current-label calls omit index. SDK objects retain their identity. */ + getName?: (item: Item, index?: number) => string } -declare const artplayerPluginHlsControl: (option: { quality?: Config, audio?: Config }) => (art: Artplayer) => { +export interface Option { + quality?: Config + audio?: Config +} + +export interface Result { name: 'artplayerPluginHlsControl' update: () => void } +declare function artplayerPluginHlsControl(option?: Option): (art: Artplayer) => Result +// Keep the required last signature for historical Parameters[0] consumers. +declare function artplayerPluginHlsControl(option: Option): (art: Artplayer) => Result + export default artplayerPluginHlsControl diff --git a/refactor/baselines/hls-types-validation.json b/refactor/baselines/hls-types-validation.json new file mode 100644 index 000000000..117591572 --- /dev/null +++ b/refactor/baselines/hls-types-validation.json @@ -0,0 +1,4142 @@ +{ + "schemaVersion": 1, + "task": "PKG-HLS-04", + "capturedAt": "2026-09-11T16:48:04.864Z", + "sourceHashesLF": { + "packages/artplayer-plugin-hls-control/src/index.ts": "c7ab89b964c481870f5b59fba0be4cd17b7a8ddf59b5bc8c03504f4983d64015", + "packages/artplayer-plugin-hls-control/src/mapping.ts": "f517854a7825ab7783375438040602bcfeab16df0218998208dd9a3b8fe443e3", + "packages/artplayer-plugin-hls-control/src/menu.ts": "774c43ebdc86555a3518b3f74d226ac03cdf41035d8cf5dd0ab519b7b144d78b", + "packages/artplayer-plugin-hls-control/src/sdk-events.ts": "4d9ee92d0720601a2c55b597bf99e7ecaf851d5fd2292adff153c539f33e460a", + "packages/artplayer-plugin-hls-control/src/types.ts": "2b9c8927e4c16ab4ce486d63d2ee3fb781a01be8a5423643cabd1ec76b17f98c", + "packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts": "ad4c3e7f7d2ba6b8371108bf08dfa13cccf78a1add846ba53cab8774c8fff0b6", + "packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.mts": "27a3a17a48f0bc92c3c50783be253730d87d01e9be627ab2726bdc552fecf1f3", + "packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts": "8c2b9eca1dbc396089dea7276787916f8029ee8a68d73c5d2f78991571de918a", + "packages/artplayer-plugin-hls-control/package.json": "084bb4aea8dfce9880b062f2cf5e89b1fc94a9b403e835505631aea0e1816014", + "packages/artplayer-plugin-hls-control/tsconfig.json": "583e4ac1afa99e3a29c7f899df9fdeefcbd14d3847d69143e3fa6a8facac6d99", + "scripts/plugin-editor-types.mjs": "a01e9b64df5ee5df00ab06e95f4e8483ae88194549456a75ec77ef934b9711b1", + "scripts/build-ts.js": "7bd574d7d6c98f416036b3de2c0342ce99fa3637b795102fc96719334b7798cb", + "scripts/typecheck.mjs": "d813da915edf5ce1d4e551779b3d1d32b440d3ff42e24d6114dcc79249dc825c", + "test/types/hls-control.ts": "3bbdeae926b6a5aad6e5b7c34a21babbc7784007c49d65acc44dac0962ba2b61", + "test/types/hls-source.ts": "4dfb36411352ecda0c857f5d24e5587f6d0c7723078ca3d6eb29aec687e9f4ae", + "refactor/scripts/hls-types.test.mjs": "0c046ab51841c2d3bbf63c45251668e639305bb559b166afbc578f98306bfe01", + "test/hls-control.test.js": "739fbccdf143ce11b07dc88cc313c9eba985e9ef6ac2991bc046f56c9f6644aa", + "test/helpers/hls-control.js": "72dcc20c9af6155a401d882716f91cffe598ebf357ccef2d4654476d3f71a87d", + "test/browser/hls-control.spec.js": "3e3f841b1b84ef0d2622be3389af570641a5ccc443fc4dff0995036867ec745a", + "test/browser/hls-editor-types.spec.js": "b5a993b04cbc531019ce216d7e12b898602c6b492e0b4855f4be1d66e64546f3", + "test/browser/editor-types.spec.js": "11303e272c1a5202ffc1c192ddc70ef3e988c9ec78b4d4dd4936c3c8a7b6636f", + "docs/assets/ts/artplayer-plugin-hls-control.d.ts": "6a623bb6ba4cc0598a3dd1aab5ef7ca4fbae11973a787885eccba10cc7aa2c7c" + }, + "artifacts": { + "artplayer-plugin-hls-control.js": { + "sha256": "8e163d4ab6734cbc45e7f539de7db644c7faf36d0318469a86d300bf6365cca6", + "bytes": 5266, + "gzip9": 2539 + }, + "artplayer-plugin-hls-control.legacy.js": { + "sha256": "fd7be1c5bf8f994b61fc040ff96eb628fc442568d99f4b5fee4f611bac1d28c0", + "bytes": 5322, + "gzip9": 2564 + }, + "artplayer-plugin-hls-control.mjs": { + "sha256": "64286498c1e90c3927236318383db193698a9dcbf39f91e93fc2b4ea2239e786", + "bytes": 9649, + "gzip9": 3117 + } + }, + "unit": { + "passed": 56, + "failed": 0, + "note": "Source and published contracts; included in full CI." + }, + "artifactUnit": { + "passed": 83, + "failed": 0, + "logSHA256": "54598a9e89e6c5189c1542c2e056947116f8fad27c6ea28956fb44114b43027f", + "note": "27 shared cases on three build outputs plus source/published cases. Candidate fixes additionally exercise source." + }, + "types": { + "modes": [ + "TS 5.9.3 Node10 CJS", + "TS 5.9.3 NodeNext CJS", + "TS 5.9.3 NodeNext ESM", + "TS 5.9.3 Bundler ESM", + "TS 4.3.5 Node10 CJS" + ], + "invalidCasesPerMode": 8, + "editorInvalidCasesPerCompiler": 3, + "actualSdk": "hls.js@1.5.17", + "sdkOnlyDiagnosticsTS43": [ + "2304: MediaDecodingConfiguration", + "2304: MediaCapabilitiesDecodingInfo" + ], + "sdkPluginAdditionalDiagnosticsTS43": 0, + "sdkDiagnosticsTS59": 0, + "skipLibCheck": false + }, + "ci": { + "file": "refactor/.cache/hls04-ci-first.log", + "sha256": "cb8488cbf7777fa9ff124a498b36e957d3427bd643a71e84135bbe0cd13454c6", + "passed": 536, + "unit": 496, + "engineering": 11, + "baseline": 29, + "productionTsFiles": 254 + }, + "modern": { + "file": "refactor/.cache/hls04-browser-main.json", + "sha256": "c7d1d2c1dced277c4c7b10882c8564c27d4a8dbc23558da593e2c08693d12e4e", + "stats": { + "startTime": "2026-09-11T16:44:14.931Z", + "duration": 32144.009, + "expected": 35, + "skipped": 16, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "SDK MSE availability is explicit; unavailable hosts report failure and clean up", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 634, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "SDK MSE availability is explicit; unavailable hosts report failure and clean up", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 2093, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "96e0ec1fa6d1118cbc977e2e1923cd5b2ba6fa38bf3c52519388e2825669e53e" + } + ] + }, + { + "title": "SDK MSE availability is explicit; unavailable hosts report failure and clean up", + "project": "webkit", + "status": "passed", + "retry": 0, + "duration": 831, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "ed52a1c05792a324fcfaae83cd2ab5c7fb259a33de32ef2f777a98f92532031a" + } + ] + }, + { + "title": "published core / published HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6254, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / published HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 815, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "59759c765474b3064d656177ff3c21d7789816bbe6ed605015415000b399be6f" + } + ] + }, + { + "title": "published core / published HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 913, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6184, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / candidate HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 891, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "59759c765474b3064d656177ff3c21d7789816bbe6ed605015415000b399be6f" + } + ] + }, + { + "title": "published core / candidate HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1369, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / published HLS: real Auto playback loses Auto label on update", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 876, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1044, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "candidate core / published HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6222, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / published HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 933, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "3939f1f1cc372ce680ac4a1cb8ce5be4e2b6cdb5511f854162d9dae3e7f4ae61" + } + ] + }, + { + "title": "candidate core / published HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 947, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6376, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / candidate HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 905, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "3939f1f1cc372ce680ac4a1cb8ce5be4e2b6cdb5511f854162d9dae3e7f4ae61" + } + ] + }, + { + "title": "candidate core / candidate HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 906, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / published HLS: real Auto playback loses Auto label on update", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 892, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1107, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "published core / published HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 4637, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / published HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1187, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / published HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1317, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 4497, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1121, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 2731, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / published HLS: real Auto playback loses Auto label on update", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1118, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1367, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "candidate core / published HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 4771, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / published HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1115, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / published HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1199, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 5734, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1111, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1243, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / published HLS: real Auto playback loses Auto label on update", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1205, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1431, + "attachments": [ + { + "name": "hls-inputs", + "input": "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "published core / published HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / published HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / published HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / published HLS: real Auto playback loses Auto label on update", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: real Auto playback loses Auto label on update", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + } + ] + }, + "legacy": { + "file": "refactor/.cache/hls04-browser-legacy.json", + "sha256": "ac3409531db0efcf12ba3e400edc6939512d210cefcc43a14dc1427113890202", + "stats": { + "startTime": "2026-09-11T16:46:19.165Z", + "duration": 30268.66, + "expected": 35, + "skipped": 16, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "SDK MSE availability is explicit; unavailable hosts report failure and clean up", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 547, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "SDK MSE availability is explicit; unavailable hosts report failure and clean up", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1834, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "SDK MSE availability is explicit; unavailable hosts report failure and clean up", + "project": "webkit", + "status": "passed", + "retry": 0, + "duration": 808, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "ed52a1c05792a324fcfaae83cd2ab5c7fb259a33de32ef2f777a98f92532031a" + } + ] + }, + { + "title": "published core / published HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 5984, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / published HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 796, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "59759c765474b3064d656177ff3c21d7789816bbe6ed605015415000b399be6f" + } + ] + }, + { + "title": "published core / published HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 883, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6084, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / candidate HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 774, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "59759c765474b3064d656177ff3c21d7789816bbe6ed605015415000b399be6f" + } + ] + }, + { + "title": "published core / candidate HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1278, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / published HLS: real Auto playback loses Auto label on update", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 853, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "published core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1010, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e" + } + ] + }, + { + "title": "candidate core / published HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6079, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / published HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 825, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "3939f1f1cc372ce680ac4a1cb8ce5be4e2b6cdb5511f854162d9dae3e7f4ae61" + } + ] + }, + { + "title": "candidate core / published HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 865, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 6543, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / candidate HLS: failed manifest and actual SDK teardown", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 796, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "3939f1f1cc372ce680ac4a1cb8ce5be4e2b6cdb5511f854162d9dae3e7f4ae61" + } + ] + }, + { + "title": "candidate core / candidate HLS: source switch drops SDK audio topology", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 881, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / published HLS: real Auto playback loses Auto label on update", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 859, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "candidate core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1053, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f" + } + ] + }, + { + "title": "published core / published HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 4586, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / published HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1041, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / published HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1131, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 4454, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1025, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 2145, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / published HLS: real Auto playback loses Auto label on update", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1104, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "published core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1345, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539" + } + ] + }, + { + "title": "candidate core / published HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 4381, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / published HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1006, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / published HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1310, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 5456, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: failed manifest and actual SDK teardown", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 966, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: source switch drops SDK audio topology", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1112, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / published HLS: real Auto playback loses Auto label on update", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1044, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "candidate core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 1319, + "attachments": [ + { + "name": "hls-inputs", + "input": "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8" + }, + { + "name": "browser-evidence", + "input": "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093" + } + ] + }, + { + "title": "published core / published HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / published HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / published HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / published HLS: real Auto playback loses Auto label on update", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "published core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: real decoding, manual quality, Auto and audio", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: failed manifest and actual SDK teardown", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: source switch drops SDK audio topology", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / published HLS: real Auto playback loses Auto label on update", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + }, + { + "title": "candidate core / candidate HLS: SDK events synchronize Auto and audio without replacing menus", + "project": "webkit", + "status": "skipped", + "retry": 0, + "duration": 0, + "attachments": [] + } + ] + }, + "monaco": { + "file": "refactor/.cache/hls04-monaco-final.json", + "sha256": "157c47a54f18fb39ee96961b99af4a4b7b0f59999e5d182ce3fc6d7bce51197b", + "stats": { + "startTime": "2026-09-11T16:43:37.613Z", + "duration": 8328.449, + "expected": 6, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1039, + "attachments": [ + { + "name": "browser-evidence", + "input": "4290e89254b177a31e1c085101d2459dffcd4384a201a6a1202bbc8bc5201200" + } + ] + }, + { + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 2394, + "attachments": [ + { + "name": "browser-evidence", + "input": "d9a3332c97cc3b82c36c2ffc494bd6499d2c06e9fd82912f2b1c460c5e51f251" + } + ] + }, + { + "title": "docs Monaco worker consumes generated core types and runs a typed player example", + "project": "webkit", + "status": "passed", + "retry": 0, + "duration": 2127, + "attachments": [ + { + "name": "browser-evidence", + "input": "fe50cfbecf70e60baf0c3dda4759bca3830a253b35bc4cf6a45b406c6ed987a4" + } + ] + }, + { + "title": "Monaco consumes HLS global types and executes the emitted plugin factory", + "project": "chromium", + "status": "passed", + "retry": 0, + "duration": 1035, + "attachments": [ + { + "name": "hls-editor-inputs", + "input": "a8d84b45095c17e8e1cda75049ccfdaa4fccf406dec37fbdc3a1f02765e7559f" + }, + { + "name": "browser-evidence", + "input": "2099348494e4b73b55967af9bbcbc963fef7469eae5946e2ba6a4b2eb7d34b89" + } + ] + }, + { + "title": "Monaco consumes HLS global types and executes the emitted plugin factory", + "project": "firefox", + "status": "passed", + "retry": 0, + "duration": 2475, + "attachments": [ + { + "name": "hls-editor-inputs", + "input": "a8d84b45095c17e8e1cda75049ccfdaa4fccf406dec37fbdc3a1f02765e7559f" + }, + { + "name": "browser-evidence", + "input": "d9a3332c97cc3b82c36c2ffc494bd6499d2c06e9fd82912f2b1c460c5e51f251" + } + ] + }, + { + "title": "Monaco consumes HLS global types and executes the emitted plugin factory", + "project": "webkit", + "status": "passed", + "retry": 0, + "duration": 1316, + "attachments": [ + { + "name": "hls-editor-inputs", + "input": "a8d84b45095c17e8e1cda75049ccfdaa4fccf406dec37fbdc3a1f02765e7559f" + }, + { + "name": "browser-evidence", + "input": "fe50cfbecf70e60baf0c3dda4759bca3830a253b35bc4cf6a45b406c6ed987a4" + } + ] + } + ] + }, + "inputs": { + "201cb21d8a5e1a78a8f21d9c67bdfa354970e40a443d3989f37263f277b511ca": { + "sdk": { + "name": "hls.js", + "version": "1.5.17", + "tarball": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.17.tgz", + "integrity": "sha512-wA66nnYFvQa1o4DO/BFgLNRKnBTVXpNeldGRBJ2Y0SvFtdwvFKCbqa9zhHoZLoxHhZ+jYsj3aIBkWQQCPNOhMw==", + "sha256": "8f9e60001992f59dbfb1dbc397e145743c41bb6dde233ec8a7974013c8a031fe", + "files": { + "package/package.json": "f2172b9942a23ffb46edd4af815cf1ea161db088e7f63dc518d30e55c95d6ae9", + "package/LICENSE": "ca8773cf798c7ed997d4dd7c8e23c348699f8d5b7462636694cc14de6cda12db", + "package/dist/hls.min.js": "484054e8cd03d3f6d1781fb7f402bdc318d8a4c527f933a95c624e27cc9a9470", + "package/src/hls.ts": "b3d3f797669e89bc8d05d2de2aae243ae110811d6738948f173d789cc1ac1f2d", + "package/src/controller/audio-track-controller.ts": "ff34f3cb29b66aa5fcba87758bb20d129b052a053808c150ce779e0ceb1e4626" + } + }, + "plugin": { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "metadataUrl": "https://registry.npmjs.org/artplayer-plugin-hls-control/1.1.0", + "tarball": "https://registry.npmjs.org/artplayer-plugin-hls-control/-/artplayer-plugin-hls-control-1.1.0.tgz", + "integrity": "sha512-lWN5oUOWDorWFHdzKcmy9Z8eHcf5f5EcUGDrxBsZBX7aEL5dGRlHPQ5+wqQEizr38D9PYPfTI/nCyun2yFopEw==", + "sha256": "598c354d78d3cb77965136fa61dfc0f94cdea6906a91a30781c1acef2b0c3e8b", + "archiveBytes": 3192, + "registryGitHead": "daf133b22630b4a0eecfa3336bbddab0e9119d96", + "files": { + "package/README.md": "42bd00dca467b581f6b3e8399ad1a416d68edcc52d42e6cb51b66f1749694556", + "package/dist/artplayer-plugin-hls-control.js": "7a6ce18a0b16f61f6149e0ea77efbb6e0503f997d39afe84271b59e366759e6d", + "package/dist/artplayer-plugin-hls-control.legacy.js": "893a3de27f9ed02b4b61f03732aec03bfcaf50d02c9beb15cc8a5767ef9121a0", + "package/dist/artplayer-plugin-hls-control.mjs": "85c4de4940e031d835b4de3ccf68af449d10aec4f630c89ecaf62f5503348931", + "package/package.json": "710ec2a27dc71f7254e7a1d2eb7cff3f56a6e23811047ac97356f1b18c8ac8b5", + "package/types/artplayer-plugin-hls-control.d.ts": "7dd8fdf556932e9cf6140b7513c05155cad6d486e2484bf06c6d48f6e823832a" + }, + "manifest": { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "description": "Hls control plugin for ArtPlayer", + "author": "Harvey Zhao ", + "license": "MIT", + "homepage": "https://artplayer.org", + "repository": { + "type": "git", + "url": "git+https://github.com/zhw2590582/ArtPlayer.git" + }, + "bugs": { + "url": "https://github.com/zhw2590582/ArtPlayer/issues" + }, + "keywords": [ + "html5", + "video", + "player" + ], + "exports": { + ".": { + "types": "./types/artplayer-plugin-hls-control.d.ts", + "import": "./dist/artplayer-plugin-hls-control.mjs", + "require": "./dist/artplayer-plugin-hls-control.js" + }, + "./legacy": { + "types": "./types/artplayer-plugin-hls-control.d.ts", + "import": "./dist/artplayer-plugin-hls-control.legacy.js", + "require": "./dist/artplayer-plugin-hls-control.legacy.js" + } + }, + "main": "./dist/artplayer-plugin-hls-control.js", + "module": "./dist/artplayer-plugin-hls-control.mjs", + "types": "./types/artplayer-plugin-hls-control.d.ts", + "legacy": "./dist/artplayer-plugin-hls-control.legacy.js", + "browserslist": "last 1 Chrome version" + } + }, + "sourceSHA256": "8e163d4ab6734cbc45e7f539de7db644c7faf36d0318469a86d300bf6365cca6", + "candidate": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-hls-control\\dist\\artplayer-plugin-hls-control.js", + "media": { + "kind": "generated-hls-media", + "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers", + "duration": 12, + "commands": [ + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "testsrc2=size=160x90:rate=24", + "-t", + "12", + "-an", + "-c:v", + "libx264", + "-pix_fmt", + "yuv420p", + "-profile:v", + "baseline", + "-level:v", + "3.0", + "-g", + "48", + "-keyint_min", + "48", + "-sc_threshold", + "0", + "-crf", + "28", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "low-%02d.mpegts", + "low.m3u8" + ], + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "testsrc2=size=320x180:rate=24", + "-t", + "12", + "-an", + "-c:v", + "libx264", + "-pix_fmt", + "yuv420p", + "-profile:v", + "baseline", + "-level:v", + "3.0", + "-g", + "48", + "-keyint_min", + "48", + "-sc_threshold", + "0", + "-crf", + "28", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "high-%02d.mpegts", + "high.m3u8" + ], + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "sine=frequency=440:sample_rate=48000", + "-t", + "12", + "-vn", + "-c:a", + "aac", + "-b:a", + "48k", + "-ac", + "2", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "english-%02d.mpegts", + "english.m3u8" + ], + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "sine=frequency=880:sample_rate=48000", + "-t", + "12", + "-vn", + "-c:a", + "aac", + "-b:a", + "48k", + "-ac", + "2", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "french-%02d.mpegts", + "french.m3u8" + ] + ], + "files": { + "english-00.mpegts": { + "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207", + "bytes": 13912 + }, + "english-01.mpegts": { + "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5", + "bytes": 14100 + }, + "english-02.mpegts": { + "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb", + "bytes": 14100 + }, + "english-03.mpegts": { + "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e", + "bytes": 13912 + }, + "english-04.mpegts": { + "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9", + "bytes": 14100 + }, + "english-05.mpegts": { + "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533", + "bytes": 14100 + }, + "english-06.mpegts": { + "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a", + "bytes": 752 + }, + "english.m3u8": { + "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21", + "bytes": 365 + }, + "french-00.mpegts": { + "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd", + "bytes": 13912 + }, + "french-01.mpegts": { + "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13", + "bytes": 14100 + }, + "french-02.mpegts": { + "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0", + "bytes": 14100 + }, + "french-03.mpegts": { + "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b", + "bytes": 13912 + }, + "french-04.mpegts": { + "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601", + "bytes": 14100 + }, + "french-05.mpegts": { + "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9", + "bytes": 14100 + }, + "french-06.mpegts": { + "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46", + "bytes": 752 + }, + "french.m3u8": { + "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e", + "bytes": 358 + }, + "high-00.mpegts": { + "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833", + "bytes": 45308 + }, + "high-01.mpegts": { + "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c", + "bytes": 52264 + }, + "high-02.mpegts": { + "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440", + "bytes": 48128 + }, + "high-03.mpegts": { + "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5", + "bytes": 54144 + }, + "high-04.mpegts": { + "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c", + "bytes": 47376 + }, + "high-05.mpegts": { + "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15", + "bytes": 48128 + }, + "high.m3u8": { + "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d", + "bytes": 311 + }, + "low-00.mpegts": { + "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62", + "bytes": 28952 + }, + "low-01.mpegts": { + "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507", + "bytes": 32900 + }, + "low-02.mpegts": { + "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2", + "bytes": 30268 + }, + "low-03.mpegts": { + "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b", + "bytes": 32336 + }, + "low-04.mpegts": { + "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af", + "bytes": 29704 + }, + "low-05.mpegts": { + "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45", + "bytes": 29516 + }, + "low.m3u8": { + "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f", + "bytes": 305 + }, + "master.m3u8": { + "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38", + "bytes": 470 + }, + "video-only.m3u8": { + "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc", + "bytes": 108 + } + } + }, + "limitations": [ + "SDK worker disabled", + "local deterministic media", + "not an isolated installed package", + "no physical device certification" + ] + }, + "2b340c9a3ff5bbe48f7408e1a3b3acd543e595923935285e9d9be7bb0b64002f": { + "browser": "153.0.8010.12", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "96e0ec1fa6d1118cbc977e2e1923cd5b2ba6fa38bf3c52519388e2825669e53e": { + "browser": "155.0", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/hls-fixture/english-06.mpegts", + "resourceType": "xhr", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ] + }, + "ed52a1c05792a324fcfaae83cd2ab5c7fb259a33de32ef2f777a98f92532031a": { + "browser": "26.6", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate", + "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", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "f470ec9452f6b0d34a5d6218653efda36d79165af0ddd80a6362058ad660e20e": { + "browser": "153.0.8010.12", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=published", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "59759c765474b3064d656177ff3c21d7789816bbe6ed605015415000b399be6f": { + "browser": "153.0.8010.12", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=published", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "media": null + }, + "errors": [], + "consoleErrors": [ + "Failed to load resource: the server responded with a status of 503 (Service Unavailable)" + ], + "failedRequests": [] + }, + "3939f1f1cc372ce680ac4a1cb8ce5be4e2b6cdb5511f854162d9dae3e7f4ae61": { + "browser": "153.0.8010.12", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "media": null + }, + "errors": [], + "consoleErrors": [ + "Failed to load resource: the server responded with a status of 503 (Service Unavailable)" + ], + "failedRequests": [] + }, + "32c5daa043d421f0ab0b12bf77e4c93e2f6e3af01dc6f24ee1cb8aba81a60539": { + "browser": "155.0", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=published", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "308bc2130df0010177ce72d1e9f115a17995597e2a206a4f5291bea0b7f33093": { + "browser": "155.0", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "7ac618fdfe9a835973a2f63aeaadf3fa5c3a5518f61cfbeae1e33bf67f2922b8": { + "sdk": { + "name": "hls.js", + "version": "1.5.17", + "tarball": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.17.tgz", + "integrity": "sha512-wA66nnYFvQa1o4DO/BFgLNRKnBTVXpNeldGRBJ2Y0SvFtdwvFKCbqa9zhHoZLoxHhZ+jYsj3aIBkWQQCPNOhMw==", + "sha256": "8f9e60001992f59dbfb1dbc397e145743c41bb6dde233ec8a7974013c8a031fe", + "files": { + "package/package.json": "f2172b9942a23ffb46edd4af815cf1ea161db088e7f63dc518d30e55c95d6ae9", + "package/LICENSE": "ca8773cf798c7ed997d4dd7c8e23c348699f8d5b7462636694cc14de6cda12db", + "package/dist/hls.min.js": "484054e8cd03d3f6d1781fb7f402bdc318d8a4c527f933a95c624e27cc9a9470", + "package/src/hls.ts": "b3d3f797669e89bc8d05d2de2aae243ae110811d6738948f173d789cc1ac1f2d", + "package/src/controller/audio-track-controller.ts": "ff34f3cb29b66aa5fcba87758bb20d129b052a053808c150ce779e0ceb1e4626" + } + }, + "plugin": { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "metadataUrl": "https://registry.npmjs.org/artplayer-plugin-hls-control/1.1.0", + "tarball": "https://registry.npmjs.org/artplayer-plugin-hls-control/-/artplayer-plugin-hls-control-1.1.0.tgz", + "integrity": "sha512-lWN5oUOWDorWFHdzKcmy9Z8eHcf5f5EcUGDrxBsZBX7aEL5dGRlHPQ5+wqQEizr38D9PYPfTI/nCyun2yFopEw==", + "sha256": "598c354d78d3cb77965136fa61dfc0f94cdea6906a91a30781c1acef2b0c3e8b", + "archiveBytes": 3192, + "registryGitHead": "daf133b22630b4a0eecfa3336bbddab0e9119d96", + "files": { + "package/README.md": "42bd00dca467b581f6b3e8399ad1a416d68edcc52d42e6cb51b66f1749694556", + "package/dist/artplayer-plugin-hls-control.js": "7a6ce18a0b16f61f6149e0ea77efbb6e0503f997d39afe84271b59e366759e6d", + "package/dist/artplayer-plugin-hls-control.legacy.js": "893a3de27f9ed02b4b61f03732aec03bfcaf50d02c9beb15cc8a5767ef9121a0", + "package/dist/artplayer-plugin-hls-control.mjs": "85c4de4940e031d835b4de3ccf68af449d10aec4f630c89ecaf62f5503348931", + "package/package.json": "710ec2a27dc71f7254e7a1d2eb7cff3f56a6e23811047ac97356f1b18c8ac8b5", + "package/types/artplayer-plugin-hls-control.d.ts": "7dd8fdf556932e9cf6140b7513c05155cad6d486e2484bf06c6d48f6e823832a" + }, + "manifest": { + "name": "artplayer-plugin-hls-control", + "version": "1.1.0", + "description": "Hls control plugin for ArtPlayer", + "author": "Harvey Zhao ", + "license": "MIT", + "homepage": "https://artplayer.org", + "repository": { + "type": "git", + "url": "git+https://github.com/zhw2590582/ArtPlayer.git" + }, + "bugs": { + "url": "https://github.com/zhw2590582/ArtPlayer/issues" + }, + "keywords": [ + "html5", + "video", + "player" + ], + "exports": { + ".": { + "types": "./types/artplayer-plugin-hls-control.d.ts", + "import": "./dist/artplayer-plugin-hls-control.mjs", + "require": "./dist/artplayer-plugin-hls-control.js" + }, + "./legacy": { + "types": "./types/artplayer-plugin-hls-control.d.ts", + "import": "./dist/artplayer-plugin-hls-control.legacy.js", + "require": "./dist/artplayer-plugin-hls-control.legacy.js" + } + }, + "main": "./dist/artplayer-plugin-hls-control.js", + "module": "./dist/artplayer-plugin-hls-control.mjs", + "types": "./types/artplayer-plugin-hls-control.d.ts", + "legacy": "./dist/artplayer-plugin-hls-control.legacy.js", + "browserslist": "last 1 Chrome version" + } + }, + "sourceSHA256": "fd7be1c5bf8f994b61fc040ff96eb628fc442568d99f4b5fee4f611bac1d28c0", + "candidate": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-hls-control\\dist\\artplayer-plugin-hls-control.legacy.js", + "media": { + "kind": "generated-hls-media", + "version": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers", + "duration": 12, + "commands": [ + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "testsrc2=size=160x90:rate=24", + "-t", + "12", + "-an", + "-c:v", + "libx264", + "-pix_fmt", + "yuv420p", + "-profile:v", + "baseline", + "-level:v", + "3.0", + "-g", + "48", + "-keyint_min", + "48", + "-sc_threshold", + "0", + "-crf", + "28", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "low-%02d.mpegts", + "low.m3u8" + ], + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "testsrc2=size=320x180:rate=24", + "-t", + "12", + "-an", + "-c:v", + "libx264", + "-pix_fmt", + "yuv420p", + "-profile:v", + "baseline", + "-level:v", + "3.0", + "-g", + "48", + "-keyint_min", + "48", + "-sc_threshold", + "0", + "-crf", + "28", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "high-%02d.mpegts", + "high.m3u8" + ], + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "sine=frequency=440:sample_rate=48000", + "-t", + "12", + "-vn", + "-c:a", + "aac", + "-b:a", + "48k", + "-ac", + "2", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "english-%02d.mpegts", + "english.m3u8" + ], + [ + "-hide_banner", + "-loglevel", + "error", + "-n", + "-f", + "lavfi", + "-i", + "sine=frequency=880:sample_rate=48000", + "-t", + "12", + "-vn", + "-c:a", + "aac", + "-b:a", + "48k", + "-ac", + "2", + "-f", + "hls", + "-hls_time", + "2", + "-hls_playlist_type", + "vod", + "-hls_segment_filename", + "french-%02d.mpegts", + "french.m3u8" + ] + ], + "files": { + "english-00.mpegts": { + "sha256": "cc599f7c270385e85c28f710a34c5bd90b09d4d27adb3b1e6af3de65584b8207", + "bytes": 13912 + }, + "english-01.mpegts": { + "sha256": "01b17c28defc8a8ebf4978c5236eb759d80521a1cb840898095c35dac420cec5", + "bytes": 14100 + }, + "english-02.mpegts": { + "sha256": "90751b8b5abedd6b2f2e4eb83ccd609098ec7f2901163aaebf977cb9a11c46eb", + "bytes": 14100 + }, + "english-03.mpegts": { + "sha256": "9b1d86b7b261df66dbdace4ef1e846796cd710ffb72b22fc69532c1fe7d1c55e", + "bytes": 13912 + }, + "english-04.mpegts": { + "sha256": "dbfddd4f997942dd0b912f4c8bdbc5c11ee2a3fc51ac67df48d3aed2756715b9", + "bytes": 14100 + }, + "english-05.mpegts": { + "sha256": "9b53790d4f50f172852b7d4ff51bdd4bedd39e4c7a1efbfe734edf7b9a68a533", + "bytes": 14100 + }, + "english-06.mpegts": { + "sha256": "50baaa5e9fe7ca49b22c4d0817c44103b3edc763aee7f1b17d22f796d4189d4a", + "bytes": 752 + }, + "english.m3u8": { + "sha256": "5aae9d117d458f65f7febae68555ea4e48b2055b4cfb123fb919e385a1edda21", + "bytes": 365 + }, + "french-00.mpegts": { + "sha256": "7278acd094bc7caeeeea424a2c11ac4285fc45a8becb6c8ec55068f295ae35cd", + "bytes": 13912 + }, + "french-01.mpegts": { + "sha256": "e9464d109e36a53d7f151442b544d47ce79324bbaa805e0a98f171621c9c7a13", + "bytes": 14100 + }, + "french-02.mpegts": { + "sha256": "3ac48cab6aac942950b59f79ac6bd950dcae425f14821b83b1b5bb72d6815eb0", + "bytes": 14100 + }, + "french-03.mpegts": { + "sha256": "906f2d8b1f29bb7d57240b145563bab975d8f7dfff78cebd1505b6d2a3feb43b", + "bytes": 13912 + }, + "french-04.mpegts": { + "sha256": "cbf82876118d41af254bdef51f6cd08d842e8c6edf53250667fad2b8088e3601", + "bytes": 14100 + }, + "french-05.mpegts": { + "sha256": "a91e564ec54d845837217c45b8e25b08fe208f2b5f97562f513baabd515427d9", + "bytes": 14100 + }, + "french-06.mpegts": { + "sha256": "2c8edc11b06bacf1e62c4db67594ce187aa93e0241012011ebcf587b64ccff46", + "bytes": 752 + }, + "french.m3u8": { + "sha256": "6f7fb3eacb944597fa3105cb6d708eac3a8dc413e1706a11b6fb0e631214634e", + "bytes": 358 + }, + "high-00.mpegts": { + "sha256": "c5a8faac85b0594818255117696dce43fda6b363df40e2f3ffc453bd236cc833", + "bytes": 45308 + }, + "high-01.mpegts": { + "sha256": "5714640c3f17d86c56036453dc17d45f871af63b461318c43527af3482f8661c", + "bytes": 52264 + }, + "high-02.mpegts": { + "sha256": "fea1cbfb199bc867a322c7a646d43594a1d0d1d23fa0bcb6e770f2669b489440", + "bytes": 48128 + }, + "high-03.mpegts": { + "sha256": "4a74a28e7ad6bc626358e32365a0b07df1da82c92753e28032983e22404958b5", + "bytes": 54144 + }, + "high-04.mpegts": { + "sha256": "d04889b3b996d3e79c12bc297f9577690d3ae4f4172cdc0484b584954dab789c", + "bytes": 47376 + }, + "high-05.mpegts": { + "sha256": "36ee0c64b8c3637d0e2282c611e9250650ac493440095fc2efbe9de1c54add15", + "bytes": 48128 + }, + "high.m3u8": { + "sha256": "672c0e8b99242be05b16fc747a00715b2c25579b1ecc1623c0579fa34f0cb11d", + "bytes": 311 + }, + "low-00.mpegts": { + "sha256": "cbd62f5f4641cbe188a15640139bea393b5927fce600ff7513ef9ade9b33fb62", + "bytes": 28952 + }, + "low-01.mpegts": { + "sha256": "f7821fba38c63f5d80daef21cdd3430880bdc9fd5f5adfa939ed6481106c2507", + "bytes": 32900 + }, + "low-02.mpegts": { + "sha256": "3dc93f9f0fd065678b01fc6c568c12350e9ab0b324d1e0fa0e9f77787da7e7d2", + "bytes": 30268 + }, + "low-03.mpegts": { + "sha256": "d94c8913f7fde98161550041287529b90a58d537d6083d4382540c5fce0b430b", + "bytes": 32336 + }, + "low-04.mpegts": { + "sha256": "11596c59b547c2ff23bbba1f70e15f061a3e87bbdc1f4f59daa9b5279a6003af", + "bytes": 29704 + }, + "low-05.mpegts": { + "sha256": "5c6ec25a69fdad73a23cfbc34f0f3c6d8abe44592650c92fa9110a38d6bd9e45", + "bytes": 29516 + }, + "low.m3u8": { + "sha256": "404a8d868ed2af3598269aee89caba0563c2805dac223fe4c00c9a9eda73554f", + "bytes": 305 + }, + "master.m3u8": { + "sha256": "f226bd38f3c76714ada2b5a6866ad1cb39b041023e4a18d971d175f26f917e38", + "bytes": 470 + }, + "video-only.m3u8": { + "sha256": "3d7bb9069f6218191dc65745389bf1ab0ba6d5ed66cbd14e2cf30211913da3fc", + "bytes": 108 + } + } + }, + "limitations": [ + "SDK worker disabled", + "local deterministic media", + "not an isolated installed package", + "no physical device certification" + ] + }, + "4290e89254b177a31e1c085101d2459dffcd4384a201a6a1202bbc8bc5201200": { + "browser": "153.0.8010.12", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate&chapter=published", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ] + }, + "d9a3332c97cc3b82c36c2ffc494bd6499d2c06e9fd82912f2b1c460c5e51f251": { + "browser": "155.0", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate&chapter=published", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "fe50cfbecf70e60baf0c3dda4759bca3830a253b35bc4cf6a45b406c6ed987a4": { + "browser": "26.6", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate&chapter=published", + "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", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + "a8d84b45095c17e8e1cda75049ccfdaa4fccf406dec37fbdc3a1f02765e7559f": { + "candidate": "D:\\github\\ArtPlayer\\packages\\artplayer-plugin-hls-control\\dist\\artplayer-plugin-hls-control.js", + "sha256": "8e163d4ab6734cbc45e7f539de7db644c7faf36d0318469a86d300bf6365cca6", + "declarations": { + "artplayer": "652c0fdf605e87203526777a05851bd69c95c1660d5ff29eab19c00967c9a985", + "artplayer-plugin-hls-control": "6a623bb6ba4cc0598a3dd1aab5ef7ca4fbae11973a787885eccba10cc7aa2c7c" + } + }, + "2099348494e4b73b55967af9bbcbc963fef7469eae5946e2ba6a4b2eb7d34b89": { + "browser": "153.0.8010.12", + "platform": "win32", + "manifest": { + "kind": "artplayer-browser-test", + "resources": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744 + }, + "/compiled/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/uncompiled/artplayer/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "32f3dc22e296dcc569dc1227f0b0cad92bd0dd7e74d747e19759ac5997443e92", + "bytes": 376744, + "aliasOf": "/candidate/artplayer.js" + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/compiled/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/uncompiled/artplayer-plugin-chapter/index.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433, + "aliasOf": "/candidate/artplayer-plugin-chapter.js" + }, + "/published/artplayer.js": { + "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 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + }, + "/test/pattern.mp4": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.mp4" + }, + "sha256": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "bytes": 251538 + }, + "/test/pattern.webm": { + "source": { + "kind": "generated-media", + "file": "test/browser/media/pattern.webm" + }, + "sha256": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "bytes": 162073 + }, + "/test/declaration-cues.vtt": { + "source": { + "kind": "test-subtitles", + "file": "test/browser/media/declaration-cues.vtt" + }, + "sha256": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "bytes": 54 + }, + "/test/thumbnail-grid.svg": { + "source": { + "kind": "test-thumbnail-grid", + "file": "test/browser/media/thumbnail-grid.svg" + }, + "sha256": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "bytes": 14969 + }, + "/test/legacy-safe-area.js": { + "source": { + "kind": "frozen-own-source", + "file": "test/helpers/legacy-safe-area.js", + "commit": "ccf77c4e" + }, + "sha256": "ce0368618ef6363b78271b8bcc7973abd0478e797cc464ddd912929e6dfa501a", + "bytes": 795 + }, + "/assets/sample/video.mp4": { + "source": { + "kind": "docs-media", + "file": "docs/assets/sample/video.mp4" + }, + "sha256": "30a2de667ba267b6bc605edcee1c4bd728c048ed76f500ea0e73d1f1a6f8f980", + "bytes": 5818706 + }, + "/test/performance.js": { + "source": { + "kind": "adapted-baseline-fixture", + "file": "refactor/fixtures/performance.js" + }, + "sha256": "2318f39bdb5f3a3348d755cb4335907ae4adc944be3a435839c1bba201e81500", + "bytes": 8994 + } + } + }, + "state": { + "url": "http://127.0.0.1:8084/test/player.html?core=candidate&chapter=published", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.8010.12 Safari/537.36", + "media": null + }, + "errors": [], + "consoleErrors": [], + "failedRequests": [] + } + }, + "scope": "Working-tree build artifacts; not isolated npm installation. Windows WebKit playback lacks MSE; its capability check and real Monaco tests pass. Monaco HLS test executes the factory, not HLS playback. SDK worker, broader SDK/device matrix and installed consumption remain HLS-05/06." +} diff --git a/refactor/changes/2026-09-12-PKG-HLS-04-types.md b/refactor/changes/2026-09-12-PKG-HLS-04-types.md new file mode 100644 index 000000000..a59ca9778 --- /dev/null +++ b/refactor/changes/2026-09-12-PKG-HLS-04-types.md @@ -0,0 +1,71 @@ +# PKG-HLS-04:HLS 严格 TypeScript 与兼容声明 + +## 实现与兼容边界 + +上一任务建立的入口、映射、菜单、SDK 订阅模块迁移到 .ts,新增 types.ts 描述窄宿主、 +SDK 可选能力和选择模型。五个自有模块均纳入 strict/noUncheckedIndexedAccess, +不引入 any、通配模块声明或 Hls 生产依赖。源码直接复用公开 Option/Result 类型, +独立消费夹具校验源码工厂与公开工厂相互可赋值。实际模块地图见包内 ARCHITECTURE.md。 + +公开工厂、字面量 name、同步 update、控件名/图标、DOM/CSS 和运行时根/legacy 路径不变。 +getName 保留原 SDK 对象身份和普通函数调用,索引准确标为可选;默认质量/音轨字段可以推断, +调用方可用泛型或回调注解选择真实 SDK 类型。旧 object 参数 formatter 仍可赋值。 +新增可选配置重载支持原来运行时就允许的省略/undefined;保留最后的必填重载, +以兼容旧 Parameters[0]['quality'] 类型提取,不将其改成可能 undefined。 +旧声明的 name 已是字面量,本次没有新增 name 写入限制。 + +.d.ts 继续为历史类型入口,.d.cts/.d.mts 提供 callable CommonJS/ESM 默认和命名类型桥, +legacy 的 typesVersions 支持 TS 4.3 Node10 查找。没有改变三个 JavaScript 文件的路径, +没有提前升级版本;逐包 next-major 与最终安装包检查继续由发布任务及 HLS-06 执行。 + +有限断言均有边界说明:入口承接外部附加的 art.hls,仍通过历史 errorHandle/media 检查; +SDK on/off 断言位于函数能力检查之后;选择项索引位于相等长度检查之后。它们不验证全部 +外部 SDK 结构,不能替代运行时契约测试。新增的局部对象别名保持原方法接收者。 + +## 在线编辑器修复 + +旧生成方式保留 default/named exports 又附加 export=,严格编译生成结果会报告 TS2309。 +新增 scripts/plugin-editor-types.mjs 使用 AST 为 HLS 生成私有定义和 callable/global 类型桥, +保留泛型默认和重载,拒绝未知 import/export,不静默删除依赖。build:ts 在写入该声明前 +以 TS 4.3.5/5.9.3 对核心+插件独立语义检查,skipLibCheck=false。 +生成器暂仅应用已验证的 HLS,其他插件按各自迁移任务接续;未手改 docs/assets/ts。 + +新测试检查输出可再生成、三条错误用法确实拒绝、损坏声明/未解析依赖不会被隐藏。 +真实 Monaco worker 用例在三个浏览器中加载实际生成文件,验证默认字段、旧类型提取、 +错误 formatter 诊断,并执行编译后的插件工厂。原核心 Monaco 示例也重跑并播放成功。 +HLS 编辑器用例自身只执行工厂,不宣称播放;实际播放由独立 HLS SDK 矩阵验证。 +首轮编辑器测试把重载错误预期写成 2322;实际 worker 正确返回 2769,无其他正例诊断。 +按真实重载语义纠正断言后,最终六项全部通过,没有修改声明来容忍非法返回。 + +## 验收证据 + +冻结文件为 [hls-types-validation.json](../baselines/hls-types-validation.json),保留源码/类型/ +生成脚本及产物指纹、浏览器输入与各用例结果、CI 日志摘要;旧任务冻结证据不覆盖。 + +| 项目 | 本次结果 | +| --- | --- | +| 结构与类型 | HLS 五个 TS 模块;全仓实际已迁移生产 TS 254 个严格检查通过 | +| 旧/新类型消费者 | TS 5.9 Node10 CJS、NodeNext CJS/ESM、Bundler ESM 和 TS 4.3 Node10 CJS 正例零诊断,每组八条非法用法拒绝;另检查 CJS 命名空间与源码工厂 | +| 实际 SDK 类型 | 真实 Hls.js 1.5.17 的 Level/MediaPlaylist 泛型消费;TS 5.9 零错误,TS 4.3 与 SDK-only 对照均仅两个既有 DOM 类型错误,插件无新增 | +| Node 与产物 | 源码/发布专项 56 通过;加 main/legacy/ESM 构建共享契约累计 83 通过 | +| 实际播放 | modern/legacy 各 35 passed、16 skipped、0 failed/retry,输入 SHA 与最终构建一致;覆盖新旧核心和插件四组合、选择/切源/失败/销毁/SDK 事件同步 | +| 编辑器 | 核心+HLS 在 Chromium/Firefox/WebKit 共六项通过,无失败/重试/跳过 | +| 完整本地 CI | yarn ci:check:536 项通过,496 单元、11 工程、29 基线;现有生成核心 editor unused eslint-disable 警告未手改 | +| 构建 | yarn build artplayer-plugin-hls-control、yarn build:ts 通过;三份 dist 与 docs/compiled 字节一致 | + +main 为 5266 raw / 2539 gzip9 字节,legacy 5322 / 2564,ESM 9649 / 3117。 +与上一任务相比只有局部别名/类型擦除后的微小变化,类型依赖未进入运行包,不声称体积优化。 + +## 未覆盖范围与交接 + +TS 4.3 的 MediaDecodingConfiguration/MediaCapabilitiesDecodingInfo 缺失来自真实 SDK +声明与旧 lib.dom 组合;保留明确对照,不加虚假 DOM 定义,不以 skipLibCheck 隐藏。 +独立插件的旧编译器验收仍严格零诊断。SDK-01 和 HLS-ENV-01 保持 open。 +Windows WebKit 的 16 个播放跳过源于已确认缺少 MSE;能力/失败清理及 Monaco 测试照常运行。 +Safari/native、SDK worker/版本/分组轨道、官方示例及隔离 tarball 为 HLS-05/06 和发布门槛。 + +本步没有新增依赖;改进现有 build:ts、typecheck,新增生成 helper 和专项测试,已纳入 +现有 test:baseline/ci:check。包内文档、类型入口和生成产物随源码一起更新。 +本任务独立提交主题:refactor(hls): [PKG-HLS-04] migrate modules and compatible types。 +回退该 commit 可恢复上一任务四模块 JS 和旧类型/生成行为;保留 HLS-01~03 的基线与修复。 +提交并核实 Git 状态后进入 PKG-HLS-05。全项目目标继续,没有 push/tag/publish/merge。 diff --git a/refactor/hls-validation.md b/refactor/hls-validation.md index fe8cf513f..997be89b3 100644 --- a/refactor/hls-validation.md +++ b/refactor/hls-validation.md @@ -59,8 +59,20 @@ EX-03、REL-09/REVIEW-02 接续,SDK-01/HLS-ENV-01 保持 open。 Safari/native fallback、更多 SDK 版本、安装包及示例页面全部组合不是本轮完成内容。 显式安装产物映射暂不接受 HLS 源码回退;HLS-06 必须加入 HLS 包对应映射和隔离 tarball 消费。 -## 后续实施 +## PKG-HLS-03/04 后续验证 -PKG-HLS-03 拆出映射、UI 提交/删除、Hls 订阅与生命周期;把上述缺陷变成候选修复断言, -保留发布版观察。PKG-HLS-04 迁移自有模块和公开类型,修正可选 option、getName 对象与可选 index, -保持旧声明接受范围及分发路径。PKG-HLS-05/06 完成实际 SDK、浏览器、示例及安装包验收。 +PKG-HLS-03 已拆出映射、UI 提交/删除、Hls 订阅与生命周期;旧缺陷成为候选修复断言, +保留发布版观察。该步最终 Node 专项 56 通过,三格式共享契约累计 83 通过,modern/legacy +浏览器各 35 通过、16 跳过;以上早期 02 结果保持其原始范围,不冒充当前源码结果。 + +PKG-HLS-04 把五个模块迁移为严格 TS,公开类型保留旧调用和类型提取习惯,补齐默认字段、 +SDK 泛型、可选 index 和 CJS/ESM/legacy 声明路径。在线编辑器声明从公开源生成,构建时用 +TS 4.3/5.9 严格校验;真实 Monaco 验证推断、错误提示及编译后的工厂执行。 +这些编辑器用例不声称执行 HLS 播放,实际播放仍由 hls-control.spec.js 负责。 +本步结果见 [类型迁移记录](changes/2026-09-12-PKG-HLS-04-types.md) 和 +[冻结证据](baselines/hls-types-validation.json)。 + +实际 Hls.js 1.5.17 声明在 TS 4.3 缺少 MediaDecodingConfiguration 和 +MediaCapabilitiesDecodingInfo;仅 SDK 的消费者也出现相同两个诊断。插件无新增诊断, +不注入虚假 DOM 定义或打开 skipLibCheck。独立插件五组类型模式均要求零诊断。 +PKG-HLS-05/06 继续完整 SDK、浏览器、示例及安装包验收,SDK-01/HLS-ENV-01 仍开放。 diff --git a/refactor/plan.md b/refactor/plan.md index a2105d223..96c13d54a 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 215 项,范围 22 个包及工作区/示例。 -状态:todo 151 / doing 0 / blocked 0 / done 64 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 150 / doing 0 / blocked 0 / done 65 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -191,7 +191,7 @@ | PKG-HLS-01 | artplayer-plugin-hls-control
核对包契约与历史用法 | BASE-05 | quality/audio 配置、getName、update、控件名及 Hls 实例绑定 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | H | done | | PKG-HLS-02 | artplayer-plugin-hls-control
建立特有行为与错误测试 | PKG-HLS-01, ENG-03, ENG-05 | Auto/手动实际 level、音轨、去重/过滤和拓扑变化 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done | | PKG-HLS-03 | artplayer-plugin-hls-control
整理内部职责与资源 | PKG-HLS-02, CORE-11, CORE-14 | 映射计算与 selector 更新/删除、Hls 事件订阅分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done | -| PKG-HLS-04 | artplayer-plugin-hls-control
迁移自有源码和公开类型 | PKG-HLS-03, ENG-04, ENG-06, CORE-07 | HLS 能力适配类型、回调上下文和旧 getName 参数 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | todo | +| PKG-HLS-04 | artplayer-plugin-hls-control
迁移自有源码和公开类型 | PKG-HLS-03, ENG-04, ENG-06, CORE-07 | HLS 能力适配类型、回调上下文和旧 getName 参数 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done | | PKG-HLS-05 | artplayer-plugin-hls-control
验证新旧核心和组合 | PKG-HLS-04, CORE-22 | 本地多码率 HLS、换成无轨道来源、旧核心和最终核心 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo | | PKG-HLS-06 | artplayer-plugin-hls-control
验证分发并同步文档 | PKG-HLS-05, ENG-07 | hls.control.js、依赖范围与回退记录 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo | @@ -468,3 +468,4 @@ - PKG-HLS-01: [记录](baselines/hls-control-contract.md) [记录](baselines/hls-control-release.json) [记录](changes/2026-09-11-PKG-HLS-01-contract.md) - PKG-HLS-02: [记录](hls-validation.md) [记录](baselines/hls-sdk.json) [记录](baselines/hls-validation.json) [记录](changes/2026-09-11-PKG-HLS-02-tests.md) - PKG-HLS-03: [记录](changes/2026-09-12-PKG-HLS-03-modules.md) [记录](baselines/hls-modules-validation.json) [记录](hls-validation.md) +- PKG-HLS-04: [记录](changes/2026-09-12-PKG-HLS-04-types.md) [记录](baselines/hls-types-validation.json) [记录](hls-validation.md) diff --git a/refactor/progress.md b/refactor/progress.md index 924015851..28b0e86c1 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,20 @@ # 进度与证据 +## 最新完成:PKG-HLS-04 严格 TS 与公开类型 + +HLS 五个自有模块已迁移严格 TS;公开声明保留旧 object formatter、Parameters 配置提取、 +同步 update 及运行时入口,补齐默认字段、SDK 泛型、可选索引和 CJS/ESM/legacy 类型桥。 +在线编辑器由公开声明生成全局桥,并在 build:ts 内做双编译器严格语义检查。 + +完整本地 CI 536 项、254 个生产 TS 文件通过;HLS Node 专项 56 项,三格式累计 83 项通过。 +modern/legacy 浏览器各 35 通过、16 跳过,核心+HLS Monaco 六项通过;无失败/重试。 +最终产物输入指纹一致。实际 SDK 在 TS 4.3 的两个 DOM 类型缺失诊断有 SDK-only 对照, +不隐藏或称为全 SDK 支持;Windows WebKit 的 MSE/Safari 缺口依然开放。 + +见 [交付记录](changes/2026-09-12-PKG-HLS-04-types.md)、[冻结证据](baselines/hls-types-validation.json) +和包内 ARCHITECTURE.md。65 done、150 todo;本任务独立本地 commit,核实后进入 PKG-HLS-05。 +完整 SDK/组合/安装包、其余生态包、性能/CI/CD/版本/复盘继续执行原计划,没有公开发布。 + ## 最新完成:PKG-HLS-03 源码分层与生命周期修复 HLS control 已拆为入口、选择映射、菜单管理、SDK 订阅四个 JS 模块,保持公开入口和同步调用;修复空轨道旧菜单、过期回调、Auto 标签、重复组丢失选中态,并补事件同步、销毁/订阅失败恢复及重入保护。公开类型和严格 TS 迁移属于下一步 04。 diff --git a/refactor/risks.json b/refactor/risks.json index b84b9c539..ace21de9e 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -610,7 +610,7 @@ "EX-03" ], "evidence": [ - "packages/artplayer-plugin-hls-control/src/index.js", + "packages/artplayer-plugin-hls-control/src/index.ts", "docs/assets/example/hls.control.js", "refactor/hls-validation.md" ], diff --git a/refactor/scripts/hls-types.test.mjs b/refactor/scripts/hls-types.test.mjs new file mode 100644 index 000000000..394918302 --- /dev/null +++ b/refactor/scripts/hls-types.test.mjs @@ -0,0 +1,92 @@ +import assert from 'node:assert/strict' +import fs from 'node:fs' +import path from 'node:path' +// eslint-disable-next-line test/no-import-node-test -- Use the repository's built-in baseline runner. +import test from 'node:test' +import { ESLint } from 'eslint' +import ts from 'typescript' +import compat from 'typescript-compat' +import { checkPluginEditorDeclaration, generatePluginEditorDeclaration } from '../../scripts/plugin-editor-types.mjs' +import { checkConsumer } from '../../scripts/typecheck.mjs' +import { ensureArchive, readMember, refactorDir } from './releases.mjs' + +test('HLS generated editor types are reproducible, standalone and reject invalid formatter uses', async () => { + const source = fs.readFileSync(new URL('../../packages/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts', import.meta.url), 'utf8') + const generated = generatePluginEditorDeclaration(source, 'artplayerPluginHlsControl') + const file = 'docs/assets/ts/artplayer-plugin-hls-control.d.ts' + const [formatted] = await new ESLint({ fix: true, fixTypes: ['layout'] }).lintText(generated, { filePath: file }) + assert.equal(formatted.errorCount, 0) + assert.equal(fs.readFileSync(file, 'utf8').replaceAll('\r\n', '\n'), formatted.output || generated, 'Run yarn build:ts') + const core = fs.readFileSync('docs/assets/ts/artplayer.d.ts', 'utf8') + const consumer = ` +const option: artplayerPluginHlsControl.Option = { quality: { getName: (level, index) => level.height + ':' + index }, audio: { getName: track => track.name } } +const legacyOption: NonNullable[0]['quality']> = { getName: (value: object) => String(value) } +const plugin: (art: Artplayer) => artplayerPluginHlsControl.Result = artplayerPluginHlsControl(option) +artplayerPluginHlsControl() +artplayerPluginHlsControl(undefined) +artplayerPluginHlsControl({ quality: { getName: (value: { bitrate: number }) => String(value.bitrate) } }) +// @ts-expect-error Formatter must return a string. +artplayerPluginHlsControl({ quality: { getName: level => level.height } }) +// @ts-expect-error Default quality type cannot silently become any. +artplayerPluginHlsControl({ quality: { getName: level => level.missing } }) +// @ts-expect-error Private definitions must not leak into globals. +const hidden: artplayerPluginHlsControlDefinitions.Option = {} +void [legacyOption, plugin, hidden] +` + for (const compiler of [ts, compat]) { + assert.deepEqual(checkPluginEditorDeclaration(generated, core, consumer, compiler), [], compiler.version) + assert.equal(checkPluginEditorDeclaration(generated, core, consumer.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, ''), compiler).length, 3) + assert(checkPluginEditorDeclaration(`${generated}\nexport interface Broken { value: MissingType }`, core, '', compiler).some(item => item.code === 2309), 'Do not hide incompatible export assignment or unresolved declarations') + } + assert.throws(() => generatePluginEditorDeclaration(source.replace('from \'artplayer\'', 'from \'missing-sdk\''), 'artplayerPluginHlsControl'), /Unsupported plugin editor import/) + assert.throws(() => generatePluginEditorDeclaration(`${source}\nexport { Missing } from './missing'`, 'artplayerPluginHlsControl'), /Unsupported plugin editor declaration/) + assert.throws(() => generatePluginEditorDeclaration('export interface {', 'plugin'), /Invalid plugin declaration syntax/) +}) + +test('HLS root, legacy, named types and callback inference work across old and modern compilers', () => { + const source = fs.readFileSync(path.join(refactorDir, '../test/types/hls-control.ts'), 'utf8') + for (const [compiler, mode] of [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']]) { + assert.deepEqual(checkConsumer(compiler, mode, source), [], `${compiler.version} ${mode}`) + const invalid = source.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, '') + assert.equal(checkConsumer(compiler, mode, invalid).length, 8, `${compiler.version} ${mode} must reject all invalid uses`) + } + const cjs = 'import hls = require(\'artplayer-plugin-hls-control\'); import legacy = require(\'artplayer-plugin-hls-control/legacy\'); const option: hls.Option = { audio: { getName: track => track.name } }; hls(option); legacy();' + assert.deepEqual(checkConsumer(ts, 'nodenext-cjs', cjs), []) +}) + +test('HLS callback generics accept actual pinned SDK declarations without a runtime dependency', async () => { + const { release } = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/hls-sdk.json'))) + const archive = await ensureArchive(release) + const directory = fs.mkdtempSync(path.join(refactorDir, '.cache/hls-types-')) + try { + fs.writeFileSync(path.join(directory, 'sdk.d.ts'), readMember(archive, 'package/dist/hls.js.d.ts')) + const filename = path.join(directory, 'consumer.ts') + fs.writeFileSync(filename, `import type { Level, MediaPlaylist } from './sdk'; +import hls from 'artplayer-plugin-hls-control'; +hls({ quality: { getName: level => String(level.bitrate) }, audio: { getName: track => track.name } }); +hls({ quality: { getName: (level: Level, index?: number) => level.height + ':' + index }, audio: { getName: (track: MediaPlaylist) => track.groupId } }); +`) + for (const compiler of [ts, compat]) { + const program = compiler.createProgram([filename], { strict: true, noEmit: true, skipLibCheck: false, types: [], esModuleInterop: true, module: compiler.ModuleKind.CommonJS, moduleResolution: compiler.ModuleResolutionKind.NodeJs, target: compiler.ScriptTarget.ES2020, lib: ['lib.es2020.d.ts', 'lib.dom.d.ts'] }) + const describe = program => compiler.getPreEmitDiagnostics(program).map(item => ({ file: item.file && path.basename(item.file.fileName), code: item.code, message: compiler.flattenDiagnosticMessageText(item.messageText, '\n') })) + const expected = compiler === compat + ? [ + { file: 'sdk.d.ts', code: 2304, message: 'Cannot find name \'MediaDecodingConfiguration\'.' }, + { file: 'sdk.d.ts', code: 2304, message: 'Cannot find name \'MediaCapabilitiesDecodingInfo\'.' }, + ] + : [] + assert.deepEqual(describe(program), expected, `Actual Hls.js types / TS ${compiler.version}`) + const sdkOnly = path.join(directory, 'sdk-only.ts') + fs.writeFileSync(sdkOnly, 'import type { Level, MediaPlaylist } from \'./sdk\'; export type Inputs = [Level, MediaPlaylist];\n') + const control = compiler.createProgram([sdkOnly], program.getCompilerOptions()) + assert.deepEqual(describe(control), expected, 'Old DOM library errors must originate in the SDK alone, not the plugin') + assert(program.getSourceFiles().some(file => path.resolve(file.fileName) === path.join(directory, 'sdk.d.ts'))) + } + } + finally { + const resolved = fs.realpathSync(directory) + assert.equal(path.dirname(resolved), fs.realpathSync(path.join(refactorDir, '.cache'))) + assert(path.basename(resolved).startsWith('hls-types-')) + fs.rmSync(resolved, { recursive: true, force: true }) + } +}) diff --git a/refactor/tasks.json b/refactor/tasks.json index 6661a9051..2e43e7544 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -1850,11 +1850,15 @@ "ENG-06", "CORE-07" ], - "status": "todo", + "status": "done", "risk": "H", "deliverable": "HLS 能力适配类型、回调上下文和旧 getName 参数", "acceptance": "严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容", - "evidence": [] + "evidence": [ + "changes/2026-09-12-PKG-HLS-04-types.md", + "baselines/hls-types-validation.json", + "hls-validation.md" + ] }, { "id": "PKG-HLS-05", diff --git a/refactor/third-party.json b/refactor/third-party.json index 3a78a426b..5c800c0ac 100644 --- a/refactor/third-party.json +++ b/refactor/third-party.json @@ -1027,10 +1027,10 @@ "EX-03" ], "sourceFiles": [ - "packages/artplayer-plugin-hls-control/src/index.js", - "packages/artplayer-plugin-hls-control/src/mapping.js", - "packages/artplayer-plugin-hls-control/src/menu.js", - "packages/artplayer-plugin-hls-control/src/sdk-events.js", + "packages/artplayer-plugin-hls-control/src/index.ts", + "packages/artplayer-plugin-hls-control/src/mapping.ts", + "packages/artplayer-plugin-hls-control/src/menu.ts", + "packages/artplayer-plugin-hls-control/src/sdk-events.ts", "docs/assets/example/hls.control.js" ], "contract": "Caller supplies art.hls; homepage demo loads hls.js 1.5.17. Preserve quality/audio selectors and old core integration.", diff --git a/refactor/typechecking.md b/refactor/typechecking.md index a467a6bdc..e090ef706 100644 --- a/refactor/typechecking.md +++ b/refactor/typechecking.md @@ -1,5 +1,15 @@ # 已实现的类型检查与迁移入口 +PKG-HLS-04 增加 HLS 的 5 个严格 TS 源模块,公开声明保留历史 .d.ts 并增加 CJS/ESM 条件桥。 +test/types/hls-control.ts 覆盖配置省略、旧 Parameters 提取、默认字段和 SDK 泛型、同步返回, +hls-source.ts 检查源码工厂与公开工厂可相互赋值。hls-types.test.mjs 对五组编译模式检查正反例, +并消费实际 Hls.js 1.5.17 声明。TS 4.3 的两个 SDK 自有 DOM 缺失诊断有 SDK-only 对照, +不作插件通过的豁免;独立插件消费者仍要求零错误。 +scripts/plugin-editor-types.mjs 与 build:ts 负责 HLS 全局声明生成和双编译器语义校验, +真实 Monaco 用例为 test/browser/hls-editor-types.spec.js;它验证类型和编译后工厂执行, +实际 HLS 播放由 hls-control.spec.js 验证。详见 changes/2026-09-12-PKG-HLS-04-types.md。 +下方按原任务保留历史计数;当前执行统计以本次冻结证据和 typecheck 输出为准。 + CORE-21 已完成声明与消费者验收。核心公开声明源已迁至 packages/artplayer/public/, 使用 yarn build:types 生成历史 types/ 路径;yarn check:types 只读检查漂移、 源错误和内部依赖,已接入 ci:check。public/ 与 src/ 分别纳入严格检查, diff --git a/scripts/build-ts.js b/scripts/build-ts.js index 38f8f3d3f..34abbc2c9 100644 --- a/scripts/build-ts.js +++ b/scripts/build-ts.js @@ -2,7 +2,9 @@ import fs from 'node:fs' import path from 'node:path' import { ESLint } from 'eslint' import { glob } from 'glob' +import compat from 'typescript-compat' import { generateCoreEditorDeclaration } from './editor-types.mjs' +import { checkPluginEditorDeclaration, generatePluginEditorDeclaration } from './plugin-editor-types.mjs' function ensureDirExists(filePath) { const dir = path.dirname(filePath) @@ -40,7 +42,16 @@ console.log(`✨ Built ${artplayerTSoutput}`); for (let index = 0; index < pluginsTS.length; index++) { const type = pluginsTS[index] const { name, file } = parsePluginInfo(type) - const code = `${String(fs.readFileSync(type)).replace(reg, '')}\nexport = ${name};\nexport as namespace ${name};\n` + const source = String(fs.readFileSync(type)) + const code = name === 'artplayerPluginHlsControl' + ? generatePluginEditorDeclaration(source, name) + : `${source.replace(reg, '')}\nexport = ${name};\nexport as namespace ${name};\n` + if (name === 'artplayerPluginHlsControl') { + const core = fs.readFileSync(artplayerTSoutput, 'utf8') + const diagnostics = [...checkPluginEditorDeclaration(code, core), ...checkPluginEditorDeclaration(code, core, '', compat)] + if (diagnostics.length) + throw new Error(`Invalid ${name} editor declaration: ${JSON.stringify(diagnostics)}`) + } const output = path.join('docs/assets/ts', file) ensureDirExists(output) fs.writeFileSync(output, code.trim()) diff --git a/scripts/plugin-editor-types.mjs b/scripts/plugin-editor-types.mjs new file mode 100644 index 000000000..bed9e79ba --- /dev/null +++ b/scripts/plugin-editor-types.mjs @@ -0,0 +1,76 @@ +import assert from 'node:assert/strict' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import ts from 'typescript' + +// Migrate each package explicitly; unknown imports/exports must not disappear silently. +export function generatePluginEditorDeclaration(code, name) { + assert(/^[a-z_$][\w$]*$/i.test(name), 'Invalid plugin global') + const source = ts.createSourceFile('plugin.d.ts', code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS) + assert.equal(source.parseDiagnostics.length, 0, 'Invalid plugin declaration syntax') + const factory = ts.factory + const definitions = [] + const aliases = [] + const internal = `${name}Definitions` + let exported = false + let callable = false + for (const node of source.statements) { + if (ts.isImportDeclaration(node)) { + assert(node.importClause?.isTypeOnly && !node.importClause.namedBindings && node.importClause.name?.text === 'Artplayer' && node.moduleSpecifier.text === 'artplayer', 'Unsupported plugin editor import') + continue + } + if (ts.isExportAssignment(node)) { + assert(!node.isExportEquals && ts.isIdentifier(node.expression) && node.expression.text === name, 'Unexpected plugin default export') + exported = true + continue + } + assert(ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isFunctionDeclaration(node), 'Unsupported plugin editor declaration') + assert(node.name && node.name.text !== internal, 'Invalid plugin declaration name') + definitions.push(factory.replaceModifiers(node, [factory.createModifier(ts.SyntaxKind.ExportKeyword)])) + if (ts.isFunctionDeclaration(node)) { + assert.equal(node.name.text, name, 'Unexpected plugin callable') + callable = true + continue + } + if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword)) { + aliases.push(factory.createTypeAliasDeclaration( + [factory.createModifier(ts.SyntaxKind.ExportKeyword)], + node.name, + node.typeParameters, + factory.createTypeReferenceNode(factory.createQualifiedName(factory.createIdentifier(internal), node.name), node.typeParameters?.map(parameter => factory.createTypeReferenceNode(parameter.name))), + )) + } + } + assert(exported && callable, 'Plugin editor requires a default function') + const namespace = (identifier, statements) => factory.createModuleDeclaration([factory.createModifier(ts.SyntaxKind.DeclareKeyword)], factory.createIdentifier(identifier), factory.createModuleBlock(statements), ts.NodeFlags.Namespace) + const statements = [ + namespace(internal, definitions), + factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.DeclareKeyword)], factory.createVariableDeclarationList([ + factory.createVariableDeclaration(name, undefined, factory.createTypeQueryNode(factory.createQualifiedName(factory.createIdentifier(internal), factory.createIdentifier(name)))), + ], ts.NodeFlags.Const)), + namespace(name, aliases), + factory.createExportAssignment(undefined, true, factory.createIdentifier(name)), + factory.createNamespaceExportDeclaration(factory.createIdentifier(name)), + ] + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }) + return `// Generated from the package public declaration by yarn build:ts. Do not edit.\n/* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */\n${statements.map(node => printer.printNode(ts.EmitHint.Unspecified, node, source)).join('\n')}\n` +} + +export function checkPluginEditorDeclaration(code, core, consumer = '', compiler = ts) { + const folder = fileURLToPath(new URL('../refactor/.cache/plugin-editor-semantic/', import.meta.url)) + const sources = new Map([ + [path.join(folder, 'artplayer.d.ts'), core], + [path.join(folder, 'plugin.d.ts'), code], + [path.join(folder, 'consumer.ts'), consumer], + ]) + const options = { strict: true, noEmit: true, skipLibCheck: false, types: [], target: compiler.ScriptTarget.ES2020, lib: ['lib.es2020.d.ts', 'lib.dom.d.ts'], module: compiler.ModuleKind.CommonJS, moduleResolution: compiler.ModuleResolutionKind.NodeJs } + const host = compiler.createCompilerHost(options) + const getSourceFile = host.getSourceFile.bind(host) + host.getSourceFile = (file, version, onError, create) => sources.has(path.resolve(file)) + ? compiler.createSourceFile(file, sources.get(path.resolve(file)), version, true) + : getSourceFile(file, version, onError, create) + const program = compiler.createProgram([...sources.keys()], options, host) + for (const file of program.getSourceFiles()) + assert(sources.has(path.resolve(file.fileName)) || program.isSourceFileDefaultLibrary(file), `Plugin editor types escaped the standalone bundle: ${file.fileName}`) + return compiler.getPreEmitDiagnostics(program).map(diagnostic => ({ code: diagnostic.code, message: compiler.flattenDiagnosticMessageText(diagnostic.messageText, '\n') })) +} diff --git a/scripts/typecheck.mjs b/scripts/typecheck.mjs index 06b132be8..16c199114 100644 --- a/scripts/typecheck.mjs +++ b/scripts/typecheck.mjs @@ -73,7 +73,7 @@ export function runTypechecks() { console.log(`Strict project passed: ${relative(config)} (${result.files.length} root files)`) } for (const [compiler, mode] of [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'bundler-esm'], [ts, 'nodenext-esm'], [compat, 'node10-commonjs']]) { - for (const fixture of ['test/types/public.ts', 'test/types/declaration-inputs.ts', 'test/types/declaration-legacy.ts', 'test/types/plugins-public.ts', 'test/types/playback-public.ts', 'test/types/chapter-options.ts', 'test/types/chapter-exports.ts', 'test/types/language-value.ts', 'refactor/fixtures/consumers/language.ts', 'refactor/fixtures/consumers/legacy-plugin.ts']) { + for (const fixture of ['test/types/public.ts', 'test/types/declaration-inputs.ts', 'test/types/declaration-legacy.ts', 'test/types/plugins-public.ts', 'test/types/playback-public.ts', 'test/types/chapter-options.ts', 'test/types/chapter-exports.ts', 'test/types/hls-control.ts', 'test/types/language-value.ts', 'refactor/fixtures/consumers/language.ts', 'refactor/fixtures/consumers/legacy-plugin.ts']) { assert.deepEqual(checkConsumer(compiler, mode, fs.readFileSync(path.join(root, fixture), 'utf8')), [], `Consumer failed: TS ${compiler.version} ${mode} ${fixture}`) } if (mode === 'nodenext-cjs') diff --git a/test/browser/hls-editor-types.spec.js b/test/browser/hls-editor-types.spec.js new file mode 100644 index 000000000..6be20c09d --- /dev/null +++ b/test/browser/hls-editor-types.spec.js @@ -0,0 +1,67 @@ +import fs from 'node:fs' +import process from 'node:process' +import { hash } from '../../refactor/scripts/releases.mjs' +import { compilePackage } from '../helpers/load.js' +import { expect, test } from './fixtures.js' + +test('Monaco consumes HLS global types and executes the emitted plugin factory', async ({ page }, testInfo) => { + const code = process.env.ARTPLAYER_HLS_ARTIFACT + ? fs.readFileSync(process.env.ARTPLAYER_HLS_ARTIFACT, 'utf8') + : await compilePackage('artplayer-plugin-hls-control', 'umd') + const declarations = Object.fromEntries(['artplayer', 'artplayer-plugin-hls-control'].map(name => [name, hash(fs.readFileSync(new URL(`../../docs/assets/ts/${name}.d.ts`, import.meta.url)))])) + const inputs = { candidate: process.env.ARTPLAYER_HLS_ARTIFACT || 'workspace source build', sha256: hash(code), declarations } + await testInfo.attach('hls-editor-inputs', { contentType: 'application/json', body: JSON.stringify(inputs) }) + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.addScriptTag({ content: code }) + await page.addScriptTag({ url: '/assets/js/vs/loader.js' }) + const result = await page.evaluate(async () => { + window.require.config({ paths: { vs: '/assets/js/vs' } }) + await new Promise((resolve, reject) => window.require(['vs/editor/editor.main'], resolve, reject)) + const api = window.monaco + const types = api.languages.typescript + types.typescriptDefaults.setCompilerOptions({ target: types.ScriptTarget.ES2020, strict: true, skipLibCheck: false, noEmit: false, types: [], allowNonTsExtensions: true }) + const names = ['artplayer', 'artplayer-plugin-hls-control'] + const libraries = await Promise.all(names.map(async (name) => { + const uri = `file:///${name}.d.ts` + const source = await (await fetch(`/assets/ts/${name}.d.ts`)).text() + return { uri, handle: types.typescriptDefaults.addExtraLib(source, uri) } + })) + const model = api.editor.createModel(` +const hlsOption: artplayerPluginHlsControl.Option = { + quality: { getName: (level, index) => level.height + ':' + index }, + audio: { getName: track => track.name }, +} +const oldQuality: NonNullable[0]['quality']> = { getName: (value: object) => String(value) } +const typedFactory: (art: Artplayer) => artplayerPluginHlsControl.Result = artplayerPluginHlsControl(hlsOption) +const defaultFactory = artplayerPluginHlsControl() +`, 'typescript', api.Uri.parse('file:///hls-consumer.ts')) + const invalid = api.editor.createModel('artplayerPluginHlsControl({ quality: { getName: level => level.height } })', 'typescript', api.Uri.parse('file:///hls-invalid.ts')) + try { + const worker = await (await types.getTypeScriptWorker())(model.uri, invalid.uri) + const syntax = await worker.getSyntacticDiagnostics(model.uri.toString()) + const semantic = await worker.getSemanticDiagnostics(model.uri.toString()) + const declarations = (await Promise.all(libraries.map(lib => worker.getSemanticDiagnostics(lib.uri)))).flat() + const bad = await worker.getSemanticDiagnostics(invalid.uri.toString()) + if (syntax.length || semantic.length || declarations.length) + return { syntax, semantic, declarations, invalid: bad.map(item => item.code), executed: false } + const output = await worker.getEmitOutput(model.uri.toString()) + const script = output.outputFiles.find(file => file.name.endsWith('.js')) + if (!script) + throw new Error('Monaco did not emit the HLS fixture') + // eslint-disable-next-line no-new-func -- Exercise the local editor Run action with its real emitted code. + const executed = new Function(`${script.text}\nreturn typeof typedFactory === 'function' && typeof defaultFactory === 'function'`)() + return { syntax, semantic, declarations, invalid: bad.map(item => item.code), executed } + } + finally { + model.dispose() + invalid.dispose() + for (const library of libraries) + library.handle.dispose() + } + }) + expect(result.syntax).toEqual([]) + expect(result.semantic).toEqual([]) + expect(result.declarations).toEqual([]) + expect(result.invalid).toEqual([2769]) + expect(result.executed).toBe(true) +}) diff --git a/test/types/hls-control.ts b/test/types/hls-control.ts new file mode 100644 index 000000000..0bf858e06 --- /dev/null +++ b/test/types/hls-control.ts @@ -0,0 +1,43 @@ +import type { AudioTrack, Config, Option, QualityLevel, Result } from 'artplayer-plugin-hls-control' +import Artplayer from 'artplayer' +import hlsControl from 'artplayer-plugin-hls-control' +import legacy from 'artplayer-plugin-hls-control/legacy' + +const option: Option = { + quality: { control: true, getName: (level, index) => `${level.height}P ${index ?? ''}` }, + audio: { setting: true, getName: track => track.name }, +} +const art = new Artplayer({ container: '#player', url: 'video.m3u8', plugins: [hlsControl(), hlsControl(option), legacy()] }) +const result: Result = hlsControl(option)(art) +type HistoricalOption = Parameters[0] +const historicalQuality: HistoricalOption['quality'] = { getName: (item: object) => String(item) } +hlsControl({ quality: historicalQuality }) +hlsControl(undefined) +const done: void = result.update() +const generic: Config = { getName: (item: object) => String(item) } +hlsControl({ quality: generic, audio: generic }) +const level: QualityLevel = { height: 720 } +const track: AudioTrack = { id: 0, name: 'English' } + +interface CustomLevel { height: number, bitrate: number, label: string } +interface CustomTrack { id: number, name: string, groupId: string } +hlsControl({ quality: { getName: (value: CustomLevel) => value.label }, audio: { getName: (value: CustomTrack) => value.groupId } }) +hlsControl({ quality: { getName: value => String(value.bitrate) } }) + +// @ts-expect-error update stays synchronous and returns void. +const promise: Promise = result.update() +// @ts-expect-error update takes no configuration argument. +result.update({}) +// @ts-expect-error The result name remains a literal. +const invalidName: Result['name'] = 'hls' +// @ts-expect-error Selected-label calls do not supply the index. +hlsControl({ quality: { getName: (value: QualityLevel, index: number) => String(index) } }) +// @ts-expect-error A formatter must return a string. +hlsControl({ audio: { getName: () => 123 } }) +// @ts-expect-error Control visibility is boolean. +legacy({ quality: { control: 'yes' } }) +// @ts-expect-error Null was never a valid options object. +hlsControl(null) +// @ts-expect-error Default quality fields are typed, not an any escape. +hlsControl({ quality: { getName: value => value.unknownProperty } }) +void [done, level, track, promise, invalidName] diff --git a/test/types/hls-source.ts b/test/types/hls-source.ts new file mode 100644 index 000000000..cadb6d477 --- /dev/null +++ b/test/types/hls-source.ts @@ -0,0 +1,9 @@ +import type PublicFactory from 'artplayer-plugin-hls-control' +import factory from '../../packages/artplayer-plugin-hls-control/src/index' + +const compatible: typeof PublicFactory = factory +const implementation: typeof factory = compatible +implementation({ quality: { getName: level => `${level.height}P` }, audio: { getName: track => track.name } }) +compatible() +// @ts-expect-error Source and public declaration both reject non-string formatter results. +factory({ quality: { getName: () => 1 } })