UNPKG

talkr-apng

Version:

Parse and play animated PNG (APNG) to sync with TTS or audio

1 lines 15 kB
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["talkr-apng"]=t():e["talkr-apng"]=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return e[n].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function i(e){return e===p}function a(e){return e===_}function s(e){var t=new Uint8Array(e);if(Array.prototype.some.call(d,function(e,r){return e!==t[r]}))return p;var r=!1;if(o(t,function(e){return!(r="acTL"===e)}),!r)return _;var n=[],i=[],a=null,s=null,u=0,h=new m.APNG;if(o(t,function(e,t,r,o){var f=new DataView(t.buffer);switch(e){case"IHDR":a=t.subarray(r+8,r+8+o),h.width=f.getUint32(r+8),h.height=f.getUint32(r+12);break;case"acTL":h.numPlays=f.getUint32(r+8+4);break;case"fcTL":s&&(h.frames.push(s),u++),s=new m.Frame,s.width=f.getUint32(r+8+4),s.height=f.getUint32(r+8+8),s.left=f.getUint32(r+8+12),s.top=f.getUint32(r+8+16);var c=f.getUint16(r+8+20),p=f.getUint16(r+8+22);0===p&&(p=100),s.delay=1e3*c/p,s.delay<=10&&(s.delay=100),h.playTime+=s.delay,s.disposeOp=f.getUint8(r+8+24),s.blendOp=f.getUint8(r+8+25),s.dataParts=[],0===u&&2===s.disposeOp&&(s.disposeOp=1);break;case"fdAT":s&&s.dataParts.push(t.subarray(r+8+4,r+8+o));break;case"IDAT":s&&s.dataParts.push(t.subarray(r+8,r+8+o));break;case"IEND":i.push(l(t,r,12+o));break;default:n.push(l(t,r,12+o))}}),s&&h.frames.push(s),0==h.frames.length)return _;var f=new Blob(n),c=new Blob(i);return h.frames.forEach(function(e){var t=[];t.push(d),a.set(y(e.width),0),a.set(y(e.height),4),t.push(v("IHDR",a)),t.push(f),e.dataParts.forEach(function(e){return t.push(v("IDAT",e))}),t.push(c),e.imageData=new Blob(t,{type:"image/png"}),delete e.dataParts,t=null}),h}function o(e,t){var r=new DataView(e.buffer),n=8,i=void 0,a=void 0,s=void 0;do a=r.getUint32(n),i=u(e,n+4,4),s=t(i,e,n,a),n+=12+a;while(s!==!1&&"IEND"!=i&&n<e.length)}function u(e,t,r){var n=Array.prototype.slice.call(e.subarray(t,t+r));return String.fromCharCode.apply(String,n)}function h(e){for(var t=new Uint8Array(e.length),r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}function l(e,t,r){var n=new Uint8Array(r);return n.set(e.subarray(t,t+r)),n}Object.defineProperty(t,"__esModule",{value:!0}),t.isNotPNG=i,t.isNotAPNG=a,t.default=s;var f=r(1),c=n(f),m=r(2),p=new Error("Not a PNG"),_=new Error("Not an animated PNG"),d=new Uint8Array([137,80,78,71,13,10,26,10]),v=function(e,t){var r=e.length+t.length,n=new Uint8Array(r+8),i=new DataView(n.buffer);i.setUint32(0,t.length),n.set(h(e),4),n.set(t,8);var a=(0,c.default)(n,4,r);return i.setUint32(r+4,a),n},y=function(e){return new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,255&e])}},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length-t,i=-1,a=t,s=t+n;a<s;a++)i=i>>>8^r[255&(i^e[a])];return i^-1};for(var r=new Uint32Array(256),n=0;n<256;n++){for(var i=n,a=0;a<8;a++)i=0!==(1&i)?3988292384^i>>>1:i>>>1;r[n]=i}},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.FrameAnim=t.Frame=t.APNG=void 0;var a=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),s=r(3),o=n(s);t.APNG=function(){function e(){i(this,e),this.width=0,this.height=0,this.numPlays=0,this.playTime=0,this.frames=[]}return a(e,[{key:"createImages",value:function(){return Promise.all(this.frames.map(function(e){return e.createImage()}))}},{key:"getPlayer",value:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.createImages().then(function(){return new o.default(t,e,r)})}}]),e}(),t.Frame=function(){function e(){i(this,e),this.left=0,this.top=0,this.width=0,this.height=0,this.delay=0,this.disposeOp=0,this.blendOp=0,this.imageData=null,this.imageElement=null}return a(e,[{key:"createImage",value:function(){var e=this;return this.imageElement?Promise.resolve():new Promise(function(t,r){var n=URL.createObjectURL(e.imageData);e.imageElement=document.createElement("img"),e.imageElement.onload=function(){URL.revokeObjectURL(n),t()},e.imageElement.onerror=function(){URL.revokeObjectURL(n),e.imageElement=null,r(new Error("Image creation error"))},e.imageElement.src=n})}}]),e}(),t.FrameAnim=function(){function e(){i(this,e),this.frames=[],this.nextRenderTime=0,this.currentFrameIndex=0}return a(e,[{key:"fromArray",value:function(e,t){this.frames=[],e.forEach(function(e){frames.push(e,t)})}},{key:"fromFrames",value:function(e){this.frames=[];var t=e.map(function(e){return e.slice()});e.forEach(function(e){if(!Array.isArray(e))throw new Error("Error. Animation must be array of arrays. [[i,dur]..]")}),this.frames=t}},{key:"tick",value:function(e,t){for(;e>=this.nextRenderTime&&this.frames.length>0;){var r=this.frames.shift();this.currentFrameIndex=r[0],this.nextRenderTime=this.nextRenderTime+r[1]/t}return e>=this.nextRenderTime&&0==this.frames.length}}]),e}()},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function i(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t<e.length;t++)r[t]=e[t];return r}return Array.from(e)}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),h=r(4),l=n(h),f=r(2),c=function(e){function t(e,r,n){a(this,t);var i=s(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return i.playbackRate=1,i._currentFrameNumber=0,i._ended=!1,i._paused=!0,i._numPlays=0,i._defaultFrameLength=40,i._is_talkr_file=!1,i._talkr_lipsync_frames=21,i._anims=[],i._apng=e,i.context=r,29===e.frames.length?i._is_talkr_file=!0:i.createFullFrames(),i.stop(),n&&i.play(),i}return o(t,e),u(t,[{key:"renderNextFrame",value:function(){this._currentFrameNumber=(this._currentFrameNumber+1)%this._apng.frames.length,this._currentFrameNumber===this._apng.frames.length-1&&(this._numPlays++,0!==this._apng.numPlays&&this._numPlays>=this._apng.numPlays&&(this.emit("end"),this._ended=!0,this._paused=!0)),this._prevFrame&&1==this._prevFrame.disposeOp?this.context.clearRect(this._prevFrame.left,this._prevFrame.top,this._prevFrame.width,this._prevFrame.height):this._prevFrame&&2==this._prevFrame.disposeOp&&this.context.putImageData(this._prevFrameData,this._prevFrame.left,this._prevFrame.top);var e=this.currentFrame;this._prevFrame=e,this._prevFrameData=null,2==e.disposeOp&&(this._prevFrameData=this.context.getImageData(e.left,e.top,e.width,e.height)),0==e.blendOp&&this.context.clearRect(e.left,e.top,e.width,e.height),this.context.drawImage(e.imageElement,e.left,e.top)}},{key:"play",value:function(){var e=this;this.emit("play"),this._ended&&this.stop(),this._paused=!1;var t=performance.now()+this.currentFrame.delay/this.playbackRate,r=function r(n){if(!e._ended&&!e._paused){if(n>=t){for(;n-t>=e._apng.playTime/e.playbackRate;)t+=e._apng.playTime/e.playbackRate,e._numPlays++;do e.renderNextFrame(),t+=e.currentFrame.delay/e.playbackRate;while(!e._ended&&n>t)}requestAnimationFrame(r)}};requestAnimationFrame(r)}},{key:"pause",value:function(){this._paused||(this.emit("pause"),this._paused=!0)}},{key:"createFullFrames",value:function(){this._fullFrameData=[],this._currentFrameNumber=-1,this.context.clearRect(0,0,this._apng.width,this._apng.height);for(var e=0;e<this._apng.frames.length;++e){this.renderNextFrame();this._apng.frames[e];this._fullFrameData.push(this.context.getImageData(0,0,this._apng.width,this._apng.height))}}},{key:"renderFullFrame",value:function(e){e%=this._apng.frames.length,e>=0&&this.context.putImageData(this._fullFrameData[e],0,0)}},{key:"addAnimToPlay",value:function(e){if(e&&0!=e.length){var t=new f.FrameAnim;t.fromFrames(e),this._anims.push(t)}}},{key:"play_anims",value:function(){var e=this;!this._ended,this._ended=!1,this._paused=!1,this._anims.forEach(function(t){if(t.frames.length>0){var r=t.frames[0];t.nextRenderTime=performance.now()+r[1]/e.playbackRate,t.currentFrameIndex=r[0]}});var t=function t(r){if(e._ended||e._paused||0==e._anims.length)return void e.context.drawImage(e._apng.frames[0].imageElement,e._apng.frames[0].left,e._apng.frames[0].top);var n=!1;e._anims.forEach(function(e){r>=e.nextRenderTime&&(n=!0)});var a=[];if(n){a.push(0);for(var s=e._anims.length-1;s>=0;--s){var o=e._anims[s].tick(r,e.playbackRate);o?e._anims.splice(s,1):a.push(e._anims[s].currentFrameIndex)}a=[].concat(i(new Set(a))).sort(function(e,t){return e-t}),e._is_talkr_file?a.forEach(function(t){e.context.drawImage(e._apng.frames[t].imageElement,e._apng.frames[t].left,e._apng.frames[t].top)}):e.renderFullFrame(a[a.length-1])}return 0==e._anims.length?(e.emit("end"),e._ended=!0,void(e._paused=!0)):void requestAnimationFrame(t)};requestAnimationFrame(t)}},{key:"create_blink_anim",value:function(e){var t=Math.random();return t<.3?[]:t<.6?[[22,50],[23,50],[24,50],[23,50],[22,50]]:[[0,t*e],[22,50],[23,50],[24,50],[23,50],[22,50]]}},{key:"create_brow_anim",value:function(e){var t=Math.random();return t<.3?[]:t<.6?[[25,50],[26,50],[27,50],[28,100],[27,80],[26,80],[25,80]]:e<1e3?[[25,50],[26,50],[27,50],[28,.9*e],[27,80],[26,80],[25,80]]:void 0}},{key:"play_for_duration",value:function(e){var t=this._defaultFrameLength/this.playbackRate,r=[[0,t]],n=0,i=!1,a=t,s=e-t,o=this._talkr_lipsync_frames;for(this._is_talkr_file||(o=this._apng.frames.length-1);a<=s;){n!==o&&0!==n||(i=n===o),!i&&n>0&&a+n*t>s&&(i=!0);var u=i?-1:1;n+=u,r.push([n,t]),a+=t}0!=n&&r.push([0,t]),this._anims=[],this.addAnimToPlay(r),this._is_talkr_file&&(this.addAnimToPlay(this.create_blink_anim()),this.addAnimToPlay(this.create_brow_anim())),this.play_anims()}},{key:"stop",value:function(){this.emit("stop"),this._numPlays=0,this._ended=!1,this._paused=!0,this._currentFrameNumber=-1,this.context.clearRect(0,0,this._apng.width,this._apng.height),this.renderNextFrame()}},{key:"currentFrameNumber",get:function(){return this._currentFrameNumber}},{key:"currentFrame",get:function(){return this._apng.frames[this._currentFrameNumber]}},{key:"paused",get:function(){return this._paused}},{key:"ended",get:function(){return this._ended}}]),t}(l.default);t.default=c},function(e,t){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function n(e){return"function"==typeof e}function i(e){return"number"==typeof e}function a(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}e.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!i(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,r,i,o,u,h;if(this._events||(this._events={}),"error"===e&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var l=new Error('Uncaught, unspecified "error" event. ('+t+")");throw l.context=t,l}if(r=this._events[e],s(r))return!1;if(n(r))switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),r.apply(this,o)}else if(a(r))for(o=Array.prototype.slice.call(arguments,1),h=r.slice(),i=h.length,u=0;u<i;u++)h[u].apply(this,o);return!0},r.prototype.addListener=function(e,t){var i;if(!n(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,n(t.listener)?t.listener:t),this._events[e]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,a(this._events[e])&&!this._events[e].warned&&(i=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,i&&i>0&&this._events[e].length>i&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),i||(i=!0,t.apply(this,arguments))}if(!n(t))throw TypeError("listener must be a function");var i=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var r,i,s,o;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(r=this._events[e],s=r.length,i=-1,r===t||n(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(r)){for(o=s;o-- >0;)if(r[o]===t||r[o].listener&&r[o].listener===t){i=o;break}if(i<0)return this;1===r.length?(r.length=0,delete this._events[e]):r.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r=this._events[e],n(r))this.removeListener(e,r);else if(r)for(;r.length;)this.removeListener(e,r[r.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?n(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(n(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}}])});