UNPKG

live2d-motionsync

Version:

Live2D Motionsync, a lip-sync library for Live2D models.

2 lines (1 loc) 4.03 kB
"use strict";var f=Object.defineProperty;var m=(s,t,o)=>t in s?f(s,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[t]=o;var n=(s,t,o)=>m(s,typeof t!="symbol"?t+"":t,o);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./fallback.motionsync3-lM6C-7qD.cjs");let r;function c(){const s=["click","keydown","touchstart","mousedown","pointerdown"];r=new AudioContext;const t=()=>{r.state==="suspended"&&r.resume().then(()=>{console.log("Audio context resumed")})};s.forEach(o=>{window.addEventListener(o,t,{capture:!0})})}function l(){return r}c();const d=48e3;class S{constructor(t){n(this,"audioBuffer",null);n(this,"audioSource",null);n(this,"previousSamplePosition",0);n(this,"audioElapsedTime",0);n(this,"audioContextPreviousTime",0);n(this,"_motionSync",null);n(this,"_internalModel");n(this,"_model");n(this,"soundBuffer",new a.csmVector);this._internalModel=t,this._model=t.coreModel,a.CubismMotionSync.startUp(new a.MotionSyncOption),a.CubismMotionSync.initialize()}get audioContext(){return l()}async loadAudio(t){const e=await(await fetch(t)).arrayBuffer();this.reset(),this.audioBuffer=await this.audioContext.decodeAudioData(e)}async loadAudioBuffer(t){this.reset(),this.audioBuffer=t}resetMouthStatus(){try{if(!this._motionSync)return;const t=this._motionSync.getData().getSetting(0);if(!t)return;const o=t.cubismParameterList;if(!o)return;const e=o._ptr.map(i=>i.parameterIndex);for(const i of e)this._model.setParameterValueByIndex(i,0)}catch(t){console.error(t)}}reset(){this.resetMouthStatus(),this.audioSource&&(this.audioSource.stop(),this.audioSource.disconnect(),this.audioSource=null),this.audioContextPreviousTime=0,this.previousSamplePosition=0,this.audioElapsedTime=0,this.soundBuffer.clear(),this.soundBuffer=new a.csmVector}async play(t){return new Promise(async(o,e)=>{typeof t=="string"?await this.loadAudio(t):await this.loadAudioBuffer(t),this.audioBuffer?(this.audioSource=this.audioContext.createBufferSource(),this.audioSource.buffer=this.audioBuffer,this.audioSource.connect(this.audioContext.destination),this.audioSource.start(0),this.audioSource.onended=()=>{o()},this.audioContextPreviousTime=this.audioContext.currentTime):e(new Error("audioBuffer is null"))})}updateMotionSync(){if(!this.audioBuffer||!this.audioSource)return;const t=this.audioContext.currentTime;t<=this.audioContextPreviousTime&&(this.audioContextPreviousTime=t);const o=t-this.audioContextPreviousTime;this.audioElapsedTime+=o;const e=Math.floor(this.audioElapsedTime*this.audioBuffer.sampleRate);if(this.previousSamplePosition<=this.audioBuffer.length){const i=this.audioBuffer.getChannelData(0).slice(this.previousSamplePosition,e);for(let u=0;u<i.length;u++)this.soundBuffer.pushBack(i[u]);if(!this._motionSync)return;this._motionSync.setSoundBuffer(0,this.soundBuffer,0),this._motionSync.updateParameters(this._model,o);const h=this._motionSync.getLastTotalProcessedCount(0);this.removeProcessedData(h),this.audioContextPreviousTime=t,this.previousSamplePosition=e}}modelUpdateWithMotionSync(){if(!this._motionSync)return;const o=this._internalModel,e=o.motionManager.update;o.motionManager.update=(...i)=>{e.apply(this._internalModel.motionManager,i),this.updateMotionSync()}}removeProcessedData(t){const o=this.soundBuffer;if(t<o.getSize())return!(o!=null&&o.begin())||(o==null?void 0:o._size)<=t||(o._ptr.splice(0,t),o._size-=t),o}loadMotionSync(t,o=d){if(t==null||t.byteLength==0){console.warn("Failed to loadMotionSync().");return}this._motionSync=a.CubismMotionSync.create(this._model,t,t.byteLength,o),this.modelUpdateWithMotionSync()}async loadDefaultMotionSync(t=d){const e=await new Blob([a.fallbackMotionsync3],{type:"application/json"}).arrayBuffer();this.loadMotionSync(e,t)}async loadMotionSyncFromUrl(t,o=d){try{const i=await(await fetch(t)).arrayBuffer();this.loadMotionSync(i,o)}catch{console.warn("Failed to loadMotionSync(). Use default fallback."),await this.loadDefaultMotionSync(o)}}}exports.MotionSync=S;exports.getAudioContext=l;exports.initAudioContext=c;