Bilibili-Evolved/registry/dist/plugins/video/download/wasm-output.js
github-actions[bot] cb93a5d993 CI build
2023-11-23 00:39:28 +00:00

4 lines
5.9 KiB
JavaScript

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["video/download/wasm-output"]=t():e["video/download/wasm-output"]=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,a)=>{for(var o in a)e.o(a,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:a[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{plugin:()=>W});const a=coreApis.toast,o=coreApis.cdnTypes,i=coreApis.download,n=coreApis.meta;function r(e,t,a){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var a=e[Symbol.toPrimitive];if(void 0!==a){var o=a.call(e,t||"default");if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t,a){!function(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object")}(e,t),t.set(e,a)}function l(e,t,a){return function(e,t,a){if(t.set)t.set.call(e,a);else{if(!t.writable)throw new TypeError("attempted to set read only private field");t.value=a}}(e,d(e,t,"set"),a),a}function c(e,t){return function(e,t){if(t.get)return t.get.call(e);return t.value}
/* eslint-disable @typescript-eslint/naming-convention */(e,d(e,t,"get"))}function d(e,t,a){if(!t.has(e))throw new TypeError("attempted to "+a+" private field on non-instance");return t.get(e)}const u=(()=>{let e=0;return()=>e++})();var p=function(e){return e.LOAD="LOAD",e.EXEC="EXEC",e.WRITE_FILE="WRITE_FILE",e.READ_FILE="READ_FILE",e.ERROR="ERROR",e}(p||{}),f=new WeakMap,h=new WeakMap,w=new WeakMap,m=new WeakMap,g=new WeakMap;const y=coreApis.utils.formatters;function b(e,t){return(a,o)=>{e.message=`${t}: ${(0,y.formatFileSize)(a)}${o>0?` / ${(0,y.formatFileSize)(o)} @ ${(0,y.formatPercent)(a/o)}`:""}`}}async function v(e,t){const a=await fetch(e);if(!a.ok)throw new Error(`${a.status} ${a.statusText}`);const o=a.body.getReader(),i=parseInt(a.headers.get("Content-Length")||"0");let n=0;const r=[];
// eslint-disable-next-line no-constant-condition
for(;;){const{done:e,value:a}=await o.read();if(e)break;r.push(a),n+=a.length,t(n,i)}const s=new Uint8Array(n);let l=0;for(const e of r)s.set(e,l),l+=e.length;return s}async function E(e,t,a){const o=await v(e,a),i=new Blob([o],{type:t});return URL.createObjectURL(i)}const F=new class{constructor(){var e=this;s(this,f,{writable:!0,value:null}),s(this,h,{writable:!0,value:{}}),s(this,w,{writable:!0,value:{}}),r(this,"loaded",!1),s(this,m,{writable:!0,value:()=>{c(this,f)&&(c(this,f).onmessage=e=>{let{data:{id:t,type:a,data:o}}=e;switch(a){case p.LOAD:this.loaded=!0,c(this,h)[t](o);break;case p.EXEC:case p.WRITE_FILE:case p.READ_FILE:c(this,h)[t](o);break;case p.ERROR:c(this,w)[t](o);break;default:throw new Error("Unknown FFmpeg message")}delete c(this,h)[t],delete c(this,w)[t]})}}),s(this,g,{writable:!0,value:function(t){let{type:a,data:o}=t,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2?arguments[2]:void 0;return c(e,f)?new Promise(((t,r)=>{const s=u();c(e,f)&&c(e,f).postMessage({id:s,type:a,data:o},i),c(e,h)[s]=t,c(e,w)[s]=r,n?.addEventListener("abort",(()=>{r(new DOMException(`Message # ${s} was aborted`,"AbortError"))}),{once:!0})})):Promise.reject(new Error("FFmpeg is not loaded"))}}),r(this,"load",((e,t)=>(c(this,f)||(l(this,f,new Worker(e.workerLoadURL,{type:"classic"})),c(this,m).call(this)),c(this,g).call(this,{type:p.LOAD,data:e},void 0,t)))),r(this,"exec",(function(t){let a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1,o=arguments.length>2?arguments[2]:void 0;return c(e,g).call(e,{type:p.EXEC,data:{args:t,timeout:a}},void 0,o)})),r(this,"terminate",(()=>{const e=Object.keys(c(this,w));for(const t of e)c(this,w)[t](new Error("FFmpeg terminated")),delete c(this,w)[t],delete c(this,h)[t];c(this,f)&&(c(this,f).terminate(),l(this,f,null),this.loaded=!1)})),r(this,"writeFile",((e,t,a)=>{const o=[];return o.push(t.buffer),c(this,g).call(this,{type:p.WRITE_FILE,data:{path:e,data:t}},o,a)})),r(this,"readFile",((e,t)=>c(this,g).call(this,{type:p.READ_FILE,data:{path:e,encoding:"binary"}},void 0,t)))}};function R(e,t){return`https://${n.meta.compilationInfo.allCdns[o.CdnTypes.jsDelivr].host}/npm/@ffmpeg/${e}@0.12.4/dist/umd/${t}`}async function A(e,t,a,o){F.loaded||await async function(e){await F.load({workerLoadURL:await E(R("ffmpeg","814.ffmpeg.js"),"text/javascript",b(e,"正在加载 FFmpeg Worker")),coreURL:await E(R("core","ffmpeg-core.js"),"text/javascript",b(e,"正在加载 FFmpeg Core")),wasmURL:await E(R("core","ffmpeg-core.wasm"),"application/wasm",b(e,"正在加载 FFmpeg WASM"))})}(o),F.writeFile("video",await v(t,b(o,"正在下载视频流"))),F.writeFile("audio",await v(a,b(o,"正在下载音频流"))),o.message="混流中……",await F.exec(["-i","video","-i","audio","-c:v","copy","-c:a","copy","output.mp4"]);const n=await F.readFile("output.mp4"),r=new Blob([n],{type:"video/mp4"});o.message="完成!",o.duration=1500,await i.DownloadPackage.single(e,r)}const L="WASM 混流输出",k="使用 WASM 在浏览器中下载并合并音视频",W={name:"downloadVideo.outputs.wasm",displayName:`下载视频 - ${L}`,description:k,author:{name:"WakelessSloth56",link:"https://github.com/WakelessSloth56"},setup:e=>{let{addData:t}=e;t("downloadVideo.outputs",(e=>{e.push({name:"wasm",displayName:"WASM",description:`${k},运行过程中请勿关闭页面,初次使用或清除缓存后需要加载约 30 MB 的 WASM 文件`,runAction:async e=>{const t=e.infos.flatMap((e=>e.titledFragments));if(2!==t.length)a.Toast.error("仅支持 DASH 格式",L);else{const e=a.Toast.info("正在加载",L);try{await A(t[0].title,t[0].url,t[1].url,e)}catch(t){e.close(),a.Toast.error(String(t),L)}}}})}))},commitHash:"04685315d5fff6c0966bdbab2b70ce7630e3b028",coreVersion:"2.8.7"};return t=t.plugin})()));