1 line
No EOL
12 KiB
JavaScript
1 line
No EOL
12 KiB
JavaScript
let SubtitlesOctopus=function(options){let supportsWebAssembly=!1;try{var module;"object"==typeof WebAssembly&&"function"==typeof WebAssembly.instantiate&&(module=new WebAssembly.Module(Uint8Array.of(0,97,115,109,1,0,0,0)))instanceof WebAssembly.Module&&(supportsWebAssembly=new WebAssembly.Instance(module)instanceof WebAssembly.Instance)}catch(e){}console.log("WebAssembly support detected: "+(supportsWebAssembly?"yes":"no"));let self=this;function renderFrames(){var data=self.renderFramesData,beforeDrawTime=performance.now();self.ctx.clearRect(0,0,self.canvas.width,self.canvas.height);for(let i=0;i<data.canvases.length;i++){var image=data.canvases[i],imageBuffer=(self.bufferCanvas.width=image.w,self.bufferCanvas.height=image.h,new Uint8ClampedArray(image.buffer));if(self.hasAlphaBug)for(let j=3;j<imageBuffer.length;j+=4)imageBuffer[j]=1<=imageBuffer[j]?imageBuffer[j]:1;var imageData=new ImageData(imageBuffer,image.w,image.h);self.bufferCanvasCtx.putImageData(imageData,0,0),self.ctx.drawImage(self.bufferCanvas,image.x,image.y)}self.debug&&(beforeDrawTime=Math.round(performance.now()-beforeDrawTime),console.log(Math.round(data.spentTime)+" ms (+ "+beforeDrawTime+" ms draw)"),self.renderStart=performance.now())}function renderFastFrames(){var data=self.renderFramesData,beforeDrawTime=performance.now();self.ctx.clearRect(0,0,self.canvas.width,self.canvas.height);for(let i=0;i<data.bitmaps.length;i++){var image=data.bitmaps[i];self.ctx.drawImage(image.bitmap,image.x,image.y)}self.debug&&(beforeDrawTime=Math.round(performance.now()-beforeDrawTime),console.log(data.bitmaps.length+" bitmaps, libass: "+Math.round(data.libassTime)+"ms, decode: "+Math.round(data.decodeTime)+"ms, draw: "+beforeDrawTime+"ms"),self.renderStart=performance.now())}self.canvas=options.canvas,self.lossyRender=options.lossyRender,self.isOurCanvas=!1,self.video=options.video,self.canvasParent=null,self.fonts=options.fonts||[],self.availableFonts=options.availableFonts||[],self.onReadyEvent=options.onReady,supportsWebAssembly?self.workerUrl=options.workerUrl||"subtitles-octopus-worker.js":self.workerUrl=options.legacyWorkerUrl||"subtitles-octopus-worker-legacy.js",self.subUrl=options.subUrl,self.subContent=options.subContent||null,self.onErrorEvent=options.onError,self.debug=options.debug||!1,self.lastRenderTime=0,self.pixelRatio=window.devicePixelRatio||1,self.timeOffset=options.timeOffset||0,self.hasAlphaBug=!1,self.detectAlphaBug=!1!==options.detectAlphaBug,(()=>{if("function"==typeof ImageData.prototype.constructor)try{return new window.ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch(e){console.log("detected that ImageData is not constructable despite browser saying so")}let ctx=document.createElement("canvas").getContext("2d");window.ImageData=function(){let i=0,data;arguments[0]instanceof Uint8ClampedArray&&(data=arguments[i++]);var width=arguments[i++],height=arguments[i],width=ctx.createImageData(width,height);return data&&width.data.set(data),width}})(),self.workerError=function(error){if(console.error("Worker error: ",error),self.onErrorEvent&&self.onErrorEvent(error),!self.debug)throw self.dispose(),new Error("Worker error: "+error)},self.init=function(){window.Worker?(self.worker||(self.worker=new Worker(self.workerUrl),self.worker.onmessage=self.onWorkerMessage,self.worker.onerror=self.workerError),self.workerActive=!1,self.createCanvas(),self.setVideo(options.video),self.setSubUrl(options.subUrl),self.worker.postMessage({target:"worker-init",width:self.canvas.width,height:self.canvas.height,URL:document.URL,currentScript:self.workerUrl,preMain:!0,fastRender:self.lossyRender,subUrl:self.subUrl,subContent:self.subContent,fonts:self.fonts,availableFonts:self.availableFonts,debug:self.debug})):self.workerError("worker not supported")},self.createCanvas=function(){if(self.canvas?self.canvasParent=self.canvas.parentNode:self.video?(self.isOurCanvas=!0,self.canvas=document.createElement("canvas"),self.canvas.className="libassjs-canvas",self.canvas.style.display="none",self.canvasParent=document.createElement("div"),self.canvasParent.className="libassjs-canvas-parent",self.canvasParent.appendChild(self.canvas),self.video.nextSibling?self.video.parentNode.insertBefore(self.canvasParent,self.video.nextSibling):self.video.parentNode.appendChild(self.canvasParent)):self.canvas||self.workerError("Don't know where to render: you should give video or canvas in options."),self.ctx=self.canvas.getContext("2d"),self.bufferCanvas=document.createElement("canvas"),self.bufferCanvasCtx=self.bufferCanvas.getContext("2d"),self.detectAlphaBug){var savedHasAlphaBug=(()=>{try{return localStorage.getItem("canvas_hasalphabug")}catch(err){console.log("error reading from storage")}return null})();if("true"===savedHasAlphaBug)self.hasAlphaBug=!0;else if("false"===savedHasAlphaBug)self.hasAlphaBug=!1;else{self.bufferCanvas.width=1,self.bufferCanvas.height=1;var savedHasAlphaBug=new Uint8ClampedArray([0,255,0,0]),savedHasAlphaBug=new ImageData(savedHasAlphaBug,1,1),prePut=(self.bufferCanvasCtx.clearRect(0,0,1,1),self.ctx.clearRect(0,0,1,1),self.ctx.getImageData(0,0,1,1).data),savedHasAlphaBug=(self.bufferCanvasCtx.putImageData(savedHasAlphaBug,0,0),self.ctx.drawImage(self.bufferCanvas,0,0),self.ctx.getImageData(0,0,1,1).data),prePut=(self.hasAlphaBug=prePut[1]!=savedHasAlphaBug[1],self.hasAlphaBug&&console.log("Detected a browser having issue with transparent pixels, applying workaround"),self.hasAlphaBug);try{localStorage.setItem("canvas_hasalphabug",prePut)}catch(err){console.log("error saving to local storage")}}}},self.setVideo=function(video){if(self.video=video,self.video){let timeupdate=function(){self.setCurrentTime(video.currentTime+self.timeOffset)};self.video.addEventListener("timeupdate",timeupdate,!1),self.video.addEventListener("playing",function(){self.setIsPaused(!1,video.currentTime+self.timeOffset)},!1),self.video.addEventListener("pause",function(){self.setIsPaused(!0,video.currentTime+self.timeOffset)},!1),self.video.addEventListener("seeking",function(){self.video.removeEventListener("timeupdate",timeupdate)},!1),self.video.addEventListener("seeked",function(){self.video.addEventListener("timeupdate",timeupdate,!1),self.setCurrentTime(video.currentTime+self.timeOffset)},!1),self.video.addEventListener("ratechange",function(){self.setRate(video.playbackRate)},!1),self.video.addEventListener("timeupdate",function(){self.setCurrentTime(video.currentTime+self.timeOffset)},!1),self.video.addEventListener("waiting",function(){self.setIsPaused(!0,video.currentTime+self.timeOffset)},!1),0<self.video.videoWidth?self.resize():self.video.addEventListener("loadedmetadata",function(e){e.target.removeEventListener(e.type,arguments.callee),self.resize()},!1)}},self.getVideoPosition=function(){var videoRatio=self.video.videoWidth/self.video.videoHeight,width=self.video.offsetWidth,height=self.video.offsetHeight;let realWidth=width,realHeight=height;videoRatio<width/height?realWidth=Math.floor(height*videoRatio):realHeight=Math.floor(width/videoRatio);videoRatio=(width-realWidth)/2,width=(height-realHeight)/2;return{width:realWidth,height:realHeight,x:videoRatio,y:width}},self.setSubUrl=function(subUrl){self.subUrl=subUrl},self.renderFrameData=null,self.workerActive=!1,self.frameId=0,self.onWorkerMessage=function(event){self.workerActive||(self.workerActive=!0,self.onReadyEvent&&self.onReadyEvent());var data=event.data;switch(data.target){case"stdout":console.log(data.content);break;case"console-log":console.log.apply(console,JSON.parse(data.content));break;case"console-debug":console.debug.apply(console,JSON.parse(data.content));break;case"console-info":console.info.apply(console,JSON.parse(data.content));break;case"console-warn":console.warn.apply(console,JSON.parse(data.content));break;case"console-error":console.error.apply(console,JSON.parse(data.content));break;case"stderr":console.error(data.content);break;case"window":window[data.method]();break;case"canvas":switch(data.op){case"getContext":self.ctx=self.canvas.getContext(data.type,data.attributes);break;case"resize":self.resize(data.width,data.height);break;case"renderCanvas":self.lastRenderTime<data.time&&(self.lastRenderTime=data.time,self.renderFramesData=data,window.requestAnimationFrame(renderFrames));break;case"renderFastCanvas":self.lastRenderTime<data.time&&(self.lastRenderTime=data.time,self.renderFramesData=data,window.requestAnimationFrame(renderFastFrames));break;case"setObjectProperty":self.canvas[data.object][data.property]=data.value;break;default:throw"eh?"}break;case"tick":self.frameId=data.id,self.worker.postMessage({target:"tock",id:self.frameId});break;case"custom":if(!self.onCustomMessage)throw"Custom message received but client onCustomMessage not implemented.";self.onCustomMessage(event);break;case"setimmediate":self.worker.postMessage({target:"setimmediate"});break;case"get-events":console.log(data.target),console.log(data.events);break;case"get-styles":console.log(data.target),console.log(data.styles);break;default:throw"what? "+data.target}},self.resize=function(width,height,top,left){let videoSize=null;var offset;top=top||0,left=left||0,width&&height||!self.video||(width=(videoSize=self.getVideoPosition()).width*self.pixelRatio,height=videoSize.height*self.pixelRatio,offset=self.canvasParent.getBoundingClientRect().top-self.video.getBoundingClientRect().top,top=videoSize.y-offset,left=videoSize.x),width&&height?self.canvas.width==width&&self.canvas.height==height&&self.canvas.style.top==top&&self.canvas.style.left==left||(self.canvas.width=width,self.canvas.height=height,null!=videoSize&&(self.canvasParent.style.position="relative",self.canvas.style.display="block",self.canvas.style.position="absolute",self.canvas.style.width=videoSize.width+"px",self.canvas.style.height=videoSize.height+"px",videoSize.height&&(self.canvas.style.aspectRatio=videoSize.width/videoSize.height),self.canvas.style.top=top+"px",self.canvas.style.left=left+"px",self.canvas.style.pointerEvents="none"),self.worker.postMessage({target:"canvas",width:self.canvas.width,height:self.canvas.height})):self.video||console.error("width or height is 0. You should specify width & height for resize.")},self.resizeWithTimeout=function(){self.resize(),setTimeout(self.resize,100)},self.runBenchmark=function(){self.worker.postMessage({target:"runBenchmark"})},self.customMessage=function(data,options){options=options||{},self.worker.postMessage({target:"custom",userData:data,preMain:options.preMain})},self.setCurrentTime=function(currentTime){self.worker.postMessage({target:"video",currentTime:currentTime})},self.setTrackByUrl=function(url){self.worker.postMessage({target:"set-track-by-url",url:url})},self.setTrack=function(content){self.worker.postMessage({target:"set-track",content:content})},self.freeTrack=function(content){self.worker.postMessage({target:"free-track"})},self.render=self.setCurrentTime,self.setIsPaused=function(isPaused,currentTime){self.worker.postMessage({target:"video",isPaused:isPaused,currentTime:currentTime})},self.setRate=function(rate){self.worker.postMessage({target:"video",rate:rate})},self.dispose=function(){self.worker.postMessage({target:"destroy"}),self.worker.terminate(),self.workerActive=!1,self.video&&self.canvasParent.remove()},self.createEvent=function(event){self.worker.postMessage({target:"create-event",event:event})},self.getEvents=function(){self.worker.postMessage({target:"get-events"})},self.setEvent=function(event,index){self.worker.postMessage({target:"set-event",event:event,index:index})},self.removeEvent=function(index){self.worker.postMessage({target:"remove-event",index:index})},self.createStyle=function(style){self.worker.postMessage({target:"create-style",style:style})},self.getStyles=function(){self.worker.postMessage({target:"get-styles"})},self.setStyle=function(style,index){self.worker.postMessage({target:"set-style",style:style,index:index})},self.removeStyle=function(index){self.worker.postMessage({target:"remove-style",index:index})},self.init()};"function"==typeof SubtitlesOctopusOnLoad&&SubtitlesOctopusOnLoad();export default SubtitlesOctopus; |