fix(core): [CORE-24] preserve source playback intent and explicit pauses

This commit is contained in:
Harvey Zhao committed 2026-09-12 03:26:26 +08:00
1 parent b5e96664ee
commit 0218196df9
22 files changed
+12895 -36

No files matched your search

+11
View File
@@ -260,6 +260,17 @@ twice. media/position-revision.ts also tracks legal public currentTime writes;
a consumer assigning currentTime directly during loading supersedes the automatic
restoration, including writes before metadata. Invalid NaN assignments remain no-ops.
Source cancellation still settles pending work and removes all listeners.
CORE-24 keeps the desired playback state on the pending source operation. A new switch inherits
that intent before disposing its predecessor; it must not infer the user's intent from the
temporary native pause performed by the previous switch. playMix/pauseMix update intent at
command entry, before native calls or public callbacks can reenter. The switch's internal pause
consumes one marker; subsequent explicit pauses remain effective, including inside callbacks.
The pause revision invalidates late play notifications and prevents an old resume from clearing
a newer pause notice. It does not change the public play promise's original value or rejection.
Completed, failed or cancelled operations cannot lend intent to a later independent source.
Do not replace these command hooks with late event listeners: an earlier user pause listener
may synchronously start another switch. See test/source.test.js, test/browser/source-intent.spec.js
and refactor/changes/2026-09-12-CORE-24-source-intent.md for the regressions and validation scope.
Use test/source.test.js, test/progress.test.js and the browser source and
progress-quality specs. Keep native media events in evidence when changing this
sequence; the original rate-interruption hypothesis was not sufficient to explain
+1 -1
View File
@@ -67,4 +67,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),c=r(t);if("object"===s){if("object"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(c,"'"));Object.keys(e).forEach(function(r){var s=t[r],c=e[r],l=n.slice();l.push(r),i(s,c,l),a(s,c,l),o(s,c,l)})}if("array"===s){if("array"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(c,"'"));t.forEach(function(r,s){var c=t[s],l=e[s]||e[0],d=n.slice();d.push(s),i(c,l,d),a(c,l,d),o(c,l,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),r.exports);const o=t(n),i="5.4.1";function a(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controlLine truncated
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),c=r(t);if("object"===s){if("object"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(c,"'"));Object.keys(e).forEach(function(r){var s=t[r],c=e[r],l=n.slice();l.push(r),i(s,c,l),a(s,c,l),o(s,c,l)})}if("array"===s){if("array"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(c,"'"));t.forEach(function(r,s){var c=t[s],l=e[s]||e[0],d=n.slice();d.push(s),i(c,l,d),a(c,l,d),o(c,l,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),r.exports);const o=t(n),i="5.4.1";function a(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controlLine truncated
+1 -1
View File
@@ -67,4 +67,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),l=r(t);if("object"===s){if("object"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(l,"'"));Object.keys(e).forEach(function(r){var s=t[r],l=e[r],c=n.slice();c.push(r),i(s,l,c),a(s,l,c),o(s,l,c)})}if("array"===s){if("array"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(l,"'"));t.forEach(function(r,s){var l=t[s],c=e[s]||e[0],d=n.slice();d.push(s),i(l,c,d),a(l,c,d),o(l,c,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),p.exports);const h=d(f),m="5.4.1";function v(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.apLine truncated
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),l=r(t);if("object"===s){if("object"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(l,"'"));Object.keys(e).forEach(function(r){var s=t[r],l=e[r],c=n.slice();c.push(r),i(s,l,c),a(s,l,c),o(s,l,c)})}if("array"===s){if("array"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(l,"'"));t.forEach(function(r,s){var l=t[s],c=e[s]||e[0],d=n.slice();d.push(s),i(l,c,d),a(l,c,d),o(l,c,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),p.exports);const h=d(f),m="5.4.1";function v(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.apLine truncated
+40 -5
View File
@@ -2096,6 +2096,22 @@ function playAndPause(option) {
const current = /* @__PURE__ */ new WeakMap();
const assignments = /* @__PURE__ */ new WeakMap();
const sources = /* @__PURE__ */ new WeakMap();
function sourcePlaybackIntent(owner) {
const operation = current.get(owner);
return operation?.active() ? operation.resumePlaying : void 0;
}
function requestSourcePlayback(owner, playing) {
const operation = current.get(owner);
if (!operation?.active() || operation.resumePlaying === void 0)
return;
if (!playing && operation.internalPause) {
operation.internalPause = false;
} else {
operation.resumePlaying = playing;
if (!playing)
operation.pauseRevision++;
}
}
function getSourceScope(owner) {
return sources.get(owner) || getScope(owner);
}
@@ -2104,6 +2120,12 @@ function captureSource(owner) {
const source = sources.get(owner);
return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed);
}
function captureSourcePlayback(owner) {
const active2 = captureSource(owner);
const operation = current.get(owner);
const revision = operation?.pauseRevision;
return () => active2() && operation?.pauseRevision === revision;
}
function beginSource(owner) {
const previous = sources.get(owner);
const source = getScope(owner).child();
@@ -2117,6 +2139,7 @@ function beginSource(owner) {
scope,
assigned: false,
acceptingEvents: false,
pauseRevision: 0,
active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation
};
current.set(owner, operation);
@@ -5713,6 +5736,7 @@ function pauseMix(art) {
} = art;
def(art, "pause", {
value() {
requestSourcePlayback(art, false);
const result = $video.pause();
notice.show = i18n.get("Pause");
art.emit("pause");
@@ -5960,7 +5984,8 @@ function playMix(art) {
} = art;
def(art, "play", {
async value() {
const active2 = captureSource(art);
requestSourcePlayback(art, true);
const active2 = captureSourcePlayback(art);
const result = await $video.play();
if (!active2())
return result;
@@ -6203,13 +6228,16 @@ function switchSource(art, url, currentTime) {
resolve();
return;
}
const playing = sourcePlaybackIntent(art) ?? art.playing;
const operation = beginSource(art);
operation.resumePlaying = playing;
const scope = operation.scope.child();
let settled = false;
const settle = (failed = false, error2) => {
if (settled)
return;
settled = true;
operation.resumePlaying = void 0;
operation.onError = void 0;
operation.onAssigned = void 0;
scope.dispose();
@@ -6227,8 +6255,13 @@ function switchSource(art, url, currentTime) {
const fail = (error2) => settle(true, error2);
operation.onError = fail;
try {
const { playing, aspectRatio: aspectRatio2, playbackRate: playbackRate2 } = art;
art.pause();
const { aspectRatio: aspectRatio2, playbackRate: playbackRate2 } = art;
operation.internalPause = true;
try {
art.pause();
} finally {
operation.internalPause = false;
}
if (!active2())
return;
const readiness = scope.child();
@@ -6237,10 +6270,11 @@ function switchSource(art, url, currentTime) {
let rateRestored = false;
const position = positionRestoration(art, currentTime, active2);
const resume = async () => {
const pauseRevision = operation.pauseRevision;
art.aspectRatio = aspectRatio2;
if (!active2())
return;
if (playing) {
if (operation.resumePlaying) {
try {
await art.play();
} catch {
@@ -6248,7 +6282,8 @@ function switchSource(art, url, currentTime) {
}
if (!active2())
return;
art.notice.show = "";
if (operation.pauseRevision === pauseRevision)
art.notice.show = "";
settle();
};
const resumeWhenReady = () => {
@@ -1,5 +1,6 @@
import type { PauseHost } from '../media/hosts'
import type { PlaybackMethods } from '../media/types'
import { requestSourcePlayback } from '../source/operation'
import { def } from '../utils'
export default function pauseMix<Media extends Pick<PlaybackMethods, 'pause'>>(art: PauseHost<Media>): asserts art is PauseHost<Media> & { pause: () => ReturnType<Media['pause']> } {
@@ -11,6 +12,7 @@ export default function pauseMix<Media extends Pick<PlaybackMethods, 'pause'>>(a
def(art, 'pause', {
value() {
requestSourcePlayback(art, false)
const result = $video.pause()
notice.show = i18n.get('Pause')
art.emit('pause')
+3 -2
View File
@@ -1,6 +1,6 @@
import type { PlayHost } from '../media/hosts'
import type { PlaybackMethods } from '../media/types'
import { captureSource } from '../source/operation'
import { captureSourcePlayback, requestSourcePlayback } from '../source/operation'
import { def } from '../utils'
export default function playMix<Media extends Pick<PlaybackMethods, 'play'>>(art: PlayHost<Media>): asserts art is PlayHost<Media> & { play: () => Promise<Awaited<ReturnType<Media['play']>>> } {
@@ -14,7 +14,8 @@ export default function playMix<Media extends Pick<PlaybackMethods, 'play'>>(art
def(art, 'play', {
async value() {
const active = captureSource(art)
requestSourcePlayback(art, true)
const active = captureSourcePlayback(art)
const result = await $video.play()
if (!active())
return result
@@ -6,6 +6,9 @@ export interface SourceOperation {
scope: ResourceScope
assigned: boolean
acceptingEvents: boolean
pauseRevision: number
resumePlaying?: boolean
internalPause?: boolean
onAssigned?: () => void
onError?: (error: unknown) => void
active: () => boolean
@@ -15,6 +18,25 @@ const current = new WeakMap<object, SourceOperation>()
const assignments = new WeakMap<object, SourceOperation>()
const sources = new WeakMap<object, ResourceScope>()
export function sourcePlaybackIntent(owner: object): boolean | undefined {
const operation = current.get(owner)
return operation?.active() ? operation.resumePlaying : undefined
}
export function requestSourcePlayback(owner: object, playing: boolean): void {
const operation = current.get(owner)
if (!operation?.active() || operation.resumePlaying === undefined)
return
if (!playing && operation.internalPause) {
operation.internalPause = false
}
else {
operation.resumePlaying = playing
if (!playing)
operation.pauseRevision++
}
}
export function getSourceScope(owner: object): ResourceScope {
return sources.get(owner) || getScope(owner)
}
@@ -26,6 +48,13 @@ export function captureSource(owner: object): () => boolean {
&& sources.get(owner) === source && (!source || !source.closed)
}
export function captureSourcePlayback(owner: object): () => boolean {
const active = captureSource(owner)
const operation = current.get(owner)
const revision = operation?.pauseRevision
return () => active() && operation?.pauseRevision === revision
}
export function beginSource(owner: object): SourceOperation {
const previous = sources.get(owner)
const source = getScope(owner).child()
@@ -39,6 +68,7 @@ export function beginSource(owner: object): SourceOperation {
scope,
assigned: false,
acceptingEvents: false,
pauseRevision: 0,
active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation,
}
current.set(owner, operation)
+20 -9
View File
@@ -1,7 +1,7 @@
import type { SourceEvent, SourceListener, SwitchHost } from './types'
import type { SourceListener, SwitchHost } from './types'
import { isClosing } from '../lifecycle/instance'
import { listenSource } from './listen'
import { assignUrl, beginSource } from './operation'
import { assignUrl, beginSource, sourcePlaybackIntent } from './operation'
import { positionRestoration } from './restore-position'
export function switchSource(art: SwitchHost, url: string, currentTime: number): Promise<void> {
@@ -10,13 +10,16 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number):
resolve()
return
}
const playing = sourcePlaybackIntent(art) ?? art.playing
const operation = beginSource(art)
operation.resumePlaying = playing
const scope = operation.scope.child()
let settled = false
const settle = (failed = false, error?: unknown) => {
if (settled)
return
settled = true
operation.resumePlaying = undefined
operation.onError = undefined
operation.onAssigned = undefined
scope.dispose()
@@ -34,8 +37,14 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number):
const fail = (error: unknown) => settle(true, error)
operation.onError = fail
try {
const { playing, aspectRatio, playbackRate } = art
art.pause()
const { aspectRatio, playbackRate } = art
operation.internalPause = true
try {
art.pause()
}
finally {
operation.internalPause = false
}
if (!active())
return
@@ -45,10 +54,11 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number):
let rateRestored = false
const position = positionRestoration(art, currentTime, active)
const resume = async () => {
const pauseRevision = operation.pauseRevision
art.aspectRatio = aspectRatio
if (!active())
return
if (playing) {
if (operation.resumePlaying) {
// The public play promise still rejects; this internal resume is best effort.
try {
await art.play()
@@ -57,7 +67,8 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number):
}
if (!active())
return
art.notice.show = ''
if (operation.pauseRevision === pauseRevision)
art.notice.show = ''
settle()
}
const resumeWhenReady = () => {
@@ -103,8 +114,8 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number):
'seek': position.manual,
}
const capture = scope.child()
const queued: [SourceEvent, unknown][] = []
const names = Object.keys(handlers) as SourceEvent[]
const queued: [keyof typeof handlers, unknown][] = []
const names = Object.keys(handlers) as (keyof typeof handlers)[]
for (const name of names) {
listenSource(capture, art, name, (event) => {
if (operation.acceptingEvents)
@@ -123,7 +134,7 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number):
settle()
return
}
const dispatch = {} as Record<SourceEvent, SourceListener>
const dispatch = {} as Record<keyof typeof handlers, SourceListener>
for (const name of names)
dispatch[name] = listenSource(readiness, art, name, handlers[name], name !== 'video:seeked')
for (const [name, event] of queued) {