UNPKG

live2d-motionsync

Version:

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

179 lines (171 loc) 5.43 kB
var h = Object.defineProperty; var d = (s, t, e) => t in s ? h(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e; var o = (s, t, e) => d(s, typeof t != "symbol" ? t + "" : t, e); import { C as r, M as f, a as p, f as _, c as y } from "./fallback.motionsync3-1oooNFSa.js"; const m = `/** * Copyright(c) Live2D Inc. All rights reserved. * * Use of this source code is governed by the Live2D Open Software license * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. */ class LAppAudioWorkletProcessor extends AudioWorkletProcessor { constructor() { super(); this.useChannel = 0; } process(inputs, outputs, parameters) { const channel = this.useChannel % inputs[0].length; const input = inputs[0][channel]; if (input == undefined || input == null) { return true; } // 後ろに追加する const audioBuffer = Float32Array.from([...input]); this.port.postMessage({ eventType: "data", audioBuffer: audioBuffer, }); let inputArray = inputs[0]; let output = outputs[0]; for (let currentChannel = 0; currentChannel < inputArray.length; ++currentChannel) { let inputChannel = inputArray[currentChannel]; let outputChannel = output[currentChannel]; for (let i = 0; i < inputChannel.length; ++i){ outputChannel[i] = inputChannel[i]; } } return true; } } registerProcessor('lappaudioworkletprocessor', LAppAudioWorkletProcessor); `, a = 48e3; class g { constructor(t) { o(this, "_motionSync", null); o(this, "_internalModel"); o(this, "_model"); o(this, "_context", null); o(this, "_source", null); o(this, "_buffer", null); this._internalModel = t, this._model = t.coreModel, r.startUp(new f()), r.initialize(); } async play(t) { (this._source || this._context) && this.reset(); const e = t.getAudioTracks(); if (e.length == 0) { p("没有找到音频轨道."); return; } const n = 48e3, i = 30, c = 2; this._buffer = new M( Math.trunc(n / i * c) ), this._context = new AudioContext({ sampleRate: n }), this._source = this._context.createMediaStreamSource( new MediaStream([e[0]]) ); const l = URL.createObjectURL( new Blob([m], { type: "application/javascript" }) ); await this._context.audioWorklet.addModule(l); const u = new AudioWorkletNode( this._context, "lappaudioworkletprocessor" ); this._source.connect(u), u.port.onmessage = this.onMessage.bind(this); } async reset() { this._source && (this._source.disconnect(), this._source = null), this._context && (this._context.close(), this._context = null), this._buffer = null, this.resetMouthStatus(); } resetMouthStatus() { try { if (!this._motionSync) return; const t = this._motionSync.getData().getSetting(0); if (!t) return; const e = t.cubismParameterList; if (!e) return; const n = e._ptr.map( (i) => i.parameterIndex ); for (const i of n) this._model.setParameterValueByIndex(i, 0); } catch (t) { console.error(t); } } pop() { if (!this._buffer) return; const t = this._buffer.toVector(); return this._buffer.clear(), t; } onMessage(t) { const e = t.data; if (e.eventType === "data" && e.audioBuffer) for (let n = 0; n < e.audioBuffer.length; n++) this._buffer.addLast(e.audioBuffer[n]); } updateMotionSync() { const t = performance.now() / 1e3, e = this.pop(); e && (this._motionSync.setSoundBuffer(0, e, 0), this._motionSync.updateParameters(this._model, t)); } modelUpdateWithMotionSync() { if (!this._motionSync) return; const e = this._internalModel, n = e.motionManager.update; e.motionManager.update = (...i) => { n.apply(this._internalModel.motionManager, i), this.updateMotionSync(); }; } loadMotionSync(t, e = a) { if (t == null || t.byteLength == 0) { console.warn("Failed to loadMotionSync()."); return; } this._motionSync = r.create( this._model, t, t.byteLength, e ), this.modelUpdateWithMotionSync(); } async loadDefaultMotionSync(t = a) { const n = await new Blob([_], { type: "application/json" }).arrayBuffer(); this.loadMotionSync(n, t); } async loadMotionSyncFromUrl(t, e = a) { try { const i = await (await fetch(t)).arrayBuffer(); this.loadMotionSync(i, e); } catch { console.warn("Failed to loadMotionSync(). Use default fallback."), await this.loadDefaultMotionSync(e); } } } class M { constructor(t) { o(this, "_buffer"); o(this, "_size"); o(this, "_head"); this._buffer = new Float32Array(t), this._size = 0, this._head = 0; } get size() { return this._size; } addLast(t) { this._buffer[this._head] = t, this._size = Math.min(this._size + 1, this._buffer.length), this._head++, this._head >= this._buffer.length && (this._head = 0); } toVector() { const t = new y(this._size); let e = this._head - this._size; e < 0 && (e += this._buffer.length); for (let n = 0; n < this._size; n++) t.pushBack(this._buffer[e]), e++, e >= this._buffer.length && (e = 0); return t; } clear() { this._size = 0, this._head = 0; } } export { g as MotionSync };