tiny-essentials 1.28.6 → 1.28.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog/1/28/6.md +3 -0
- package/changelog/1/28/7.md +7 -0
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.cjs +27 -0
- package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.d.mts +15 -0
- package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.mjs +24 -0
- package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.cjs +27 -0
- package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.d.mts +15 -0
- package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.mjs +24 -0
- package/dist/v1/libs/TinyMediaPlayer/SoundCloud.cjs +55 -1
- package/dist/v1/libs/TinyMediaPlayer/SoundCloud.d.mts +15 -0
- package/dist/v1/libs/TinyMediaPlayer/SoundCloud.mjs +49 -1
- package/dist/v1/libs/TinyMediaPlayer/Youtube.cjs +27 -0
- package/dist/v1/libs/TinyMediaPlayer/Youtube.d.mts +15 -0
- package/dist/v1/libs/TinyMediaPlayer/Youtube.mjs +24 -0
- package/dist/v1/libs/TinyMediaPlayer/index.cjs +27 -0
- package/dist/v1/libs/TinyMediaPlayer/index.d.mts +15 -0
- package/dist/v1/libs/TinyMediaPlayer/index.mjs +24 -0
- package/dist/v1/libs/TinyMediaPlayer.cjs +37 -0
- package/dist/v1/libs/TinyMediaPlayer.d.mts +9 -0
- package/dist/v1/libs/TinyMediaPlayer.mjs +33 -0
- package/docs/v1/libs/TinyMediaPlayer.md +31 -37
- package/package.json +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var e={843(e,t,r){r.d(t,{TinyMediaPlayer:()=>v});var n=r.cjs(function(e,t){var r,n="object"==typeof Reflect?Reflect:null,o=n&&"function"==typeof n.apply?n.apply:function(e,t,r){return Function.prototype.apply.call(e,t,r)};r=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var s=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise(function(r,n){function o(r){e.removeListener(t,s),n(r)}function s(){"function"==typeof e.removeListener&&e.removeListener("error",o),r([].slice.call(arguments))}f(e,t,s,{once:!0}),"error"!==t&&function(e,t){"function"==typeof e.on&&f(e,"error",t,{once:!0})}(e,o)})},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var a=10;function l(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function d(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function u(e,t,r,n){var o,s,i,a;if(l(r),void 0===(s=e._events)?(s=e._events=Object.create(null),e._eventsCount=0):(void 0!==s.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),s=e._events),i=s[t]),void 0===i)i=s[t]=r,++e._eventsCount;else if("function"==typeof i?i=s[t]=n?[r,i]:[i,r]:n?i.unshift(r):i.push(r),(o=d(e))>0&&i.length>o&&!i.warned){i.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+i.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=i.length,a=u,console&&console.warn&&console.warn(a)}return e}function h(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},o=h.bind(n);return o.listener=r,n.wrapFn=o,o}function c(e,t,r){var n=e._events;if(void 0===n)return[];var o=n[t];return void 0===o?[]:"function"==typeof o?r?[o.listener||o]:[o]:r?function(e){for(var t=new Array(e.length),r=0;r<t.length;++r)t[r]=e[r].listener||e[r];return t}(o):y(o,o.length)}function m(e){var t=this._events;if(void 0!==t){var r=t[e];if("function"==typeof r)return 1;if(void 0!==r)return r.length}return 0}function y(e,t){for(var r=new Array(t),n=0;n<t;++n)r[n]=e[n];return r}function f(e,t,r,n){if("function"==typeof e.on)n.once?e.once(t,r):e.on(t,r);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,function o(s){n.once&&e.removeEventListener(t,o),r(s)})}}Object.defineProperty(i,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e||e<0||s(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");a=e}}),i.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},i.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||s(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},i.prototype.getMaxListeners=function(){return d(this)},i.prototype.emit=function(e){for(var t=[],r=1;r<arguments.length;r++)t.push(arguments[r]);var n="error"===e,s=this._events;if(void 0!==s)n=n&&void 0===s.error;else if(!n)return!1;if(n){var i;if(t.length>0&&(i=t[0]),i instanceof Error)throw i;var a=new Error("Unhandled error."+(i?" ("+i.message+")":""));throw a.context=i,a}var l=s[e];if(void 0===l)return!1;if("function"==typeof l)o(l,this,t);else{var d=l.length,u=y(l,d);for(r=0;r<d;++r)o(u[r],this,t)}return!0},i.prototype.addListener=function(e,t){return u(this,e,t,!1)},i.prototype.on=i.prototype.addListener,i.prototype.prependListener=function(e,t){return u(this,e,t,!0)},i.prototype.once=function(e,t){return l(t),this.on(e,p(this,e,t)),this},i.prototype.prependOnceListener=function(e,t){return l(t),this.prependListener(e,p(this,e,t)),this},i.prototype.removeListener=function(e,t){var r,n,o,s,i;if(l(t),void 0===(n=this._events))return this;if(void 0===(r=n[e]))return this;if(r===t||r.listener===t)0===--this._eventsCount?this._events=Object.create(null):(delete n[e],n.removeListener&&this.emit("removeListener",e,r.listener||t));else if("function"!=typeof r){for(o=-1,s=r.length-1;s>=0;s--)if(r[s]===t||r[s].listener===t){i=r[s].listener,o=s;break}if(o<0)return this;0===o?r.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(r,o),1===r.length&&(n[e]=r[0]),void 0!==n.removeListener&&this.emit("removeListener",e,i||t)}return this},i.prototype.off=i.prototype.removeListener,i.prototype.removeAllListeners=function(e){var t,r,n;if(void 0===(r=this._events))return this;if(void 0===r.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==r[e]&&(0===--this._eventsCount?this._events=Object.create(null):delete r[e]),this;if(0===arguments.length){var o,s=Object.keys(r);for(n=0;n<s.length;++n)"removeListener"!==(o=s[n])&&this.removeAllListeners(o);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=r[e]))this.removeListener(e,t);else if(void 0!==t)for(n=t.length-1;n>=0;n--)this.removeListener(e,t[n]);return this},i.prototype.listeners=function(e){return c(this,e,!0)},i.prototype.rawListeners=function(e){return c(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):m.call(e,t)},i.prototype.listenerCount=m,i.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}});const o=(e,t)=>{if("string"!=typeof t)throw new TypeError('Expected "name" to be a string.');if("string"!=typeof e)throw new TypeError(`Expected "${t}" to be a string, but received ${typeof e}.`)},s=(e,t)=>{if("string"!=typeof t)throw new TypeError('Expected "name" to be a string.');if("function"!=typeof e)throw new TypeError(`Expected "${t}" to be a function, but received ${typeof e}.`)},i=(e,t)=>{if("string"!=typeof t)throw new TypeError('Expected "name" to be a string.');if("object"!=typeof e||null===e||Array.isArray(e))throw new TypeError(`Expected "${t}" to be a plain object, but received ${null===e?"null":Array.isArray(e)?"array":typeof e}.`)},a=new Map;class l extends Error{constructor(e,t,r){if(o(e,"message"),o(t,"url"),"string"!=typeof r)throw new TypeError(`Expected "stage" to be a string, but received ${typeof r}.`);super(e),this.name="MediaLoadingError",this.url=t,this.stage=r}}const d=async e=>{o(e,"str");const t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-1",t);return Array.from(new Uint8Array(r)).map(e=>e.toString(16).padStart(2,"0")).join("").substring(0,8)},u=(e,t="image/jpeg")=>{if(!(e instanceof Uint8Array)&&"string"!=typeof e)throw new TypeError(`Expected "data" to be an instance of Uint8Array or a string, but received ${typeof e}.`);o(t,"format");const r=e=>{const t=URL.createObjectURL(e),r=a.get(t);return a.set(t,"number"==typeof r?r+1:1),t};if(e instanceof Uint8Array)return r(new Blob([e],{type:t}));if("string"==typeof e&&e.startsWith("data:")){const n=e.split(",")[1],o=atob(n),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return r(new Blob([s],{type:t}))}return"string"==typeof e?e:""},h=(e,t)=>{if(i(e,"common"),"boolean"!=typeof t)throw new TypeError('Expected "isPartial" to be a boolean.');const r=e=>t&&void 0===e,n=e=>r(e)||"string"==typeof e||null===e,a=(e,t)=>(s(t,"valueValidator"),!!r(e)||!(!Array.isArray(e)||!e.every(t)));if(!n(e.title))throw new TypeError('Invalid metadata: "title" must be a string or null.');if(!n(e.album))throw new TypeError('Invalid metadata: "album" must be a string or null.');if(!n(e.albumartist))throw new TypeError('Invalid metadata: "albumartist" must be a string or null.');if(!n(e.artist))throw new TypeError('Invalid metadata: "artist" must be a string or null.');if(l=e.year,!r(l)&&"number"!=typeof l&&null!==l)throw new TypeError('Invalid metadata: "year" must be a number or null.');var l;if(!a(e.albumartists,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "albumartists" must be an array of string.');if(!a(e.genre,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "genre" must be an array of string.');if(!a(e.label,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "label" must be an array of string.');if(!a(e.composer,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "composer" must be an array of string.');if(!a(e.artists,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "artists" must be an array of string.');if(!a(e.picture,e=>e&&"object"==typeof e&&(void 0===e.description||"string"==typeof e.description)&&(void 0===e.name||"string"==typeof e.name)&&(void 0===e.type||"string"==typeof e.type)&&"string"==typeof e.format&&(e.data instanceof Uint8Array||"string"==typeof e.data)))throw new TypeError('Invalid metadata: "picture" must be an array of pictures.');const d=(e,t)=>{if(o(e,"name"),!r(t)){if(null==t)throw new TypeError(`Invalid metadata: "${e}" is required.`);if("object"!=typeof t)throw new TypeError(`Invalid metadata: "${e}" must be an object or null.`);if("number"!=typeof t.no&&null!==t.no)throw new TypeError(`Invalid metadata: "${e}.no" must be a number or null.`);if("number"!=typeof t.of&&null!==t.of)throw new TypeError(`Invalid metadata: "${e}.of" must be a number or null.`)}};d("disk",e.disk),d("track",e.track)},p=e=>(i(e,"common"),h(e,!1)),c=e=>t=>{if(t)throw new Error(`This ${e} instance has been destroyed and can no longer be used.`)},m=c("BaseMediaAdapter");class y extends n.EventEmitter{constructor(){if(new.target===y)throw new Error("BaseMediaAdapter is an abstract class and cannot be instantiated directly.");super()}#e=!1;get destroyed(){return this.#e}static canHandle(e){throw new Error('Method "canHandle" must be implemented by the subclass.')}isReady(){throw m(this.#e),new Error('Method "isReady" must be implemented by the subclass.')}async waitIsReady(){throw m(this.#e),new Error('Method "waitIsReady" must be implemented by the subclass.')}canHandle(e){return m(this.#e),y.canHandle(e)}async play(e){throw m(this.#e),new Error('Method "play" must be implemented by the subclass.')}async pause(){throw m(this.#e),new Error('Method "pause" must be implemented by the subclass.')}async stop(){throw m(this.#e),new Error('Method "stop" must be implemented by the subclass.')}async seek(e){throw m(this.#e),new Error('Method "seek" must be implemented by the subclass.')}getCurrentTime(){throw m(this.#e),new Error('Method "getCurrentTime" must be implemented by the subclass.')}getTotalDuration(){throw m(this.#e),new Error('Method "getTotalDuration" must be implemented by the subclass.')}getRemainingTime(){throw m(this.#e),new Error('Method "getRemainingTime" must be implemented by the subclass.')}getPlaybackPercentage(){throw m(this.#e),new Error('Method "getPlaybackPercentage" must be implemented by the subclass.')}getTimeData(){throw m(this.#e),new Error('Method "getTimeData" must be implemented by the subclass.')}setVolume(e){throw m(this.#e),new Error('Method "setVolume" must be implemented by the subclass.')}getVolume(){throw m(this.#e),new Error('Method "getVolume" must be implemented by the subclass.')}async getContentData(){throw m(this.#e),new Error('Method "getContentData" must be implemented by the subclass.')}destroy(){this.#e||(this.removeAllListeners(),this.#e=!0,this.emit("destroyed"))}}function f(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}const w=c("TinyMediaPlayer");class g extends n.EventEmitter{static BaseMediaAdapter=y;static#t="Unknown Artist";static get unknownArtist(){return g.#t}static set unknownArtist(e){if("string"!=typeof e&&"function"!=typeof e)throw new TypeError("unknownArtist must be a string or a function.");g.#t=e}static async parseContent(e,t,r,n,a){return(async(e,t={},r={},n=e=>{if(!(e instanceof Blob))throw new TypeError('Expected "data" to be a Blob.');return new Promise((e,t)=>t(new TypeError("parseFile library not found.")))},a={},p="null")=>{if("string"!=typeof e&&!(e instanceof HTMLMediaElement))throw new TypeError("Source must be a string or an HTMLMediaElement.");if(i(t,"defaultMetadata"),i(r,"metadata"),s(n,"parseFile"),i(a,"callbacks"),a.onProgress&&"function"!=typeof a.onProgress)throw new TypeError("callbacks.onProgress must be a function.");if(a.onError&&"function"!=typeof a.onError)throw new TypeError("callbacks.onError must be a function.");if("string"!=typeof p&&"function"!=typeof p)throw new TypeError("unknownArtist must be a string or a function returning a string.");let c,m="";const y=(t,r)=>{if(o(t,"stage"),void 0!==r&&!(r instanceof Event))throw new TypeError('Expected "event" to be an Event or undefined.');a.onProgress&&a.onProgress({event:r,status:"loading",stage:t,url:m||(e instanceof HTMLMediaElement?e.src:"unknown")})},f=(t,r)=>{if(!(t instanceof Error))throw new TypeError('Expected "error" to be an Error.');o(r,"stage"),a.onError&&a.onError({error:t,url:m||(e instanceof HTMLMediaElement?e.src:"unknown"),stage:r})};try{y("INITIALIZING"),"string"==typeof e?(m=e,c=new Audio(m)):(c=e,m=c.src);try{await new Promise((e,t)=>{const r=e=>y("DOWNLOADING",e),n=()=>{s(),e(void 0)},o=e=>{s(),t(new Error(`HTMLMediaElement failed to load: ${e.message||"Unknown error"}`))},s=()=>{c.removeEventListener("progress",r),c.removeEventListener("loadedmetadata",n),c.removeEventListener("error",o)};c.addEventListener("progress",r),c.addEventListener("loadedmetadata",n),c.addEventListener("error",o),c.readyState>=1&&(s(),e(void 0))}),y("METADATA_LOADED")}catch(e){throw new l(e instanceof Error?e.message:"UNKNOWN ERROR",m,"METADATA")}const w={id:r.id||await d(m),duration:Math.floor(1e3*c.duration),url:m,weight:r.weight??1};let g={};y("EXTRACTING_ID3");try{g=await(async(e,t)=>{o(e,"url"),s(t,"parseFile");try{const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch audio file: ${r.status} ${r.statusText}`);const n=await r.blob(),o=await t(n);if(!o||"object"!=typeof o.common)throw new TypeError('Invalid metadata: "common" property is missing or not an object.');const s=o.common;return(e=>{i(e,"common"),h(e,!0)})(s),{title:s?.title??null,album:s?.album??null,albumartist:s?.albumartist??null,albumartists:s?.albumartists??[],genre:s?.genre??[],label:s?.label??[],composer:s?.composer??[],year:s?.year??null,artist:s?.artist??null,artists:s?.artists??[],disk:s?.disk?{no:s.disk.no,of:s.disk.of}:{no:null,of:null},track:s?.track?{no:s.track.no,of:s.track.of}:{no:null,of:null},picture:s?.picture?.map(e=>({...e,data:u(e.data,e.format)}))??[]}}catch(e){throw e}})(m,n)}catch(e){f(e instanceof Error?e:new Error("Unknown Error"),"ID3"),console.warn(`[TinyAudioUtils] ID3 extraction failed for ${m}. Falling back to filename.`)}const v=e=>{o(e,"url");try{return(e.split(/[?#]/)[0].split("/").pop()??"").replace(/\.[^/.]+$/,"")||"Unknown Track"}catch{return"Unknown Track"}},b={...w,...t,...g,...r,title:g.title||r.title||v(m),artist:g.artist||r.artist||("string"==typeof p?p:String(p()))};return a.onProgress&&a.onProgress({status:"success",stage:"COMPLETE",url:m}),b}catch(e){if(e instanceof l)throw e;{const t=new l(e instanceof Error?e.message:"UNKNOWN ERROR",m,"INITIALIZING");throw f(t,"INITIALIZING"),t}}})(e,t,r,n,a,g.#t)}#e=!1;get destroyed(){return this.#e}#r=new Set;#n=new WeakMap;#o=[];#s=-1;#i="NONE";#a=!1;#l=!1;#d=1;#u;#h;#p;#c=!1;#m;#y;#f=null;#w=null;#g=300;get fadeVolumeSpeed(){return w(this.#e),this.#g}set fadeVolumeSpeed(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("fadeVolumeSpeed must be a number.");if(e<0)throw new RangeError("fadeVolumeSpeed cannot be negative.");this.#g=e,this.emit("fadeVolumeSpeedChange",this.#g)}#v=2e3;get prevClickTimeoutDuration(){return w(this.#e),this.#v}set prevClickTimeoutDuration(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("prevClickTimeoutDuration must be a number.");if(e<0)throw new RangeError("prevClickTimeoutDuration cannot be negative.");this.#v=e,this.emit("prevClickTimeoutDurationChange",this.#v)}get repeatCurrentOnPrev(){return w(this.#e),this.#p}set repeatCurrentOnPrev(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("repeatCurrentOnPrev must be a boolean.");this.#p=e,this.emit("repeatCurrentOnPrevChange",this.#p)}get smoothPlayPauseVolume(){return w(this.#e),this.#m}set smoothPlayPauseVolume(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("smoothPlayPauseVolume must be a boolean.");this.#m=e,this.emit("smoothPlayPauseVolumeChange",this.#m)}get smoothStopVolume(){return w(this.#e),this.#y}set smoothStopVolume(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("smoothStopVolume must be a boolean.");this.#y=e,this.emit("smoothStopVolumeChange",this.#y)}constructor(e={}){if(super(),!f(e))throw new TypeError("Options must be a non-null object.");if(void 0!==e.persistVolume){if("boolean"!=typeof e.persistVolume)throw new TypeError("persistVolume must be a boolean.");this.#u=e.persistVolume}else this.#u=!1;if(void 0!==e.volumeStorageKey){if("string"!=typeof e.volumeStorageKey)throw new TypeError("volumeStorageKey must be a string.");this.#h=e.volumeStorageKey}else this.#h="tiny_media_player_volume";if(void 0!==e.repeatCurrentOnPrev){if("boolean"!=typeof e.repeatCurrentOnPrev)throw new TypeError("repeatCurrentOnPrev must be a boolean.");this.#p=e.repeatCurrentOnPrev}else this.#p=!1;if(void 0!==e.smoothPlayPauseVolume){if("boolean"!=typeof e.smoothPlayPauseVolume)throw new TypeError("smoothPlayPauseVolume must be a boolean.");this.#m=e.smoothPlayPauseVolume}else this.#m=!1;if(void 0!==e.smoothStopVolume){if("boolean"!=typeof e.smoothStopVolume)throw new TypeError("smoothStopVolume must be a boolean.");this.#y=e.smoothStopVolume}else this.#y=!1;this.#u&&this.#b()}#b(){try{if("undefined"!=typeof window&&window.localStorage){const e=window.localStorage.getItem(this.#h);if(null!==e){const t=parseFloat(e);!isNaN(t)&&t>=0&&t<=1&&(this.#d=t)}}}catch(e){console.warn("[TinyMediaPlayer] Failed to read volume from localStorage.",e)}}#E(){try{this.#u&&"undefined"!=typeof window&&window.localStorage&&window.localStorage.setItem(this.#h,this.#d.toString())}catch(e){console.warn("[TinyMediaPlayer] Failed to save volume to localStorage.",e)}}_getWeightedRandomIndex(){if(0===this.#o.length)return-1;if(1===this.#o.length)return 0;let e=0;for(let t=0;t<this.#o.length;t++){if(t===this.#s)continue;const r=this.#o[t];e+="number"==typeof r.weight&&r.weight>0?r.weight:1}let t=Math.random()*e;for(let e=0;e<this.#o.length;e++){if(e===this.#s)continue;const r=this.#o[e],n="number"==typeof r.weight&&r.weight>0?r.weight:1;if(t<n)return e;t-=n}return this.#s===this.#o.length-1?0:this.#o.length-1}async#T(e){this.#f&&this.#f.abort(),this.#f=new AbortController;const{signal:t}=this.#f,r=this.#A();if(!r)return;const n=r.getVolume(),o=performance.now(),s=this.#g;return new Promise(i=>{const a=l=>{if(t.aborted)return i();const d=l-o,u=Math.min(d/s,1),h=n+(e-n)*u,p=Math.max(0,Math.min(1,h));r.setVolume(p),u<1?requestAnimationFrame(a):(r.setVolume(e),i())};requestAnimationFrame(a)})}get playlist(){return w(this.#e),[...this.#o]}set playlist(e){if(w(this.#e),!Array.isArray(e))throw new TypeError("Playlist must be an array of MediaContent objects.");e.forEach(e=>p(e));const t=this.#l;let r=null;if(-1!==this.#s&&this.#o.length>0)try{r=this.#A()}catch(e){}this.#o=e,this.emit("playlistUpdate",this.playlist),0===this.#o.length?this.#s=-1:(this.#s>=this.#o.length||-1===this.#s)&&(this.#s=0),this.emit("trackChange",this.#s),t&&(async()=>{try{r&&await r.stop(),-1!==this.#s&&await this.play()}catch(e){console.warn("[TinyMediaPlayer] Background transition error on playlist update:",e)}})()}get currentIndex(){return w(this.#e),this.#s}set currentIndex(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Current index must be a number.");if(e<-1||e>=this.#o.length&&this.#o.length>0)throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);if(this.#s===e)return;const t=this.#l;let r=null;if(-1!==this.#s&&this.#o.length>0)try{r=this.#A()}catch(e){}this.#s=e,this.emit("trackChange",this.#s),t&&(async()=>{try{r&&await r.stop(),-1!==this.#s&&await this.play()}catch(e){console.warn("[TinyMediaPlayer] Background transition error on index update:",e)}})()}get loopMode(){return w(this.#e),this.#i}set loopMode(e){w(this.#e);const t=["NONE","TRACK","PLAYLIST"];if(!t.includes(e))throw new TypeError(`Loop mode must be one of: ${t.join(", ")}.`);this.#i=e,this.emit("loopModeChange",this.#i)}get isRandom(){return w(this.#e),this.#a}set isRandom(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("Random mode state must be a boolean.");this.#a=e,this.emit("randomModeChange",this.#a)}get isPlaying(){return w(this.#e),this.#l}get volume(){return w(this.#e),this.#d}set volume(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Volume must be a number.");if(e<0||e>1)throw new RangeError("Volume must be tightly constrained between 0.0 and 1.0.");if(this.#f&&this.#f.abort(),this.#d=e,this.#E(),this.emit("volumeChange",this.#d),-1!==this.#s&&this.#o.length>0)try{const e=this.#A();e&&e.setVolume(this.#d)}catch(e){}}get persistVolume(){return w(this.#e),this.#u}set persistVolume(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("Persist volume parameter must be a boolean.");this.#u=e,e&&this.#E()}get volumeStorageKey(){return w(this.#e),this.#h}set volumeStorageKey(e){if(w(this.#e),"string"!=typeof e)throw new TypeError("Volume storage key must be a string.");if(""===e.trim())throw new TypeError("Volume storage key cannot be an empty string.");const t=this.#h;this.#h=e;try{this.#u&&"undefined"!=typeof window&&window.localStorage&&(window.localStorage.removeItem(t),this.#E())}catch(e){console.warn("[TinyMediaPlayer] Failed to migrate volume storage key.",e)}}get adapters(){return Array.from(this.#r)}get adaptersSize(){return this.#r.size}static#x=["timeupdate","ended"];static get defaultAdapterEventNames(){return structuredClone(g.#x)}static set defaultAdapterEventNames(e){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError("TinyMediaPlayer.defaultAdapterEventNames must be an array of strings.");g.#x=[...e]}#I=new Set(g.defaultAdapterEventNames);#P(e){const t=this.#n.get(e);t&&(this.#I.forEach(r=>{const n=t.get(r);n&&e.off(r,n)}),t.clear(),this.#n.delete(e))}registerAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");const t=new Map;this.#n.set(e,t),this.#I.forEach(t=>{this.#C(e,t)}),this.#r.add(e)}removeAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");return this.#P(e),this.#r.delete(e)}destroyAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");this.#P(e);const t=this.#r.delete(e);return t&&e.destroy(),t}hasAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");return this.#r.has(e)}destroyAllAdapters(){w(this.#e),this.#r.forEach(e=>{this.#P(e),e.destroy()}),this.#r.clear()}clearAdapters(){w(this.#e),this.#r.forEach(e=>this.#P(e)),this.#r.clear()}getMediaAdapter(e){if(!f(e))throw new TypeError("Content must be a valid object.");for(const t of this.#r.values())if(t.canHandle(e))return t;return null}#A(){if(-1===this.#s||0===this.#o.length)return null;const e=this.#o[this.#s],t=this.getMediaAdapter(e);if(t)return t;throw new Error(`No compatible adapter found for content ID: ${e.id}.`)}addAdapterEvent(e){if(w(this.#e),"string"!=typeof e)throw new TypeError("Event name must be a string.");this.#I.has(e)||(this.#I.add(e),this.#r.forEach(t=>{this.#C(t,e)}))}removeAdapterEvent(e){if(w(this.#e),"string"!=typeof e)throw new TypeError("Event name must be a string.");this.#I.has(e)&&(this.#I.delete(e),this.#r.forEach(t=>{this.#k(t,e)}))}resetAdapterEvents(){w(this.#e);const e=g.defaultAdapterEventNames,t=Array.from(this.#I);for(const r of t)e.includes(r)||this.removeAdapterEvent(r);for(const t of e)this.#I.has(t)||this.addAdapterEvent(t)}#C(e,t){const r=this.#n.get(e);if(!r)return;const n=(...e)=>{this.#e||this.emit(t,...e)};e.on(t,n),r.set(t,n)}#k(e,t){const r=this.#n.get(e);if(!r)return;const n=r.get(t);n&&(e.off(t,n),r.delete(t))}addTrack(e){if(w(this.#e),!f(e)||"string"!=typeof e.url)throw new TypeError("Track content must be a valid MediaContent object containing a URL.");const t={id:"",title:"",artist:"",url:"",duration:0,weight:1,title:null,album:null,albumartist:null,albumartists:[],genre:[],label:[],composer:[],year:null,artist:null,artists:[],disk:{no:null,of:null},track:{no:null,of:null},picture:[],...e};p(t);const r=this.#o.push(t);return-1===this.#s&&(this.#s=0,this.emit("trackChange",this.#s)),this.emit("playlistUpdate",this.playlist),r}existsTrack(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Index must be a number.");return e>=0&&e<this.#o.length}getTrack(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Index must be a number.");if(!this.existsTrack(e))throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);return this.#o[e]}async removeTrack(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Index must be a number.");if(!this.existsTrack(e))throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);e===this.#s?(await this.stop(),this.#o.splice(e,1),0===this.#o.length?this.#s=-1:this.#s>=this.#o.length&&(this.#s=0),this.emit("trackChange",this.#s)):(this.#o.splice(e,1),e<this.#s&&(this.#s-=1,this.emit("trackChange",this.#s))),this.emit("playlistUpdate",this.playlist)}searchTrack(e){if(w(this.#e),"string"!=typeof e&&"function"!=typeof e)throw new TypeError("Search query must be a string or a boolean evaluation function.");const t=[];for(let r=0;r<this.#o.length;r++){const n=this.#o[r];let o=!1;if("function"==typeof e)o=Boolean(e(n));else{const t=e.toLowerCase(),r=n.title&&n.title.toLowerCase().includes(t),s=n.artist&&n.artist.toLowerCase().includes(t),i=n.album&&n.album.toLowerCase().includes(t);o=Boolean(r||s||i)}o&&t.push({track:n,index:r})}return t}async clearPlaylist(){w(this.#e),await this.stop(),this.#o=[],this.#s=-1,this.emit("playlistUpdate",this.playlist),this.emit("trackChange",this.#s)}async play(){w(this.#e);const e=this.#A();e&&(this.#m?await this.#T(this.#d):e.setVolume(this.#d),await e.play(this.#o[this.#s]),this.#l=!0,this.emit("play",this.#s))}async pause(){w(this.#e);const e=this.#A();e&&(this.#m&&await this.#T(0),await e.pause(),this.#l=!1,this.emit("pause",this.#s))}async stop(){w(this.#e);const e=this.#A();e&&(this.#y&&await this.#T(0),await e.stop(),this.#l=!1,this.emit("stop",this.#s))}async next(){if(w(this.#e),0!==this.#o.length)if(await this.stop(),"TRACK"!==this.#i){if(this.#a)this.#s=this._getWeightedRandomIndex();else{let e=this.#s+1;if(e>=this.#o.length){if("PLAYLIST"!==this.#i)return;e=0}this.#s=e}this.emit("trackChange",this.#s),await this.play()}else await this.play()}async prev(){if(w(this.#e),0!==this.#o.length){if(this.#p&&!this.#c)return this.#c=!0,this.#w&&clearTimeout(this.#w),this.#w=setTimeout(()=>{this.#c=!1,this.#w=null},2e3),await this.stop(),void await this.play();if(this.#w&&(clearTimeout(this.#w),this.#w=null),this.#c=!1,await this.stop(),this.#a)this.#s=this._getWeightedRandomIndex();else{let e=this.#s-1;if(e<0){if("PLAYLIST"!==this.#i)return;e=this.#o.length-1}this.#s=e}this.emit("trackChange",this.#s),await this.play()}}async seek(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Seek time must be a number in milliseconds.");if(e<0)throw new RangeError("Seek time cannot be negative.");const t=this.#A();t&&(await t.seek(e),this.emit("seek",e))}async step(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Step amount must be a number in milliseconds.");const t=this.#A();if(!t)return;let r=t.getCurrentTime()+e;r<0&&(r=0),await this.seek(r)}getCurrentTime(){w(this.#e);try{const e=this.#A();return e?e.getCurrentTime():0}catch{return 0}}getTotalDuration(){w(this.#e);try{const e=this.#A();return e?e.getTotalDuration():0}catch{return 0}}getRemainingTime(){w(this.#e);try{const e=this.#A();return e?e.getRemainingTime():0}catch{return 0}}getPlaybackPercentage(){w(this.#e);try{const e=this.#A();return e?e.getPlaybackPercentage():0}catch{return 0}}async getContentData(){w(this.#e);const e={id:"",createdAt:"",artistId:"",artistName:"",description:"",title:"",duration:0,avatar:"",url:""};try{const t=this.#A();return t?t.getContentData():e}catch{return e}}async waitIsReady(){w(this.#e);const e=this.#A();if(e)return e.waitIsReady()}async destroy(){if(!this.#e){try{this.#l&&await this.stop()}catch(e){console.warn("[TinyMediaPlayer] Non-fatal error during playback termination:",e)}this.#w&&clearTimeout(this.#w),this.#o=[],this.#s=-1,this.#l=!1,this.#c=!1,this.destroyAllAdapters(),this.removeAllListeners(),this.#I.clear(),this.#e=!0,this.emit("destroyed")}}}const v=g}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.d=(e,t)=>{if(Array.isArray(t))for(var n=0;n<t.length;){var o=t[n++],s=t[n++];r.o(e,o)?0===s&&n++:0===s?Object.defineProperty(e,o,{enumerable:!0,value:t[n++]}):Object.defineProperty(e,o,{enumerable:!0,get:s})}else for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.cjs=e=>{const t={exports:{}};return e.call(t.exports,t,t.exports),t.exports};let n=r(843);window.TinyMediaPlayer=n.TinyMediaPlayer})();
|
|
1
|
+
(()=>{"use strict";var e={843(e,t,r){r.d(t,{TinyMediaPlayer:()=>v});var n=r.cjs(function(e,t){var r,n="object"==typeof Reflect?Reflect:null,o=n&&"function"==typeof n.apply?n.apply:function(e,t,r){return Function.prototype.apply.call(e,t,r)};r=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var s=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise(function(r,n){function o(r){e.removeListener(t,s),n(r)}function s(){"function"==typeof e.removeListener&&e.removeListener("error",o),r([].slice.call(arguments))}f(e,t,s,{once:!0}),"error"!==t&&function(e,t){"function"==typeof e.on&&f(e,"error",t,{once:!0})}(e,o)})},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var a=10;function l(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function d(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function u(e,t,r,n){var o,s,i,a;if(l(r),void 0===(s=e._events)?(s=e._events=Object.create(null),e._eventsCount=0):(void 0!==s.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),s=e._events),i=s[t]),void 0===i)i=s[t]=r,++e._eventsCount;else if("function"==typeof i?i=s[t]=n?[r,i]:[i,r]:n?i.unshift(r):i.push(r),(o=d(e))>0&&i.length>o&&!i.warned){i.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+i.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=i.length,a=u,console&&console.warn&&console.warn(a)}return e}function h(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},o=h.bind(n);return o.listener=r,n.wrapFn=o,o}function c(e,t,r){var n=e._events;if(void 0===n)return[];var o=n[t];return void 0===o?[]:"function"==typeof o?r?[o.listener||o]:[o]:r?function(e){for(var t=new Array(e.length),r=0;r<t.length;++r)t[r]=e[r].listener||e[r];return t}(o):y(o,o.length)}function m(e){var t=this._events;if(void 0!==t){var r=t[e];if("function"==typeof r)return 1;if(void 0!==r)return r.length}return 0}function y(e,t){for(var r=new Array(t),n=0;n<t;++n)r[n]=e[n];return r}function f(e,t,r,n){if("function"==typeof e.on)n.once?e.once(t,r):e.on(t,r);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,function o(s){n.once&&e.removeEventListener(t,o),r(s)})}}Object.defineProperty(i,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e||e<0||s(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");a=e}}),i.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},i.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||s(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},i.prototype.getMaxListeners=function(){return d(this)},i.prototype.emit=function(e){for(var t=[],r=1;r<arguments.length;r++)t.push(arguments[r]);var n="error"===e,s=this._events;if(void 0!==s)n=n&&void 0===s.error;else if(!n)return!1;if(n){var i;if(t.length>0&&(i=t[0]),i instanceof Error)throw i;var a=new Error("Unhandled error."+(i?" ("+i.message+")":""));throw a.context=i,a}var l=s[e];if(void 0===l)return!1;if("function"==typeof l)o(l,this,t);else{var d=l.length,u=y(l,d);for(r=0;r<d;++r)o(u[r],this,t)}return!0},i.prototype.addListener=function(e,t){return u(this,e,t,!1)},i.prototype.on=i.prototype.addListener,i.prototype.prependListener=function(e,t){return u(this,e,t,!0)},i.prototype.once=function(e,t){return l(t),this.on(e,p(this,e,t)),this},i.prototype.prependOnceListener=function(e,t){return l(t),this.prependListener(e,p(this,e,t)),this},i.prototype.removeListener=function(e,t){var r,n,o,s,i;if(l(t),void 0===(n=this._events))return this;if(void 0===(r=n[e]))return this;if(r===t||r.listener===t)0===--this._eventsCount?this._events=Object.create(null):(delete n[e],n.removeListener&&this.emit("removeListener",e,r.listener||t));else if("function"!=typeof r){for(o=-1,s=r.length-1;s>=0;s--)if(r[s]===t||r[s].listener===t){i=r[s].listener,o=s;break}if(o<0)return this;0===o?r.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(r,o),1===r.length&&(n[e]=r[0]),void 0!==n.removeListener&&this.emit("removeListener",e,i||t)}return this},i.prototype.off=i.prototype.removeListener,i.prototype.removeAllListeners=function(e){var t,r,n;if(void 0===(r=this._events))return this;if(void 0===r.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==r[e]&&(0===--this._eventsCount?this._events=Object.create(null):delete r[e]),this;if(0===arguments.length){var o,s=Object.keys(r);for(n=0;n<s.length;++n)"removeListener"!==(o=s[n])&&this.removeAllListeners(o);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=r[e]))this.removeListener(e,t);else if(void 0!==t)for(n=t.length-1;n>=0;n--)this.removeListener(e,t[n]);return this},i.prototype.listeners=function(e){return c(this,e,!0)},i.prototype.rawListeners=function(e){return c(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):m.call(e,t)},i.prototype.listenerCount=m,i.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}});const o=(e,t)=>{if("string"!=typeof t)throw new TypeError('Expected "name" to be a string.');if("string"!=typeof e)throw new TypeError(`Expected "${t}" to be a string, but received ${typeof e}.`)},s=(e,t)=>{if("string"!=typeof t)throw new TypeError('Expected "name" to be a string.');if("function"!=typeof e)throw new TypeError(`Expected "${t}" to be a function, but received ${typeof e}.`)},i=(e,t)=>{if("string"!=typeof t)throw new TypeError('Expected "name" to be a string.');if("object"!=typeof e||null===e||Array.isArray(e))throw new TypeError(`Expected "${t}" to be a plain object, but received ${null===e?"null":Array.isArray(e)?"array":typeof e}.`)},a=new Map;class l extends Error{constructor(e,t,r){if(o(e,"message"),o(t,"url"),"string"!=typeof r)throw new TypeError(`Expected "stage" to be a string, but received ${typeof r}.`);super(e),this.name="MediaLoadingError",this.url=t,this.stage=r}}const d=async e=>{o(e,"str");const t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-1",t);return Array.from(new Uint8Array(r)).map(e=>e.toString(16).padStart(2,"0")).join("").substring(0,8)},u=(e,t="image/jpeg")=>{if(!(e instanceof Uint8Array)&&"string"!=typeof e)throw new TypeError(`Expected "data" to be an instance of Uint8Array or a string, but received ${typeof e}.`);o(t,"format");const r=e=>{const t=URL.createObjectURL(e),r=a.get(t);return a.set(t,"number"==typeof r?r+1:1),t};if(e instanceof Uint8Array)return r(new Blob([e],{type:t}));if("string"==typeof e&&e.startsWith("data:")){const n=e.split(",")[1],o=atob(n),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return r(new Blob([s],{type:t}))}return"string"==typeof e?e:""},h=(e,t)=>{if(i(e,"common"),"boolean"!=typeof t)throw new TypeError('Expected "isPartial" to be a boolean.');const r=e=>t&&void 0===e,n=e=>r(e)||"string"==typeof e||null===e,a=(e,t)=>(s(t,"valueValidator"),!!r(e)||!(!Array.isArray(e)||!e.every(t)));if(!n(e.title))throw new TypeError('Invalid metadata: "title" must be a string or null.');if(!n(e.album))throw new TypeError('Invalid metadata: "album" must be a string or null.');if(!n(e.albumartist))throw new TypeError('Invalid metadata: "albumartist" must be a string or null.');if(!n(e.artist))throw new TypeError('Invalid metadata: "artist" must be a string or null.');if(l=e.year,!r(l)&&"number"!=typeof l&&null!==l)throw new TypeError('Invalid metadata: "year" must be a number or null.');var l;if(!a(e.albumartists,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "albumartists" must be an array of string.');if(!a(e.genre,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "genre" must be an array of string.');if(!a(e.label,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "label" must be an array of string.');if(!a(e.composer,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "composer" must be an array of string.');if(!a(e.artists,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "artists" must be an array of string.');if(!a(e.picture,e=>e&&"object"==typeof e&&(void 0===e.description||"string"==typeof e.description)&&(void 0===e.name||"string"==typeof e.name)&&(void 0===e.type||"string"==typeof e.type)&&"string"==typeof e.format&&(e.data instanceof Uint8Array||"string"==typeof e.data)))throw new TypeError('Invalid metadata: "picture" must be an array of pictures.');const d=(e,t)=>{if(o(e,"name"),!r(t)){if(null==t)throw new TypeError(`Invalid metadata: "${e}" is required.`);if("object"!=typeof t)throw new TypeError(`Invalid metadata: "${e}" must be an object or null.`);if("number"!=typeof t.no&&null!==t.no)throw new TypeError(`Invalid metadata: "${e}.no" must be a number or null.`);if("number"!=typeof t.of&&null!==t.of)throw new TypeError(`Invalid metadata: "${e}.of" must be a number or null.`)}};d("disk",e.disk),d("track",e.track)},p=e=>(i(e,"common"),h(e,!1)),c=e=>t=>{if(t)throw new Error(`This ${e} instance has been destroyed and can no longer be used.`)},m=c("BaseMediaAdapter");class y extends n.EventEmitter{constructor(){if(new.target===y)throw new Error("BaseMediaAdapter is an abstract class and cannot be instantiated directly.");super()}#e=!1;get destroyed(){return this.#e}static canHandle(e){throw new Error('Method "canHandle" must be implemented by the subclass.')}isReady(){throw m(this.#e),new Error('Method "isReady" must be implemented by the subclass.')}async waitIsReady(){throw m(this.#e),new Error('Method "waitIsReady" must be implemented by the subclass.')}canHandle(e){return m(this.#e),y.canHandle(e)}async play(e){throw m(this.#e),new Error('Method "play" must be implemented by the subclass.')}async pause(){throw m(this.#e),new Error('Method "pause" must be implemented by the subclass.')}async stop(){throw m(this.#e),new Error('Method "stop" must be implemented by the subclass.')}async seek(e){throw m(this.#e),new Error('Method "seek" must be implemented by the subclass.')}isMuted(){throw m(this.#e),new Error('Method "isMuted" must be implemented by the subclass.')}async mute(){throw m(this.#e),new Error('Method "mute" must be implemented by the subclass.')}async unMute(){throw m(this.#e),new Error('Method "unMute" must be implemented by the subclass.')}getCurrentTime(){throw m(this.#e),new Error('Method "getCurrentTime" must be implemented by the subclass.')}getTotalDuration(){throw m(this.#e),new Error('Method "getTotalDuration" must be implemented by the subclass.')}getRemainingTime(){throw m(this.#e),new Error('Method "getRemainingTime" must be implemented by the subclass.')}getPlaybackPercentage(){throw m(this.#e),new Error('Method "getPlaybackPercentage" must be implemented by the subclass.')}getTimeData(){throw m(this.#e),new Error('Method "getTimeData" must be implemented by the subclass.')}setVolume(e){throw m(this.#e),new Error('Method "setVolume" must be implemented by the subclass.')}getVolume(){throw m(this.#e),new Error('Method "getVolume" must be implemented by the subclass.')}async getContentData(){throw m(this.#e),new Error('Method "getContentData" must be implemented by the subclass.')}destroy(){this.#e||(this.removeAllListeners(),this.#e=!0,this.emit("destroyed"))}}function f(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}const w=c("TinyMediaPlayer");class g extends n.EventEmitter{static BaseMediaAdapter=y;static#t="Unknown Artist";static get unknownArtist(){return g.#t}static set unknownArtist(e){if("string"!=typeof e&&"function"!=typeof e)throw new TypeError("unknownArtist must be a string or a function.");g.#t=e}static async parseContent(e,t,r,n,a){return(async(e,t={},r={},n=e=>{if(!(e instanceof Blob))throw new TypeError('Expected "data" to be a Blob.');return new Promise((e,t)=>t(new TypeError("parseFile library not found.")))},a={},p="null")=>{if("string"!=typeof e&&!(e instanceof HTMLMediaElement))throw new TypeError("Source must be a string or an HTMLMediaElement.");if(i(t,"defaultMetadata"),i(r,"metadata"),s(n,"parseFile"),i(a,"callbacks"),a.onProgress&&"function"!=typeof a.onProgress)throw new TypeError("callbacks.onProgress must be a function.");if(a.onError&&"function"!=typeof a.onError)throw new TypeError("callbacks.onError must be a function.");if("string"!=typeof p&&"function"!=typeof p)throw new TypeError("unknownArtist must be a string or a function returning a string.");let c,m="";const y=(t,r)=>{if(o(t,"stage"),void 0!==r&&!(r instanceof Event))throw new TypeError('Expected "event" to be an Event or undefined.');a.onProgress&&a.onProgress({event:r,status:"loading",stage:t,url:m||(e instanceof HTMLMediaElement?e.src:"unknown")})},f=(t,r)=>{if(!(t instanceof Error))throw new TypeError('Expected "error" to be an Error.');o(r,"stage"),a.onError&&a.onError({error:t,url:m||(e instanceof HTMLMediaElement?e.src:"unknown"),stage:r})};try{y("INITIALIZING"),"string"==typeof e?(m=e,c=new Audio(m)):(c=e,m=c.src);try{await new Promise((e,t)=>{const r=e=>y("DOWNLOADING",e),n=()=>{s(),e(void 0)},o=e=>{s(),t(new Error(`HTMLMediaElement failed to load: ${e.message||"Unknown error"}`))},s=()=>{c.removeEventListener("progress",r),c.removeEventListener("loadedmetadata",n),c.removeEventListener("error",o)};c.addEventListener("progress",r),c.addEventListener("loadedmetadata",n),c.addEventListener("error",o),c.readyState>=1&&(s(),e(void 0))}),y("METADATA_LOADED")}catch(e){throw new l(e instanceof Error?e.message:"UNKNOWN ERROR",m,"METADATA")}const w={id:r.id||await d(m),duration:Math.floor(1e3*c.duration),url:m,weight:r.weight??1};let g={};y("EXTRACTING_ID3");try{g=await(async(e,t)=>{o(e,"url"),s(t,"parseFile");try{const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch audio file: ${r.status} ${r.statusText}`);const n=await r.blob(),o=await t(n);if(!o||"object"!=typeof o.common)throw new TypeError('Invalid metadata: "common" property is missing or not an object.');const s=o.common;return(e=>{i(e,"common"),h(e,!0)})(s),{title:s?.title??null,album:s?.album??null,albumartist:s?.albumartist??null,albumartists:s?.albumartists??[],genre:s?.genre??[],label:s?.label??[],composer:s?.composer??[],year:s?.year??null,artist:s?.artist??null,artists:s?.artists??[],disk:s?.disk?{no:s.disk.no,of:s.disk.of}:{no:null,of:null},track:s?.track?{no:s.track.no,of:s.track.of}:{no:null,of:null},picture:s?.picture?.map(e=>({...e,data:u(e.data,e.format)}))??[]}}catch(e){throw e}})(m,n)}catch(e){f(e instanceof Error?e:new Error("Unknown Error"),"ID3"),console.warn(`[TinyAudioUtils] ID3 extraction failed for ${m}. Falling back to filename.`)}const v=e=>{o(e,"url");try{return(e.split(/[?#]/)[0].split("/").pop()??"").replace(/\.[^/.]+$/,"")||"Unknown Track"}catch{return"Unknown Track"}},b={...w,...t,...g,...r,title:g.title||r.title||v(m),artist:g.artist||r.artist||("string"==typeof p?p:String(p()))};return a.onProgress&&a.onProgress({status:"success",stage:"COMPLETE",url:m}),b}catch(e){if(e instanceof l)throw e;{const t=new l(e instanceof Error?e.message:"UNKNOWN ERROR",m,"INITIALIZING");throw f(t,"INITIALIZING"),t}}})(e,t,r,n,a,g.#t)}#e=!1;get destroyed(){return this.#e}#r=new Set;#n=new WeakMap;#o=[];#s=-1;#i="NONE";#a=!1;#l=!1;#d=!1;#u=1;#h;#p;#c;#m=!1;#y;#f;#w=null;#g=null;#v=300;get fadeVolumeSpeed(){return w(this.#e),this.#v}set fadeVolumeSpeed(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("fadeVolumeSpeed must be a number.");if(e<0)throw new RangeError("fadeVolumeSpeed cannot be negative.");this.#v=e,this.emit("fadeVolumeSpeedChange",this.#v)}#b=2e3;get prevClickTimeoutDuration(){return w(this.#e),this.#b}set prevClickTimeoutDuration(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("prevClickTimeoutDuration must be a number.");if(e<0)throw new RangeError("prevClickTimeoutDuration cannot be negative.");this.#b=e,this.emit("prevClickTimeoutDurationChange",this.#b)}get repeatCurrentOnPrev(){return w(this.#e),this.#c}set repeatCurrentOnPrev(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("repeatCurrentOnPrev must be a boolean.");this.#c=e,this.emit("repeatCurrentOnPrevChange",this.#c)}get smoothPlayPauseVolume(){return w(this.#e),this.#y}set smoothPlayPauseVolume(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("smoothPlayPauseVolume must be a boolean.");this.#y=e,this.emit("smoothPlayPauseVolumeChange",this.#y)}get smoothStopVolume(){return w(this.#e),this.#f}set smoothStopVolume(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("smoothStopVolume must be a boolean.");this.#f=e,this.emit("smoothStopVolumeChange",this.#f)}constructor(e={}){if(super(),!f(e))throw new TypeError("Options must be a non-null object.");if(void 0!==e.persistVolume){if("boolean"!=typeof e.persistVolume)throw new TypeError("persistVolume must be a boolean.");this.#h=e.persistVolume}else this.#h=!1;if(void 0!==e.volumeStorageKey){if("string"!=typeof e.volumeStorageKey)throw new TypeError("volumeStorageKey must be a string.");this.#p=e.volumeStorageKey}else this.#p="tiny_media_player_volume";if(void 0!==e.repeatCurrentOnPrev){if("boolean"!=typeof e.repeatCurrentOnPrev)throw new TypeError("repeatCurrentOnPrev must be a boolean.");this.#c=e.repeatCurrentOnPrev}else this.#c=!1;if(void 0!==e.smoothPlayPauseVolume){if("boolean"!=typeof e.smoothPlayPauseVolume)throw new TypeError("smoothPlayPauseVolume must be a boolean.");this.#y=e.smoothPlayPauseVolume}else this.#y=!1;if(void 0!==e.smoothStopVolume){if("boolean"!=typeof e.smoothStopVolume)throw new TypeError("smoothStopVolume must be a boolean.");this.#f=e.smoothStopVolume}else this.#f=!1;this.#h&&this.#E()}#E(){try{if("undefined"!=typeof window&&window.localStorage){const e=window.localStorage.getItem(this.#p);if(null!==e){const t=parseFloat(e);!isNaN(t)&&t>=0&&t<=1&&(this.#u=t)}}}catch(e){console.warn("[TinyMediaPlayer] Failed to read volume from localStorage.",e)}}#T(){try{this.#h&&"undefined"!=typeof window&&window.localStorage&&window.localStorage.setItem(this.#p,this.#u.toString())}catch(e){console.warn("[TinyMediaPlayer] Failed to save volume to localStorage.",e)}}_getWeightedRandomIndex(){if(0===this.#o.length)return-1;if(1===this.#o.length)return 0;let e=0;for(let t=0;t<this.#o.length;t++){if(t===this.#s)continue;const r=this.#o[t];e+="number"==typeof r.weight&&r.weight>0?r.weight:1}let t=Math.random()*e;for(let e=0;e<this.#o.length;e++){if(e===this.#s)continue;const r=this.#o[e],n="number"==typeof r.weight&&r.weight>0?r.weight:1;if(t<n)return e;t-=n}return this.#s===this.#o.length-1?0:this.#o.length-1}async#A(e){this.#w&&this.#w.abort(),this.#w=new AbortController;const{signal:t}=this.#w,r=this.#x();if(!r)return;const n=r.getVolume(),o=performance.now(),s=this.#v;return new Promise(i=>{const a=l=>{if(t.aborted)return i();const d=l-o,u=Math.min(d/s,1),h=n+(e-n)*u,p=Math.max(0,Math.min(1,h));r.setVolume(p),u<1?requestAnimationFrame(a):(r.setVolume(e),i())};requestAnimationFrame(a)})}get playlist(){return w(this.#e),[...this.#o]}set playlist(e){if(w(this.#e),!Array.isArray(e))throw new TypeError("Playlist must be an array of MediaContent objects.");e.forEach(e=>p(e));const t=this.#l;let r=null;if(-1!==this.#s&&this.#o.length>0)try{r=this.#x()}catch(e){}this.#o=e,this.emit("playlistUpdate",this.playlist),0===this.#o.length?this.#s=-1:(this.#s>=this.#o.length||-1===this.#s)&&(this.#s=0),this.emit("trackChange",this.#s),t&&(async()=>{try{r&&await r.stop(),-1!==this.#s&&await this.play()}catch(e){console.warn("[TinyMediaPlayer] Background transition error on playlist update:",e)}})()}get currentIndex(){return w(this.#e),this.#s}set currentIndex(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Current index must be a number.");if(e<-1||e>=this.#o.length&&this.#o.length>0)throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);if(this.#s===e)return;const t=this.#l;let r=null;if(-1!==this.#s&&this.#o.length>0)try{r=this.#x()}catch(e){}this.#s=e,this.emit("trackChange",this.#s),t&&(async()=>{try{r&&await r.stop(),-1!==this.#s&&await this.play()}catch(e){console.warn("[TinyMediaPlayer] Background transition error on index update:",e)}})()}get loopMode(){return w(this.#e),this.#i}set loopMode(e){w(this.#e);const t=["NONE","TRACK","PLAYLIST"];if(!t.includes(e))throw new TypeError(`Loop mode must be one of: ${t.join(", ")}.`);this.#i=e,this.emit("loopModeChange",this.#i)}get isRandom(){return w(this.#e),this.#a}set isRandom(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("Random mode state must be a boolean.");this.#a=e,this.emit("randomModeChange",this.#a)}get isPlaying(){return w(this.#e),this.#l}get volume(){return w(this.#e),this.#u}set volume(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Volume must be a number.");if(e<0||e>1)throw new RangeError("Volume must be tightly constrained between 0.0 and 1.0.");if(this.#w&&this.#w.abort(),this.#u=e,this.#T(),this.emit("volumeChange",this.#u),-1!==this.#s&&this.#o.length>0)try{const e=this.#x();e&&e.setVolume(this.#u)}catch(e){}}get persistVolume(){return w(this.#e),this.#h}set persistVolume(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("Persist volume parameter must be a boolean.");this.#h=e,e&&this.#T()}get volumeStorageKey(){return w(this.#e),this.#p}set volumeStorageKey(e){if(w(this.#e),"string"!=typeof e)throw new TypeError("Volume storage key must be a string.");if(""===e.trim())throw new TypeError("Volume storage key cannot be an empty string.");const t=this.#p;this.#p=e;try{this.#h&&"undefined"!=typeof window&&window.localStorage&&(window.localStorage.removeItem(t),this.#T())}catch(e){console.warn("[TinyMediaPlayer] Failed to migrate volume storage key.",e)}}get isMuted(){return w(this.#e),this.#d}set isMuted(e){if(w(this.#e),"boolean"!=typeof e)throw new TypeError("isMuted must be a boolean.");this.#d=e;try{const t=this.#x();t&&(e?t.mute():t.unMute())}catch(e){}this.emit("muteChange",this.#d)}get adapters(){return Array.from(this.#r)}get adaptersSize(){return this.#r.size}static#I=["timeupdate","ended"];static get defaultAdapterEventNames(){return structuredClone(g.#I)}static set defaultAdapterEventNames(e){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError("TinyMediaPlayer.defaultAdapterEventNames must be an array of strings.");g.#I=[...e]}#P=new Set(g.defaultAdapterEventNames);#C(e){const t=this.#n.get(e);t&&(this.#P.forEach(r=>{const n=t.get(r);n&&e.off(r,n)}),t.clear(),this.#n.delete(e))}registerAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");const t=new Map;this.#n.set(e,t),this.#P.forEach(t=>{this.#k(e,t)}),this.#r.add(e)}removeAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");return this.#C(e),this.#r.delete(e)}destroyAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");this.#C(e);const t=this.#r.delete(e);return t&&e.destroy(),t}hasAdapter(e){if(w(this.#e),!(e instanceof y))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");return this.#r.has(e)}destroyAllAdapters(){w(this.#e),this.#r.forEach(e=>{this.#C(e),e.destroy()}),this.#r.clear()}clearAdapters(){w(this.#e),this.#r.forEach(e=>this.#C(e)),this.#r.clear()}getMediaAdapter(e){if(!f(e))throw new TypeError("Content must be a valid object.");for(const t of this.#r.values())if(t.canHandle(e))return t;return null}#x(){if(-1===this.#s||0===this.#o.length)return null;const e=this.#o[this.#s],t=this.getMediaAdapter(e);if(t)return t;throw new Error(`No compatible adapter found for content ID: ${e.id}.`)}addAdapterEvent(e){if(w(this.#e),"string"!=typeof e)throw new TypeError("Event name must be a string.");this.#P.has(e)||(this.#P.add(e),this.#r.forEach(t=>{this.#k(t,e)}))}removeAdapterEvent(e){if(w(this.#e),"string"!=typeof e)throw new TypeError("Event name must be a string.");this.#P.has(e)&&(this.#P.delete(e),this.#r.forEach(t=>{this.#M(t,e)}))}resetAdapterEvents(){w(this.#e);const e=g.defaultAdapterEventNames,t=Array.from(this.#P);for(const r of t)e.includes(r)||this.removeAdapterEvent(r);for(const t of e)this.#P.has(t)||this.addAdapterEvent(t)}#k(e,t){const r=this.#n.get(e);if(!r)return;const n=(...e)=>{this.#e||this.emit(t,...e)};e.on(t,n),r.set(t,n)}#M(e,t){const r=this.#n.get(e);if(!r)return;const n=r.get(t);n&&(e.off(t,n),r.delete(t))}addTrack(e){if(w(this.#e),!f(e)||"string"!=typeof e.url)throw new TypeError("Track content must be a valid MediaContent object containing a URL.");const t={id:"",title:"",artist:"",url:"",duration:0,weight:1,title:null,album:null,albumartist:null,albumartists:[],genre:[],label:[],composer:[],year:null,artist:null,artists:[],disk:{no:null,of:null},track:{no:null,of:null},picture:[],...e};p(t);const r=this.#o.push(t);return-1===this.#s&&(this.#s=0,this.emit("trackChange",this.#s)),this.emit("playlistUpdate",this.playlist),r}existsTrack(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Index must be a number.");return e>=0&&e<this.#o.length}getTrack(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Index must be a number.");if(!this.existsTrack(e))throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);return this.#o[e]}async removeTrack(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Index must be a number.");if(!this.existsTrack(e))throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);e===this.#s?(await this.stop(),this.#o.splice(e,1),0===this.#o.length?this.#s=-1:this.#s>=this.#o.length&&(this.#s=0),this.emit("trackChange",this.#s)):(this.#o.splice(e,1),e<this.#s&&(this.#s-=1,this.emit("trackChange",this.#s))),this.emit("playlistUpdate",this.playlist)}searchTrack(e){if(w(this.#e),"string"!=typeof e&&"function"!=typeof e)throw new TypeError("Search query must be a string or a boolean evaluation function.");const t=[];for(let r=0;r<this.#o.length;r++){const n=this.#o[r];let o=!1;if("function"==typeof e)o=Boolean(e(n));else{const t=e.toLowerCase(),r=n.title&&n.title.toLowerCase().includes(t),s=n.artist&&n.artist.toLowerCase().includes(t),i=n.album&&n.album.toLowerCase().includes(t);o=Boolean(r||s||i)}o&&t.push({track:n,index:r})}return t}async clearPlaylist(){w(this.#e),await this.stop(),this.#o=[],this.#s=-1,this.emit("playlistUpdate",this.playlist),this.emit("trackChange",this.#s)}async play(){w(this.#e);const e=this.#x();e&&(this.#y?await this.#A(this.#u):e.setVolume(this.#u),await e.play(this.#o[this.#s]),this.#d&&await e.mute(),this.#l=!0,this.emit("play",this.#s))}async pause(){w(this.#e);const e=this.#x();e&&(this.#y&&await this.#A(0),await e.pause(),this.#l=!1,this.emit("pause",this.#s))}async stop(){w(this.#e);const e=this.#x();e&&(this.#f&&await this.#A(0),await e.stop(),this.#l=!1,this.emit("stop",this.#s))}async next(){if(w(this.#e),0!==this.#o.length)if(await this.stop(),"TRACK"!==this.#i){if(this.#a)this.#s=this._getWeightedRandomIndex();else{let e=this.#s+1;if(e>=this.#o.length){if("PLAYLIST"!==this.#i)return;e=0}this.#s=e}this.emit("trackChange",this.#s),await this.play()}else await this.play()}async prev(){if(w(this.#e),0!==this.#o.length){if(this.#c&&!this.#m)return this.#m=!0,this.#g&&clearTimeout(this.#g),this.#g=setTimeout(()=>{this.#m=!1,this.#g=null},2e3),await this.stop(),void await this.play();if(this.#g&&(clearTimeout(this.#g),this.#g=null),this.#m=!1,await this.stop(),this.#a)this.#s=this._getWeightedRandomIndex();else{let e=this.#s-1;if(e<0){if("PLAYLIST"!==this.#i)return;e=this.#o.length-1}this.#s=e}this.emit("trackChange",this.#s),await this.play()}}async seek(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Seek time must be a number in milliseconds.");if(e<0)throw new RangeError("Seek time cannot be negative.");const t=this.#x();t&&(await t.seek(e),this.emit("seek",e))}async step(e){if(w(this.#e),"number"!=typeof e)throw new TypeError("Step amount must be a number in milliseconds.");const t=this.#x();if(!t)return;let r=t.getCurrentTime()+e;r<0&&(r=0),await this.seek(r)}getCurrentTime(){w(this.#e);try{const e=this.#x();return e?e.getCurrentTime():0}catch{return 0}}getTotalDuration(){w(this.#e);try{const e=this.#x();return e?e.getTotalDuration():0}catch{return 0}}getRemainingTime(){w(this.#e);try{const e=this.#x();return e?e.getRemainingTime():0}catch{return 0}}getPlaybackPercentage(){w(this.#e);try{const e=this.#x();return e?e.getPlaybackPercentage():0}catch{return 0}}async getContentData(){w(this.#e);const e={id:"",createdAt:"",artistId:"",artistName:"",description:"",title:"",duration:0,avatar:"",url:""};try{const t=this.#x();return t?t.getContentData():e}catch{return e}}async waitIsReady(){w(this.#e);const e=this.#x();if(e)return e.waitIsReady()}async destroy(){if(!this.#e){try{this.#l&&await this.stop()}catch(e){console.warn("[TinyMediaPlayer] Non-fatal error during playback termination:",e)}this.#g&&clearTimeout(this.#g),this.#o=[],this.#s=-1,this.#l=!1,this.#m=!1,this.destroyAllAdapters(),this.removeAllListeners(),this.#P.clear(),this.#e=!0,this.emit("destroyed")}}}const v=g}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.d=(e,t)=>{if(Array.isArray(t))for(var n=0;n<t.length;){var o=t[n++],s=t[n++];r.o(e,o)?0===s&&n++:0===s?Object.defineProperty(e,o,{enumerable:!0,value:t[n++]}):Object.defineProperty(e,o,{enumerable:!0,get:s})}else for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.cjs=e=>{const t={exports:{}};return e.call(t.exports,t,t.exports),t.exports};let n=r(843);window.TinyMediaPlayer=n.TinyMediaPlayer})();
|
|
@@ -192,6 +192,33 @@ class HtmlAudioAdapter extends index.BaseMediaAdapter {
|
|
|
192
192
|
this.#audioElement.currentTime = currentTime;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Checks whether the player is currently muted.
|
|
197
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
198
|
+
*/
|
|
199
|
+
isMuted() {
|
|
200
|
+
checkDestroy(this.#destroyed);
|
|
201
|
+
return this.#audioElement.muted;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Mutes the current playback.
|
|
206
|
+
* @returns {Promise<void>}
|
|
207
|
+
*/
|
|
208
|
+
async mute() {
|
|
209
|
+
checkDestroy(this.#destroyed);
|
|
210
|
+
this.#audioElement.muted = true;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Unmutes the current playback.
|
|
215
|
+
* @returns {Promise<void>}
|
|
216
|
+
*/
|
|
217
|
+
async unMute() {
|
|
218
|
+
checkDestroy(this.#destroyed);
|
|
219
|
+
this.#audioElement.muted = false;
|
|
220
|
+
}
|
|
221
|
+
|
|
195
222
|
/**
|
|
196
223
|
* Gets the current playback time.
|
|
197
224
|
* @returns {number} The current time in milliseconds.
|
|
@@ -85,6 +85,21 @@ declare class HtmlAudioAdapter extends BaseMediaAdapter {
|
|
|
85
85
|
* @throws {TypeError} If timeMs is not a number.
|
|
86
86
|
*/
|
|
87
87
|
seek(timeMs: number): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Checks whether the player is currently muted.
|
|
90
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
91
|
+
*/
|
|
92
|
+
isMuted(): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Mutes the current playback.
|
|
95
|
+
* @returns {Promise<void>}
|
|
96
|
+
*/
|
|
97
|
+
mute(): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Unmutes the current playback.
|
|
100
|
+
* @returns {Promise<void>}
|
|
101
|
+
*/
|
|
102
|
+
unMute(): Promise<void>;
|
|
88
103
|
/**
|
|
89
104
|
* Gets the current playback time.
|
|
90
105
|
* @returns {number} The current time in milliseconds.
|
|
@@ -165,6 +165,30 @@ class HtmlAudioAdapter extends BaseMediaAdapter {
|
|
|
165
165
|
const currentTime = timeMs / 1000;
|
|
166
166
|
this.#audioElement.currentTime = currentTime;
|
|
167
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Checks whether the player is currently muted.
|
|
170
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
171
|
+
*/
|
|
172
|
+
isMuted() {
|
|
173
|
+
checkDestroy(this.#destroyed);
|
|
174
|
+
return this.#audioElement.muted;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Mutes the current playback.
|
|
178
|
+
* @returns {Promise<void>}
|
|
179
|
+
*/
|
|
180
|
+
async mute() {
|
|
181
|
+
checkDestroy(this.#destroyed);
|
|
182
|
+
this.#audioElement.muted = true;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Unmutes the current playback.
|
|
186
|
+
* @returns {Promise<void>}
|
|
187
|
+
*/
|
|
188
|
+
async unMute() {
|
|
189
|
+
checkDestroy(this.#destroyed);
|
|
190
|
+
this.#audioElement.muted = false;
|
|
191
|
+
}
|
|
168
192
|
/**
|
|
169
193
|
* Gets the current playback time.
|
|
170
194
|
* @returns {number} The current time in milliseconds.
|
|
@@ -189,6 +189,33 @@ class HtmlVideoAdapter extends index.BaseMediaAdapter {
|
|
|
189
189
|
this.#videoElement.currentTime = currentTime;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Checks whether the player is currently muted.
|
|
194
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
195
|
+
*/
|
|
196
|
+
isMuted() {
|
|
197
|
+
checkDestroy(this.#destroyed);
|
|
198
|
+
return this.#videoElement.muted;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Mutes the current playback.
|
|
203
|
+
* @returns {Promise<void>}
|
|
204
|
+
*/
|
|
205
|
+
async mute() {
|
|
206
|
+
checkDestroy(this.#destroyed);
|
|
207
|
+
this.#videoElement.muted = true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Unmutes the current playback.
|
|
212
|
+
* @returns {Promise<void>}
|
|
213
|
+
*/
|
|
214
|
+
async unMute() {
|
|
215
|
+
checkDestroy(this.#destroyed);
|
|
216
|
+
this.#videoElement.muted = false;
|
|
217
|
+
}
|
|
218
|
+
|
|
192
219
|
/**
|
|
193
220
|
* Gets the current playback time.
|
|
194
221
|
* @returns {number} The current time in milliseconds.
|
|
@@ -85,6 +85,21 @@ declare class HtmlVideoAdapter extends BaseMediaAdapter {
|
|
|
85
85
|
* @throws {TypeError} If timeMs is not a number.
|
|
86
86
|
*/
|
|
87
87
|
seek(timeMs: number): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Checks whether the player is currently muted.
|
|
90
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
91
|
+
*/
|
|
92
|
+
isMuted(): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Mutes the current playback.
|
|
95
|
+
* @returns {Promise<void>}
|
|
96
|
+
*/
|
|
97
|
+
mute(): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Unmutes the current playback.
|
|
100
|
+
* @returns {Promise<void>}
|
|
101
|
+
*/
|
|
102
|
+
unMute(): Promise<void>;
|
|
88
103
|
/**
|
|
89
104
|
* Gets the current playback time.
|
|
90
105
|
* @returns {number} The current time in milliseconds.
|
|
@@ -162,6 +162,30 @@ class HtmlVideoAdapter extends BaseMediaAdapter {
|
|
|
162
162
|
const currentTime = timeMs / 1000;
|
|
163
163
|
this.#videoElement.currentTime = currentTime;
|
|
164
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Checks whether the player is currently muted.
|
|
167
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
168
|
+
*/
|
|
169
|
+
isMuted() {
|
|
170
|
+
checkDestroy(this.#destroyed);
|
|
171
|
+
return this.#videoElement.muted;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Mutes the current playback.
|
|
175
|
+
* @returns {Promise<void>}
|
|
176
|
+
*/
|
|
177
|
+
async mute() {
|
|
178
|
+
checkDestroy(this.#destroyed);
|
|
179
|
+
this.#videoElement.muted = true;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Unmutes the current playback.
|
|
183
|
+
* @returns {Promise<void>}
|
|
184
|
+
*/
|
|
185
|
+
async unMute() {
|
|
186
|
+
checkDestroy(this.#destroyed);
|
|
187
|
+
this.#videoElement.muted = false;
|
|
188
|
+
}
|
|
165
189
|
/**
|
|
166
190
|
* Gets the current playback time.
|
|
167
191
|
* @returns {number} The current time in milliseconds.
|
|
@@ -284,6 +284,12 @@ class SoundCloudMediaAdapter extends index.BaseMediaAdapter {
|
|
|
284
284
|
/** @type {number} */
|
|
285
285
|
#cachedPosition = 0;
|
|
286
286
|
|
|
287
|
+
/** @type {boolean} */
|
|
288
|
+
#isMuted = false;
|
|
289
|
+
|
|
290
|
+
/** @type {number} */
|
|
291
|
+
#preMuteVolume = 1.0;
|
|
292
|
+
|
|
287
293
|
/**
|
|
288
294
|
* Gets whether the adapter has been destroyed.
|
|
289
295
|
* @returns {boolean}
|
|
@@ -449,7 +455,7 @@ class SoundCloudMediaAdapter extends index.BaseMediaAdapter {
|
|
|
449
455
|
|
|
450
456
|
// Command to load the new song
|
|
451
457
|
this.#widget?.load(`https://api.soundcloud.com/tracks/${targetId}`);
|
|
452
|
-
await promiseUtils.waitForTrue(() => true,
|
|
458
|
+
await promiseUtils.waitForTrue(() => true, 700);
|
|
453
459
|
/** @type {Partial<SoundObject>} */
|
|
454
460
|
let sound = {};
|
|
455
461
|
|
|
@@ -508,6 +514,13 @@ class SoundCloudMediaAdapter extends index.BaseMediaAdapter {
|
|
|
508
514
|
|
|
509
515
|
const eventSync = (/** @type {any} */ event, /** @type {string} */ eventName) => {
|
|
510
516
|
if (!event) return;
|
|
517
|
+
if (this.#isMuted)
|
|
518
|
+
this.#widget?.getVolume((volume) => {
|
|
519
|
+
if (this.#isMuted && volume > 0) {
|
|
520
|
+
this.#isMuted = false;
|
|
521
|
+
this.volume = this.#preMuteVolume;
|
|
522
|
+
}
|
|
523
|
+
});
|
|
511
524
|
if (typeof event.currentPosition === 'number') this.#cachedPosition = event.currentPosition;
|
|
512
525
|
if (typeof event.loadedProgress === 'number') this.#loadedProgress = event.loadedProgress;
|
|
513
526
|
if (typeof event.soundId === 'number') this.#currentContentId = String(event.soundId);
|
|
@@ -640,6 +653,47 @@ class SoundCloudMediaAdapter extends index.BaseMediaAdapter {
|
|
|
640
653
|
this.#widget?.seekTo(timeMs);
|
|
641
654
|
}
|
|
642
655
|
|
|
656
|
+
/**
|
|
657
|
+
* Checks whether the player is currently muted.
|
|
658
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
659
|
+
*/
|
|
660
|
+
isMuted() {
|
|
661
|
+
checkDestroy(this.#destroyed);
|
|
662
|
+
return this.#isMuted;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Mutes the current playback.
|
|
667
|
+
* @returns {Promise<void>}
|
|
668
|
+
*/
|
|
669
|
+
async mute() {
|
|
670
|
+
checkDestroy(this.#destroyed);
|
|
671
|
+
if (this.#isMuted) return;
|
|
672
|
+
|
|
673
|
+
this.#isMuted = true;
|
|
674
|
+
this.#preMuteVolume = this.#currentVolume;
|
|
675
|
+
|
|
676
|
+
// We update the state directly to avoid the setter's logic
|
|
677
|
+
// overwriting preMuteVolume during the transition.
|
|
678
|
+
this.#currentVolume = 0;
|
|
679
|
+
if (this.#widget && typeof this.#widget.setVolume === 'function') {
|
|
680
|
+
this.#widget.setVolume(0);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Unmutes the current playback.
|
|
686
|
+
* @returns {Promise<void>}
|
|
687
|
+
*/
|
|
688
|
+
async unMute() {
|
|
689
|
+
checkDestroy(this.#destroyed);
|
|
690
|
+
if (!this.#isMuted) return;
|
|
691
|
+
|
|
692
|
+
this.#isMuted = false;
|
|
693
|
+
// This will trigger the 'set volume' logic which applies the restored volume
|
|
694
|
+
this.volume = this.#preMuteVolume;
|
|
695
|
+
}
|
|
696
|
+
|
|
643
697
|
/**
|
|
644
698
|
* Retrieves the current playback time.
|
|
645
699
|
* @returns {number} The current time in milliseconds.
|
|
@@ -237,6 +237,21 @@ declare class SoundCloudMediaAdapter extends BaseMediaAdapter {
|
|
|
237
237
|
* @throws {TypeError} If timeMs is not a number.
|
|
238
238
|
*/
|
|
239
239
|
seek(timeMs: number): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Checks whether the player is currently muted.
|
|
242
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
243
|
+
*/
|
|
244
|
+
isMuted(): boolean;
|
|
245
|
+
/**
|
|
246
|
+
* Mutes the current playback.
|
|
247
|
+
* @returns {Promise<void>}
|
|
248
|
+
*/
|
|
249
|
+
mute(): Promise<void>;
|
|
250
|
+
/**
|
|
251
|
+
* Unmutes the current playback.
|
|
252
|
+
* @returns {Promise<void>}
|
|
253
|
+
*/
|
|
254
|
+
unMute(): Promise<void>;
|
|
240
255
|
/**
|
|
241
256
|
* Retrieves the current playback time.
|
|
242
257
|
* @returns {number} The current time in milliseconds.
|
|
@@ -249,6 +249,10 @@ class SoundCloudMediaAdapter extends BaseMediaAdapter {
|
|
|
249
249
|
#cachedDuration = 0;
|
|
250
250
|
/** @type {number} */
|
|
251
251
|
#cachedPosition = 0;
|
|
252
|
+
/** @type {boolean} */
|
|
253
|
+
#isMuted = false;
|
|
254
|
+
/** @type {number} */
|
|
255
|
+
#preMuteVolume = 1.0;
|
|
252
256
|
/**
|
|
253
257
|
* Gets whether the adapter has been destroyed.
|
|
254
258
|
* @returns {boolean}
|
|
@@ -391,7 +395,7 @@ class SoundCloudMediaAdapter extends BaseMediaAdapter {
|
|
|
391
395
|
}, 10000);
|
|
392
396
|
// Command to load the new song
|
|
393
397
|
this.#widget?.load(`https://api.soundcloud.com/tracks/${targetId}`);
|
|
394
|
-
await waitForTrue(() => true,
|
|
398
|
+
await waitForTrue(() => true, 700);
|
|
395
399
|
/** @type {Partial<SoundObject>} */
|
|
396
400
|
let sound = {};
|
|
397
401
|
// We registered the listener for the READY event before calling the load
|
|
@@ -444,6 +448,13 @@ class SoundCloudMediaAdapter extends BaseMediaAdapter {
|
|
|
444
448
|
const eventSync = (/** @type {any} */ event, /** @type {string} */ eventName) => {
|
|
445
449
|
if (!event)
|
|
446
450
|
return;
|
|
451
|
+
if (this.#isMuted)
|
|
452
|
+
this.#widget?.getVolume((volume) => {
|
|
453
|
+
if (this.#isMuted && volume > 0) {
|
|
454
|
+
this.#isMuted = false;
|
|
455
|
+
this.volume = this.#preMuteVolume;
|
|
456
|
+
}
|
|
457
|
+
});
|
|
447
458
|
if (typeof event.currentPosition === 'number')
|
|
448
459
|
this.#cachedPosition = event.currentPosition;
|
|
449
460
|
if (typeof event.loadedProgress === 'number')
|
|
@@ -561,6 +572,43 @@ class SoundCloudMediaAdapter extends BaseMediaAdapter {
|
|
|
561
572
|
throw new TypeError('Time must be a number.');
|
|
562
573
|
this.#widget?.seekTo(timeMs);
|
|
563
574
|
}
|
|
575
|
+
/**
|
|
576
|
+
* Checks whether the player is currently muted.
|
|
577
|
+
* @returns {boolean} True if muted, false otherwise.
|
|
578
|
+
*/
|
|
579
|
+
isMuted() {
|
|
580
|
+
checkDestroy(this.#destroyed);
|
|
581
|
+
return this.#isMuted;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Mutes the current playback.
|
|
585
|
+
* @returns {Promise<void>}
|
|
586
|
+
*/
|
|
587
|
+
async mute() {
|
|
588
|
+
checkDestroy(this.#destroyed);
|
|
589
|
+
if (this.#isMuted)
|
|
590
|
+
return;
|
|
591
|
+
this.#isMuted = true;
|
|
592
|
+
this.#preMuteVolume = this.#currentVolume;
|
|
593
|
+
// We update the state directly to avoid the setter's logic
|
|
594
|
+
// overwriting preMuteVolume during the transition.
|
|
595
|
+
this.#currentVolume = 0;
|
|
596
|
+
if (this.#widget && typeof this.#widget.setVolume === 'function') {
|
|
597
|
+
this.#widget.setVolume(0);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Unmutes the current playback.
|
|
602
|
+
* @returns {Promise<void>}
|
|
603
|
+
*/
|
|
604
|
+
async unMute() {
|
|
605
|
+
checkDestroy(this.#destroyed);
|
|
606
|
+
if (!this.#isMuted)
|
|
607
|
+
return;
|
|
608
|
+
this.#isMuted = false;
|
|
609
|
+
// This will trigger the 'set volume' logic which applies the restored volume
|
|
610
|
+
this.volume = this.#preMuteVolume;
|
|
611
|
+
}
|
|
564
612
|
/**
|
|
565
613
|
* Retrieves the current playback time.
|
|
566
614
|
* @returns {number} The current time in milliseconds.
|
|
@@ -633,6 +633,33 @@ class YoutubeMediaAdapter extends index.BaseMediaAdapter {
|
|
|
633
633
|
this.#player?.seekTo(targetTimeInSeconds, true);
|
|
634
634
|
}
|
|
635
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Checks whether the player is currently muted.
|
|
638
|
+
* @returns {boolean|null} True if muted, false otherwise.
|
|
639
|
+
*/
|
|
640
|
+
isMuted() {
|
|
641
|
+
checkDestroy(this.#destroyed);
|
|
642
|
+
return this.#player?.isMuted() ?? null;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Mutes the current playback.
|
|
647
|
+
* @returns {Promise<void>}
|
|
648
|
+
*/
|
|
649
|
+
async mute() {
|
|
650
|
+
checkDestroy(this.#destroyed);
|
|
651
|
+
this.#player?.mute();
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Unmutes the current playback.
|
|
656
|
+
* @returns {Promise<void>}
|
|
657
|
+
*/
|
|
658
|
+
async unMute() {
|
|
659
|
+
checkDestroy(this.#destroyed);
|
|
660
|
+
this.#player?.unMute();
|
|
661
|
+
}
|
|
662
|
+
|
|
636
663
|
/**
|
|
637
664
|
* Retrieves the current playback time.
|
|
638
665
|
* @returns {number} The current time in milliseconds.
|
|
@@ -290,6 +290,21 @@ declare class YoutubeMediaAdapter extends BaseMediaAdapter {
|
|
|
290
290
|
* @throws {TypeError} If timeMs is not a number.
|
|
291
291
|
*/
|
|
292
292
|
seek(timeMs: number): Promise<void>;
|
|
293
|
+
/**
|
|
294
|
+
* Checks whether the player is currently muted.
|
|
295
|
+
* @returns {boolean|null} True if muted, false otherwise.
|
|
296
|
+
*/
|
|
297
|
+
isMuted(): boolean | null;
|
|
298
|
+
/**
|
|
299
|
+
* Mutes the current playback.
|
|
300
|
+
* @returns {Promise<void>}
|
|
301
|
+
*/
|
|
302
|
+
mute(): Promise<void>;
|
|
303
|
+
/**
|
|
304
|
+
* Unmutes the current playback.
|
|
305
|
+
* @returns {Promise<void>}
|
|
306
|
+
*/
|
|
307
|
+
unMute(): Promise<void>;
|
|
293
308
|
/**
|
|
294
309
|
* Retrieves the current playback time.
|
|
295
310
|
* @returns {number} The current time in milliseconds.
|
|
@@ -560,6 +560,30 @@ class YoutubeMediaAdapter extends BaseMediaAdapter {
|
|
|
560
560
|
const targetTimeInSeconds = timeMs / 1000;
|
|
561
561
|
this.#player?.seekTo(targetTimeInSeconds, true);
|
|
562
562
|
}
|
|
563
|
+
/**
|
|
564
|
+
* Checks whether the player is currently muted.
|
|
565
|
+
* @returns {boolean|null} True if muted, false otherwise.
|
|
566
|
+
*/
|
|
567
|
+
isMuted() {
|
|
568
|
+
checkDestroy(this.#destroyed);
|
|
569
|
+
return this.#player?.isMuted() ?? null;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Mutes the current playback.
|
|
573
|
+
* @returns {Promise<void>}
|
|
574
|
+
*/
|
|
575
|
+
async mute() {
|
|
576
|
+
checkDestroy(this.#destroyed);
|
|
577
|
+
this.#player?.mute();
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Unmutes the current playback.
|
|
581
|
+
* @returns {Promise<void>}
|
|
582
|
+
*/
|
|
583
|
+
async unMute() {
|
|
584
|
+
checkDestroy(this.#destroyed);
|
|
585
|
+
this.#player?.unMute();
|
|
586
|
+
}
|
|
563
587
|
/**
|
|
564
588
|
* Retrieves the current playback time.
|
|
565
589
|
* @returns {number} The current time in milliseconds.
|
|
@@ -127,6 +127,33 @@ class BaseMediaAdapter extends events.EventEmitter {
|
|
|
127
127
|
throw new Error('Method "seek" must be implemented by the subclass.');
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Checks whether the player is currently muted.
|
|
132
|
+
* @returns {boolean|null} True if muted, false otherwise.
|
|
133
|
+
*/
|
|
134
|
+
isMuted() {
|
|
135
|
+
checkDestroy(this.#destroyed);
|
|
136
|
+
throw new Error('Method "isMuted" must be implemented by the subclass.');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Mutes the current playback.
|
|
141
|
+
* @returns {Promise<void>}
|
|
142
|
+
*/
|
|
143
|
+
async mute() {
|
|
144
|
+
checkDestroy(this.#destroyed);
|
|
145
|
+
throw new Error('Method "mute" must be implemented by the subclass.');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Unmutes the current playback.
|
|
150
|
+
* @returns {Promise<void>}
|
|
151
|
+
*/
|
|
152
|
+
async unMute() {
|
|
153
|
+
checkDestroy(this.#destroyed);
|
|
154
|
+
throw new Error('Method "unMute" must be implemented by the subclass.');
|
|
155
|
+
}
|
|
156
|
+
|
|
130
157
|
/**
|
|
131
158
|
* Retrieves the current playback time from the underlying API.
|
|
132
159
|
* @returns {number} The current time in milliseconds.
|