@laplace.live/pixijs-live2d 0.3.0 → 0.4.0
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/index.d.ts +2 -0
- package/dist/index.js +48 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -3698,6 +3698,8 @@ export declare const VOLUME = 0.5;
|
|
|
3698
3698
|
* Manages all the sounds.
|
|
3699
3699
|
*/
|
|
3700
3700
|
export declare class SoundManager {
|
|
3701
|
+
/** Select the speaker used by current and future motion audio and speak() calls. */
|
|
3702
|
+
static setOutputDevice(deviceId: string): Promise<void>;
|
|
3701
3703
|
/**
|
|
3702
3704
|
* Audio elements playing or pending to play. Finished audios will be removed automatically.
|
|
3703
3705
|
*/
|
package/dist/index.js
CHANGED
|
@@ -3663,17 +3663,33 @@ const VOLUME = .5;
|
|
|
3663
3663
|
const SOUND_ALIAS_PREFIX = "live2d-sound-";
|
|
3664
3664
|
let soundId = 0;
|
|
3665
3665
|
let pixiSoundPromise;
|
|
3666
|
-
const configuredLibraries = /* @__PURE__ */ new
|
|
3666
|
+
const configuredLibraries = /* @__PURE__ */ new Set();
|
|
3667
|
+
let outputDeviceId = "";
|
|
3668
|
+
let outputError = null;
|
|
3669
|
+
/** Device changes and first-use routing run in order, so a library never settles on a stale device. */
|
|
3670
|
+
let routing = Promise.resolve();
|
|
3671
|
+
function queueRouting(task) {
|
|
3672
|
+
const run = routing.then(task);
|
|
3673
|
+
routing = run.catch(() => void 0);
|
|
3674
|
+
return run;
|
|
3675
|
+
}
|
|
3676
|
+
async function routeContext(context, deviceId) {
|
|
3677
|
+
const routable = context;
|
|
3678
|
+
if (routable.setSinkId) await routable.setSinkId(deviceId);
|
|
3679
|
+
else if (deviceId) throw new Error("Audio output selection is not supported");
|
|
3680
|
+
}
|
|
3667
3681
|
function configureSoundLibrary(library) {
|
|
3668
|
-
|
|
3682
|
+
return queueRouting(async () => {
|
|
3683
|
+
if (configuredLibraries.has(library)) return library;
|
|
3669
3684
|
try {
|
|
3670
3685
|
library.disableAutoPause = true;
|
|
3671
3686
|
} catch (e) {
|
|
3672
3687
|
logger.warn(TAG$2, "Failed to disable @pixi/sound auto pause.", e);
|
|
3673
3688
|
}
|
|
3689
|
+
if (outputDeviceId) await routeContext(library.context.audioContext, outputDeviceId);
|
|
3674
3690
|
configuredLibraries.add(library);
|
|
3675
|
-
|
|
3676
|
-
|
|
3691
|
+
return library;
|
|
3692
|
+
});
|
|
3677
3693
|
}
|
|
3678
3694
|
function getGlobalSoundLibrary() {
|
|
3679
3695
|
return typeof PIXI !== "undefined" ? PIXI?.sound : void 0;
|
|
@@ -3681,11 +3697,12 @@ function getGlobalSoundLibrary() {
|
|
|
3681
3697
|
async function resolveSoundLibrary() {
|
|
3682
3698
|
const globalLibrary = getGlobalSoundLibrary();
|
|
3683
3699
|
if (globalLibrary) return configureSoundLibrary(globalLibrary);
|
|
3684
|
-
pixiSoundPromise ??= import("@pixi/sound").then(({ sound }) =>
|
|
3700
|
+
pixiSoundPromise ??= import("@pixi/sound").then(({ sound }) => sound).catch((e) => {
|
|
3685
3701
|
logger.warn(TAG$2, "@pixi/sound is not available. Load pixi-sound.js before using motion sounds, speak(), or lip sync.", e);
|
|
3686
3702
|
return null;
|
|
3687
3703
|
});
|
|
3688
|
-
|
|
3704
|
+
const library = await pixiSoundPromise;
|
|
3705
|
+
return library ? configureSoundLibrary(library) : null;
|
|
3689
3706
|
}
|
|
3690
3707
|
function removeSound(library, alias) {
|
|
3691
3708
|
try {
|
|
@@ -3710,6 +3727,25 @@ function getAudioBuffer(audio) {
|
|
|
3710
3727
|
* Manages all the sounds.
|
|
3711
3728
|
*/
|
|
3712
3729
|
var SoundManager = class SoundManager {
|
|
3730
|
+
/** Select the speaker used by current and future motion audio and speak() calls. */
|
|
3731
|
+
static setOutputDevice(deviceId) {
|
|
3732
|
+
return queueRouting(async () => {
|
|
3733
|
+
const changed = [];
|
|
3734
|
+
try {
|
|
3735
|
+
for (const library of configuredLibraries) {
|
|
3736
|
+
const context = library.context.audioContext;
|
|
3737
|
+
await routeContext(context, deviceId);
|
|
3738
|
+
changed.push(context);
|
|
3739
|
+
}
|
|
3740
|
+
outputDeviceId = deviceId;
|
|
3741
|
+
outputError = null;
|
|
3742
|
+
} catch (error) {
|
|
3743
|
+
outputError = error;
|
|
3744
|
+
await Promise.allSettled(changed.map((context) => routeContext(context, outputDeviceId)));
|
|
3745
|
+
throw error;
|
|
3746
|
+
}
|
|
3747
|
+
});
|
|
3748
|
+
}
|
|
3713
3749
|
/**
|
|
3714
3750
|
* Audio elements playing or pending to play. Finished audios will be removed automatically.
|
|
3715
3751
|
*/
|
|
@@ -3740,6 +3776,7 @@ var SoundManager = class SoundManager {
|
|
|
3740
3776
|
let library = null;
|
|
3741
3777
|
let alias;
|
|
3742
3778
|
try {
|
|
3779
|
+
if (outputError) throw outputError;
|
|
3743
3780
|
library = await resolveSoundLibrary();
|
|
3744
3781
|
if (!library) throw new Error("@pixi/sound is not available");
|
|
3745
3782
|
alias = `${SOUND_ALIAS_PREFIX}${soundId++}`;
|
|
@@ -3768,6 +3805,7 @@ var SoundManager = class SoundManager {
|
|
|
3768
3805
|
}
|
|
3769
3806
|
});
|
|
3770
3807
|
});
|
|
3808
|
+
if (outputError) throw outputError;
|
|
3771
3809
|
SoundManager.aliases.set(audio, {
|
|
3772
3810
|
alias: soundAlias,
|
|
3773
3811
|
library: soundLibrary
|
|
@@ -3787,6 +3825,10 @@ var SoundManager = class SoundManager {
|
|
|
3787
3825
|
* @param onFinish - Callback invoked when the playback has finished.
|
|
3788
3826
|
*/
|
|
3789
3827
|
static play(audio, onFinish) {
|
|
3828
|
+
if (outputError) {
|
|
3829
|
+
SoundManager.dispose(audio);
|
|
3830
|
+
return;
|
|
3831
|
+
}
|
|
3790
3832
|
audio.play({
|
|
3791
3833
|
singleInstance: true,
|
|
3792
3834
|
complete: () => {
|