danoniplus 49.0.0 → 49.1.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/js/danoni_main.js +75 -26
- package/js/lib/danoni_constants.js +3 -2
- package/package.json +1 -1
package/js/danoni_main.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Source by tickle
|
|
6
6
|
* Created : 2018/10/08
|
|
7
|
-
* Revised : 2026/
|
|
7
|
+
* Revised : 2026/07/04
|
|
8
8
|
*
|
|
9
9
|
* https://github.com/cwtickle/danoniplus
|
|
10
10
|
*/
|
|
11
|
-
const g_version = `Ver 49.
|
|
12
|
-
const g_revisedDate = `2026/
|
|
11
|
+
const g_version = `Ver 49.1.1`;
|
|
12
|
+
const g_revisedDate = `2026/07/04`;
|
|
13
13
|
|
|
14
14
|
// カスタム用バージョン (danoni_custom.js 等で指定可)
|
|
15
15
|
let g_localVersion = ``;
|
|
@@ -2514,7 +2514,7 @@ const drawTitleResultMotion = _displayName =>
|
|
|
2514
2514
|
// WebAudioAPIでAudio要素風に再生するクラス
|
|
2515
2515
|
class AudioPlayer {
|
|
2516
2516
|
constructor() {
|
|
2517
|
-
this._context =
|
|
2517
|
+
this._context = getSharedAudioContext();
|
|
2518
2518
|
this._gain = this._context.createGain();
|
|
2519
2519
|
this._gain.connect(this._context.destination);
|
|
2520
2520
|
this._startTime = 0;
|
|
@@ -2562,11 +2562,8 @@ class AudioPlayer {
|
|
|
2562
2562
|
}
|
|
2563
2563
|
|
|
2564
2564
|
close() {
|
|
2565
|
-
if (this._context) {
|
|
2566
|
-
this._context.close()?.catch(() => {/* ignore double-close */ });
|
|
2567
|
-
this._buffer = null;
|
|
2568
|
-
}
|
|
2569
2565
|
if (this._source) {
|
|
2566
|
+
this._source.stop(0);
|
|
2570
2567
|
this._source.disconnect(this._gain);
|
|
2571
2568
|
this._source = null;
|
|
2572
2569
|
}
|
|
@@ -2641,10 +2638,33 @@ class AudioPlayer {
|
|
|
2641
2638
|
this._eventListeners[_type] = this._eventListeners[_type].filter(_element => _element !== _listener);
|
|
2642
2639
|
}
|
|
2643
2640
|
|
|
2641
|
+
getBuffer() {
|
|
2642
|
+
return this._buffer;
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
setBuffer(_buffer) {
|
|
2646
|
+
this._buffer = _buffer;
|
|
2647
|
+
this._duration = _buffer.duration;
|
|
2648
|
+
this._eventListeners[`canplaythrough`]?.forEach(_listener => _listener());
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2644
2651
|
load() { }
|
|
2645
2652
|
dispatchEvent() { }
|
|
2646
2653
|
}
|
|
2647
2654
|
|
|
2655
|
+
// グローバルで1つだけ保持(遅延生成)
|
|
2656
|
+
let g_sharedAudioContext = null;
|
|
2657
|
+
const getSharedAudioContext = () => {
|
|
2658
|
+
if (!g_sharedAudioContext) {
|
|
2659
|
+
g_sharedAudioContext = new AudioContext();
|
|
2660
|
+
}
|
|
2661
|
+
// タブのバックグラウンド化等でsuspendedになることがあるため念のためresume
|
|
2662
|
+
if (g_sharedAudioContext.state === `suspended`) {
|
|
2663
|
+
g_sharedAudioContext.resume();
|
|
2664
|
+
}
|
|
2665
|
+
return g_sharedAudioContext;
|
|
2666
|
+
};
|
|
2667
|
+
|
|
2648
2668
|
/**
|
|
2649
2669
|
* クリップボードコピー関数
|
|
2650
2670
|
* 入力値をクリップボードへコピーし、メッセージを表示
|
|
@@ -6370,23 +6390,22 @@ const playBGM = async (_num, _currentLoopNum = g_settings.musicLoopNum) => {
|
|
|
6370
6390
|
|
|
6371
6391
|
if (encodeFlg) {
|
|
6372
6392
|
try {
|
|
6373
|
-
|
|
6374
|
-
if (
|
|
6375
|
-
|
|
6393
|
+
closeExistingAudio();
|
|
6394
|
+
if (g_audioBufferCache.has(url)) {
|
|
6395
|
+
const tmpAudio = new AudioPlayer();
|
|
6396
|
+
tmpAudio.setBuffer(g_audioBufferCache.get(url)); // 新設メソッド、decode不要
|
|
6397
|
+
g_audioForMS = tmpAudio;
|
|
6398
|
+
} else {
|
|
6376
6399
|
await loadScript2(url);
|
|
6377
6400
|
musicInit();
|
|
6378
|
-
if (!isTitle()) {
|
|
6379
|
-
|
|
6380
|
-
return;
|
|
6381
|
-
}
|
|
6401
|
+
if (!isTitle()) { g_musicdata = ``; return; }
|
|
6402
|
+
|
|
6382
6403
|
const tmpAudio = new AudioPlayer();
|
|
6383
|
-
const array =
|
|
6404
|
+
const array = base64ToUint8Array(g_musicdata);
|
|
6384
6405
|
await tmpAudio.init(array.buffer);
|
|
6385
|
-
if (!isTitle()) {
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
return;
|
|
6389
|
-
}
|
|
6406
|
+
if (!isTitle()) { g_musicdata = ``; tmpAudio.close(); return; }
|
|
6407
|
+
|
|
6408
|
+
cacheAudioBuffer(url, tmpAudio.getBuffer());
|
|
6390
6409
|
g_audioForMS = tmpAudio;
|
|
6391
6410
|
}
|
|
6392
6411
|
g_audioForMS.volume = g_stateObj.bgmVolume / 100;
|
|
@@ -11969,7 +11988,7 @@ const loadMusic = () => {
|
|
|
11969
11988
|
const blobUrl = URL.createObjectURL(request.response);
|
|
11970
11989
|
createEmptySprite(divRoot, `loader`, g_windowObj.loader);
|
|
11971
11990
|
lblLoading.textContent = g_lblNameObj.pleaseWait;
|
|
11972
|
-
setAudio(blobUrl);
|
|
11991
|
+
setAudio(blobUrl, url);
|
|
11973
11992
|
} else {
|
|
11974
11993
|
makeWarningWindow(`${g_msgInfoObj.E_0041.split('{0}').join(getFullPath(url))}<br>(${request.status} ${request.statusText})`, { backBtnUse: true });
|
|
11975
11994
|
}
|
|
@@ -12001,8 +12020,9 @@ const loadMusic = () => {
|
|
|
12001
12020
|
* 音楽データの設定
|
|
12002
12021
|
* iOSの場合はAudioタグによる再生
|
|
12003
12022
|
* @param {string} _url
|
|
12023
|
+
* @param {string} _cacheKey
|
|
12004
12024
|
*/
|
|
12005
|
-
const setAudio = async (_url) => {
|
|
12025
|
+
const setAudio = async (_url, _cacheKey = _url) => {
|
|
12006
12026
|
|
|
12007
12027
|
const loadMp3 = () => {
|
|
12008
12028
|
if (g_isFile) {
|
|
@@ -12019,6 +12039,7 @@ const setAudio = async (_url) => {
|
|
|
12019
12039
|
g_currentPage = `loadingIos`;
|
|
12020
12040
|
lblLoading.textContent = `Click to Start!`;
|
|
12021
12041
|
divRoot.appendChild(makePlayButton(evt => {
|
|
12042
|
+
getSharedAudioContext().resume();
|
|
12022
12043
|
g_currentPage = `loading`;
|
|
12023
12044
|
resetKeyControl();
|
|
12024
12045
|
divRoot.removeChild(evt.target);
|
|
@@ -12034,7 +12055,7 @@ const setAudio = async (_url) => {
|
|
|
12034
12055
|
await loadScript2(_url);
|
|
12035
12056
|
if (typeof musicInit === C_TYP_FUNCTION) {
|
|
12036
12057
|
musicInit();
|
|
12037
|
-
readyToStart(() => initWebAudioAPIfromBase64(g_musicdata));
|
|
12058
|
+
readyToStart(() => initWebAudioAPIfromBase64(g_musicdata, _cacheKey));
|
|
12038
12059
|
} else {
|
|
12039
12060
|
makeWarningWindow(g_msgInfoObj.E_0031);
|
|
12040
12061
|
musicAfterLoaded();
|
|
@@ -12045,11 +12066,19 @@ const setAudio = async (_url) => {
|
|
|
12045
12066
|
};
|
|
12046
12067
|
|
|
12047
12068
|
// Base64から音声データに変換してWebAudioAPIで再生する準備
|
|
12048
|
-
const initWebAudioAPIfromBase64 = async (_base64) => {
|
|
12069
|
+
const initWebAudioAPIfromBase64 = async (_base64, _cacheKey) => {
|
|
12049
12070
|
g_audio = new AudioPlayer();
|
|
12050
12071
|
musicAfterLoaded();
|
|
12051
|
-
|
|
12072
|
+
|
|
12073
|
+
if (_cacheKey && g_audioBufferCache.has(_cacheKey)) {
|
|
12074
|
+
g_audio.setBuffer(g_audioBufferCache.get(_cacheKey)); // デコード完全スキップ
|
|
12075
|
+
return;
|
|
12076
|
+
}
|
|
12077
|
+
const array = base64ToUint8Array(_base64);
|
|
12052
12078
|
await g_audio.init(array.buffer);
|
|
12079
|
+
if (_cacheKey) {
|
|
12080
|
+
cacheAudioBuffer(_cacheKey, g_audio.getBuffer());
|
|
12081
|
+
}
|
|
12053
12082
|
};
|
|
12054
12083
|
|
|
12055
12084
|
// 音声ファイルを読み込んでWebAudioAPIで再生する準備
|
|
@@ -12061,6 +12090,26 @@ const initWebAudioAPIfromURL = async (_url) => {
|
|
|
12061
12090
|
await g_audio.init(arrayBuffer);
|
|
12062
12091
|
};
|
|
12063
12092
|
|
|
12093
|
+
const g_audioBufferCache = new Map();
|
|
12094
|
+
const AUDIO_CACHE_MAX = 5;
|
|
12095
|
+
|
|
12096
|
+
const cacheAudioBuffer = (_key, _buffer) => {
|
|
12097
|
+
g_audioBufferCache.set(_key, _buffer);
|
|
12098
|
+
if (g_audioBufferCache.size > AUDIO_CACHE_MAX) {
|
|
12099
|
+
g_audioBufferCache.delete(g_audioBufferCache.keys().next().value); // 古い順に破棄
|
|
12100
|
+
}
|
|
12101
|
+
};
|
|
12102
|
+
|
|
12103
|
+
const base64ToUint8Array = (_base64Str) => {
|
|
12104
|
+
const binaryStr = atob(_base64Str);
|
|
12105
|
+
const len = binaryStr.length;
|
|
12106
|
+
const array = new Uint8Array(len);
|
|
12107
|
+
for (let i = 0; i < len; i++) {
|
|
12108
|
+
array[i] = binaryStr.charCodeAt(i);
|
|
12109
|
+
}
|
|
12110
|
+
return array;
|
|
12111
|
+
};
|
|
12112
|
+
|
|
12064
12113
|
const musicAfterLoaded = () => {
|
|
12065
12114
|
g_audio.load();
|
|
12066
12115
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2019/11/19
|
|
8
|
-
* Revised : 2026/
|
|
8
|
+
* Revised : 2026/07/04 (v49.1.1)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -145,7 +145,8 @@ const g_localeObj = {
|
|
|
145
145
|
};
|
|
146
146
|
|
|
147
147
|
const g_userAgent = window.navigator.userAgent.toLowerCase(); // msie, edge, chrome, safari, firefox, opera
|
|
148
|
-
const g_isIos = listMatching(g_userAgent, [`iphone`, `ipad`, `ipod`])
|
|
148
|
+
const g_isIos = listMatching(g_userAgent, [`iphone`, `ipad`, `ipod`]) ||
|
|
149
|
+
(navigator.maxTouchPoints > 1 && /macintosh/i.test(g_userAgent));
|
|
149
150
|
const g_isMac = listMatching(g_userAgent, [`iphone`, `ipad`, `ipod`, `mac os`]);
|
|
150
151
|
|
|
151
152
|
// 変数型
|