pixi-live2d-display-advanced 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cubism2.es.js +75 -90
- package/dist/cubism2.js +96 -112
- package/dist/cubism2.min.js +1 -1
- package/dist/cubism4.es.js +75 -90
- package/dist/cubism4.js +96 -112
- package/dist/cubism4.min.js +1 -1
- package/dist/index.es.js +77 -93
- package/dist/index.js +98 -115
- package/dist/index.min.js +1 -1
- package/package.json +21 -18
- package/types/index.d.ts +16 -24
package/dist/cubism2.es.js
CHANGED
|
@@ -23,6 +23,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
import { utils as utils$1, Matrix, Texture, Transform, Point, ObservablePoint } from "@pixi/core";
|
|
26
|
+
import { Sound, webaudio } from "@pixi/sound";
|
|
26
27
|
import { Container } from "@pixi/display";
|
|
27
28
|
const LOGICAL_WIDTH = 2;
|
|
28
29
|
const LOGICAL_HEIGHT = 2;
|
|
@@ -77,7 +78,7 @@ const config = {
|
|
|
77
78
|
preserveExpressionOnMotion: true,
|
|
78
79
|
cubism4: CubismConfig
|
|
79
80
|
};
|
|
80
|
-
const VERSION = "v0.
|
|
81
|
+
const VERSION = "v0.5.1";
|
|
81
82
|
const logger = {
|
|
82
83
|
log(tag, ...messages) {
|
|
83
84
|
if (config.logLevel <= config.LOG_LEVEL_VERBOSE) {
|
|
@@ -3711,58 +3712,55 @@ class SoundManager {
|
|
|
3711
3712
|
* @param file - URL of the sound file.
|
|
3712
3713
|
* @param onFinish - Callback invoked when the playback has finished.
|
|
3713
3714
|
* @param onError - Callback invoked when error occurs.
|
|
3714
|
-
* @param crossOrigin - Cross origin setting.
|
|
3715
3715
|
* @return Created audio element.
|
|
3716
3716
|
*/
|
|
3717
|
-
static add(file, onFinish, onError
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3717
|
+
static add(file, onFinish, onError) {
|
|
3718
|
+
return __async(this, null, function* () {
|
|
3719
|
+
try {
|
|
3720
|
+
const task = new Promise((resolve, reject) => {
|
|
3721
|
+
const audio = Sound.from({
|
|
3722
|
+
url: file,
|
|
3723
|
+
volume: this._volume,
|
|
3724
|
+
preload: true,
|
|
3725
|
+
complete: () => {
|
|
3726
|
+
this.dispose(audio);
|
|
3727
|
+
onFinish == null ? void 0 : onFinish();
|
|
3728
|
+
},
|
|
3729
|
+
loaded: () => {
|
|
3730
|
+
if (!(audio.media instanceof webaudio.WebAudioMedia)) {
|
|
3731
|
+
reject(new Error(`Error: ${file} is not WebAudioMedia`));
|
|
3732
|
+
}
|
|
3733
|
+
debugger;
|
|
3734
|
+
resolve(audio);
|
|
3735
|
+
}
|
|
3736
|
+
});
|
|
3737
|
+
});
|
|
3738
|
+
return yield task;
|
|
3739
|
+
} catch (e) {
|
|
3740
|
+
logger.warn(TAG$2, `Error occurred on "${file}"`, e);
|
|
3741
|
+
onError == null ? void 0 : onError(e);
|
|
3742
|
+
return null;
|
|
3743
|
+
}
|
|
3730
3744
|
});
|
|
3731
|
-
this.audios.push(audio);
|
|
3732
|
-
return audio;
|
|
3733
3745
|
}
|
|
3734
3746
|
/**
|
|
3735
3747
|
* Plays the sound.
|
|
3736
3748
|
* @param audio - An audio element.
|
|
3737
|
-
* @return Promise that resolves when the audio is ready to play, rejects when error occurs.
|
|
3738
3749
|
*/
|
|
3739
3750
|
static play(audio) {
|
|
3740
|
-
|
|
3741
|
-
var _a;
|
|
3742
|
-
(_a = audio.play()) == null ? void 0 : _a.catch((e) => {
|
|
3743
|
-
audio.dispatchEvent(new ErrorEvent("error", { error: e }));
|
|
3744
|
-
reject(e);
|
|
3745
|
-
});
|
|
3746
|
-
if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
|
|
3747
|
-
resolve();
|
|
3748
|
-
} else {
|
|
3749
|
-
audio.addEventListener("canplaythrough", resolve);
|
|
3750
|
-
}
|
|
3751
|
-
});
|
|
3752
|
-
}
|
|
3753
|
-
static addContext(audio) {
|
|
3754
|
-
const context = new AudioContext();
|
|
3755
|
-
this.contexts.push(context);
|
|
3756
|
-
return context;
|
|
3751
|
+
audio.play();
|
|
3757
3752
|
}
|
|
3758
3753
|
static addAnalyzer(audio, context) {
|
|
3759
|
-
const
|
|
3754
|
+
const media = audio.media;
|
|
3755
|
+
const source = context.createBufferSource();
|
|
3756
|
+
source.buffer = media.buffer;
|
|
3760
3757
|
const analyser = context.createAnalyser();
|
|
3761
3758
|
analyser.fftSize = config.fftSize;
|
|
3762
3759
|
analyser.minDecibels = -90;
|
|
3763
3760
|
analyser.maxDecibels = -10;
|
|
3764
3761
|
analyser.smoothingTimeConstant = 0.85;
|
|
3765
3762
|
source.connect(analyser);
|
|
3763
|
+
source.start(0);
|
|
3766
3764
|
analyser.connect(context.destination);
|
|
3767
3765
|
this.analysers.push(analyser);
|
|
3768
3766
|
return analyser;
|
|
@@ -3773,17 +3771,21 @@ class SoundManager {
|
|
|
3773
3771
|
* @return Returns value to feed into lip sync
|
|
3774
3772
|
*/
|
|
3775
3773
|
static analyze(analyser) {
|
|
3776
|
-
if (analyser
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3774
|
+
if (!analyser) return parseFloat(Math.random().toFixed(1));
|
|
3775
|
+
const buffer = new Float32Array(analyser.fftSize);
|
|
3776
|
+
analyser.getFloatTimeDomainData(buffer);
|
|
3777
|
+
let sumSquares = 0;
|
|
3778
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
3779
|
+
sumSquares += __pow(buffer[i], 2);
|
|
3780
|
+
}
|
|
3781
|
+
const rms = Math.sqrt(sumSquares / buffer.length);
|
|
3782
|
+
const minDecibel = -100;
|
|
3783
|
+
const db = 20 * Math.log10(rms || __pow(10, minDecibel / 20));
|
|
3784
|
+
const scaledDb = Math.min(
|
|
3785
|
+
Math.max((db - analyser.minDecibels) / (analyser.maxDecibels - analyser.minDecibels), 0),
|
|
3786
|
+
1
|
|
3787
|
+
);
|
|
3788
|
+
return parseFloat(scaledDb.toFixed(1));
|
|
3787
3789
|
}
|
|
3788
3790
|
/**
|
|
3789
3791
|
* Disposes an audio element and removes it from {@link audios}.
|
|
@@ -3791,7 +3793,6 @@ class SoundManager {
|
|
|
3791
3793
|
*/
|
|
3792
3794
|
static dispose(audio) {
|
|
3793
3795
|
audio.pause();
|
|
3794
|
-
audio.removeAttribute("src");
|
|
3795
3796
|
remove(this.audios, audio);
|
|
3796
3797
|
}
|
|
3797
3798
|
/**
|
|
@@ -3799,7 +3800,7 @@ class SoundManager {
|
|
|
3799
3800
|
*/
|
|
3800
3801
|
static destroy() {
|
|
3801
3802
|
for (let i = this.contexts.length - 1; i >= 0; i--) {
|
|
3802
|
-
this.contexts[i].close();
|
|
3803
|
+
setTimeout(() => this.contexts[i].close());
|
|
3803
3804
|
}
|
|
3804
3805
|
for (let i = this.audios.length - 1; i >= 0; i--) {
|
|
3805
3806
|
this.dispose(this.audios[i]);
|
|
@@ -3851,7 +3852,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
3851
3852
|
__publicField(this, "state", new MotionState());
|
|
3852
3853
|
/**
|
|
3853
3854
|
* Audio element of the current motion if a sound file is defined with it.
|
|
3854
|
-
* @type {
|
|
3855
|
+
* @type {Sound | undefined}
|
|
3855
3856
|
*/
|
|
3856
3857
|
__publicField(this, "currentAudio");
|
|
3857
3858
|
/**
|
|
@@ -3966,13 +3967,13 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
3966
3967
|
}
|
|
3967
3968
|
/**
|
|
3968
3969
|
* Initializes audio playback and sets up audio analysis for lipsync.
|
|
3969
|
-
* @param audio - The
|
|
3970
|
+
* @param audio - The Sound to initialize.
|
|
3970
3971
|
* @param volume - The playback volume (0-1).
|
|
3971
3972
|
*/
|
|
3972
3973
|
initializeAudio(audio, volume) {
|
|
3973
3974
|
this.currentAudio = audio;
|
|
3974
3975
|
SoundManager.volume = volume;
|
|
3975
|
-
this.currentContext =
|
|
3976
|
+
this.currentContext = audio.context.audioContext;
|
|
3976
3977
|
this.currentAnalyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
|
|
3977
3978
|
}
|
|
3978
3979
|
/**
|
|
@@ -3991,7 +3992,6 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
3991
3992
|
volume = VOLUME,
|
|
3992
3993
|
expression,
|
|
3993
3994
|
resetExpression = true,
|
|
3994
|
-
crossOrigin,
|
|
3995
3995
|
onFinish,
|
|
3996
3996
|
onError
|
|
3997
3997
|
} = {}) {
|
|
@@ -4000,7 +4000,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4000
4000
|
}
|
|
4001
4001
|
let audio;
|
|
4002
4002
|
if (this.currentAudio) {
|
|
4003
|
-
if (
|
|
4003
|
+
if (this.currentAudio.isPlaying) {
|
|
4004
4004
|
return false;
|
|
4005
4005
|
}
|
|
4006
4006
|
}
|
|
@@ -4017,7 +4017,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4017
4017
|
const file = sound;
|
|
4018
4018
|
if (file) {
|
|
4019
4019
|
try {
|
|
4020
|
-
audio = SoundManager.add(
|
|
4020
|
+
audio = yield SoundManager.add(
|
|
4021
4021
|
file,
|
|
4022
4022
|
(that = this) => {
|
|
4023
4023
|
logger.warn(this.tag, "Audio finished playing");
|
|
@@ -4027,7 +4027,6 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4027
4027
|
}
|
|
4028
4028
|
that.currentAudio = void 0;
|
|
4029
4029
|
},
|
|
4030
|
-
// reset expression when audio is done
|
|
4031
4030
|
(e, that = this) => {
|
|
4032
4031
|
logger.error(this.tag, "Error during audio playback:", e);
|
|
4033
4032
|
onError == null ? void 0 : onError(e);
|
|
@@ -4035,9 +4034,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4035
4034
|
that.expressionManager.resetExpression();
|
|
4036
4035
|
}
|
|
4037
4036
|
that.currentAudio = void 0;
|
|
4038
|
-
}
|
|
4039
|
-
// on error
|
|
4040
|
-
crossOrigin
|
|
4037
|
+
}
|
|
4041
4038
|
);
|
|
4042
4039
|
this.initializeAudio(audio, volume);
|
|
4043
4040
|
} catch (e) {
|
|
@@ -4047,15 +4044,16 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4047
4044
|
}
|
|
4048
4045
|
if (audio) {
|
|
4049
4046
|
let playSuccess = true;
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
});
|
|
4054
|
-
if (config.motionSync) {
|
|
4055
|
-
yield readyToPlay;
|
|
4056
|
-
if (!playSuccess) {
|
|
4057
|
-
return false;
|
|
4047
|
+
try {
|
|
4048
|
+
if (config.motionSync) {
|
|
4049
|
+
SoundManager.play(audio);
|
|
4058
4050
|
}
|
|
4051
|
+
} catch (e) {
|
|
4052
|
+
logger.warn(this.tag, "Failed to play audio", audio.url, e);
|
|
4053
|
+
playSuccess = false;
|
|
4054
|
+
}
|
|
4055
|
+
if (!playSuccess) {
|
|
4056
|
+
return false;
|
|
4059
4057
|
}
|
|
4060
4058
|
}
|
|
4061
4059
|
if (this.state.shouldOverrideExpression()) {
|
|
@@ -4089,7 +4087,6 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4089
4087
|
volume = VOLUME,
|
|
4090
4088
|
expression = void 0,
|
|
4091
4089
|
resetExpression = true,
|
|
4092
|
-
crossOrigin,
|
|
4093
4090
|
onFinish,
|
|
4094
4091
|
onError,
|
|
4095
4092
|
ignoreParamIds = []
|
|
@@ -4099,7 +4096,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4099
4096
|
return false;
|
|
4100
4097
|
}
|
|
4101
4098
|
if (this.currentAudio) {
|
|
4102
|
-
if (
|
|
4099
|
+
if (this.currentAudio.isPlaying && priority != MotionPriority.FORCE) {
|
|
4103
4100
|
return false;
|
|
4104
4101
|
}
|
|
4105
4102
|
}
|
|
@@ -4127,7 +4124,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4127
4124
|
const file = soundURL;
|
|
4128
4125
|
if (file) {
|
|
4129
4126
|
try {
|
|
4130
|
-
audio = SoundManager.add(
|
|
4127
|
+
audio = yield SoundManager.add(
|
|
4131
4128
|
file,
|
|
4132
4129
|
(that = this) => {
|
|
4133
4130
|
onFinish == null ? void 0 : onFinish();
|
|
@@ -4136,7 +4133,6 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4136
4133
|
}
|
|
4137
4134
|
that.currentAudio = void 0;
|
|
4138
4135
|
},
|
|
4139
|
-
// reset expression when audio is done
|
|
4140
4136
|
(e, that = this) => {
|
|
4141
4137
|
logger.error(this.tag, "Error during audio playback:", e);
|
|
4142
4138
|
onError == null ? void 0 : onError(e);
|
|
@@ -4144,9 +4140,7 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4144
4140
|
that.expressionManager.resetExpression();
|
|
4145
4141
|
}
|
|
4146
4142
|
that.currentAudio = void 0;
|
|
4147
|
-
}
|
|
4148
|
-
// on error
|
|
4149
|
-
crossOrigin
|
|
4143
|
+
}
|
|
4150
4144
|
);
|
|
4151
4145
|
this.initializeAudio(audio, volume);
|
|
4152
4146
|
} catch (e) {
|
|
@@ -4155,11 +4149,12 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4155
4149
|
}
|
|
4156
4150
|
const motion = yield this.loadMotion(group, index);
|
|
4157
4151
|
if (audio) {
|
|
4158
|
-
const readyToPlay = SoundManager.play(audio).catch(
|
|
4159
|
-
(e) => logger.warn(this.tag, "Failed to play audio", audio.src, e)
|
|
4160
|
-
);
|
|
4161
4152
|
if (config.motionSync) {
|
|
4162
|
-
|
|
4153
|
+
try {
|
|
4154
|
+
SoundManager.play(audio);
|
|
4155
|
+
} catch (e) {
|
|
4156
|
+
logger.warn(this.tag, "Failed to play audio", audio.url, e);
|
|
4157
|
+
}
|
|
4163
4158
|
}
|
|
4164
4159
|
}
|
|
4165
4160
|
if (!this.state.start(motion, group, index, priority)) {
|
|
@@ -4201,7 +4196,6 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4201
4196
|
volume = VOLUME,
|
|
4202
4197
|
expression,
|
|
4203
4198
|
resetExpression = true,
|
|
4204
|
-
crossOrigin,
|
|
4205
4199
|
onFinish,
|
|
4206
4200
|
onError
|
|
4207
4201
|
} = {}) {
|
|
@@ -4220,7 +4214,6 @@ class MotionManager extends utils$1.EventEmitter {
|
|
|
4220
4214
|
volume,
|
|
4221
4215
|
expression,
|
|
4222
4216
|
resetExpression,
|
|
4223
|
-
crossOrigin,
|
|
4224
4217
|
onFinish,
|
|
4225
4218
|
onError
|
|
4226
4219
|
});
|
|
@@ -5532,7 +5525,6 @@ class Live2DModel extends Container {
|
|
|
5532
5525
|
* @param [options.volume=0.5] - Volume of the sound (0-1).
|
|
5533
5526
|
* @param [options.expression] - In case you want to mix up an expression while playing sound (bind with Model.expression()).
|
|
5534
5527
|
* @param [options.resetExpression=true] - Reset the expression to default after the motion is finished.
|
|
5535
|
-
* @param [options.crossOrigin] - CORS settings for audio resources.
|
|
5536
5528
|
* @param [options.onFinish] - Callback function when speaking completes.
|
|
5537
5529
|
* @param [options.onError] - Callback function when an error occurs.
|
|
5538
5530
|
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
|
|
@@ -5543,7 +5535,6 @@ class Live2DModel extends Container {
|
|
|
5543
5535
|
volume = VOLUME,
|
|
5544
5536
|
expression = void 0,
|
|
5545
5537
|
resetExpression = true,
|
|
5546
|
-
crossOrigin,
|
|
5547
5538
|
onFinish,
|
|
5548
5539
|
onError
|
|
5549
5540
|
} = {}) {
|
|
@@ -5553,7 +5544,6 @@ class Live2DModel extends Container {
|
|
|
5553
5544
|
volume,
|
|
5554
5545
|
expression,
|
|
5555
5546
|
resetExpression,
|
|
5556
|
-
crossOrigin,
|
|
5557
5547
|
onFinish,
|
|
5558
5548
|
onError
|
|
5559
5549
|
});
|
|
@@ -5563,7 +5553,6 @@ class Live2DModel extends Container {
|
|
|
5563
5553
|
volume,
|
|
5564
5554
|
expression,
|
|
5565
5555
|
resetExpression,
|
|
5566
|
-
crossOrigin,
|
|
5567
5556
|
onFinish,
|
|
5568
5557
|
onError
|
|
5569
5558
|
});
|
|
@@ -5639,7 +5628,6 @@ class Live2DModel extends Container {
|
|
|
5639
5628
|
* @param [options.volume] - Volume of the sound (0-1).
|
|
5640
5629
|
* @param [options.expression] - In case you want to mix up an expression while playing sound (bind with Model.expression()).
|
|
5641
5630
|
* @param [options.resetExpression=true] - Reset the expression to default after the motion is finished.
|
|
5642
|
-
* @param {string} [options.crossOrigin] - CORS settings for audio resources.
|
|
5643
5631
|
* @param [options.onFinish] - Callback function when speaking completes.
|
|
5644
5632
|
* @param [options.onError] - Callback function when an error occurs.
|
|
5645
5633
|
* @returns Promise that resolves with true if the sound is playing, false if it's not.
|
|
@@ -5648,7 +5636,6 @@ class Live2DModel extends Container {
|
|
|
5648
5636
|
volume = VOLUME,
|
|
5649
5637
|
expression,
|
|
5650
5638
|
resetExpression = true,
|
|
5651
|
-
crossOrigin,
|
|
5652
5639
|
onFinish,
|
|
5653
5640
|
onError
|
|
5654
5641
|
} = {}) {
|
|
@@ -5656,7 +5643,6 @@ class Live2DModel extends Container {
|
|
|
5656
5643
|
volume,
|
|
5657
5644
|
expression,
|
|
5658
5645
|
resetExpression,
|
|
5659
|
-
crossOrigin,
|
|
5660
5646
|
onFinish,
|
|
5661
5647
|
onError
|
|
5662
5648
|
});
|
|
@@ -6399,13 +6385,12 @@ class Cubism2InternalModel extends InternalModel {
|
|
|
6399
6385
|
let value = this.motionManager.mouthSync();
|
|
6400
6386
|
let min_ = 0;
|
|
6401
6387
|
const max_ = 1;
|
|
6402
|
-
const
|
|
6403
|
-
const bias_power = 0.7;
|
|
6388
|
+
const bias_power = 0.4;
|
|
6404
6389
|
if (value > 0) {
|
|
6405
6390
|
min_ = 0.4;
|
|
6406
6391
|
}
|
|
6407
6392
|
value = Math.pow(value, bias_power);
|
|
6408
|
-
value = clamp(value
|
|
6393
|
+
value = clamp(value, min_, max_);
|
|
6409
6394
|
for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
|
|
6410
6395
|
this.coreModel.setParamFloat(
|
|
6411
6396
|
this.coreModel.getParamIndex(this.motionManager.lipSyncIds[i]),
|