Update index.html
Browse files- index.html +59 -57
index.html
CHANGED
@@ -697,63 +697,65 @@
|
|
697 |
});
|
698 |
}
|
699 |
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
|
|
|
|
757 |
|
758 |
// 再生関数
|
759 |
function playMedia() {
|
|
|
697 |
});
|
698 |
}
|
699 |
|
700 |
+
function playAudio(file, startTime) {
|
701 |
+
if (!audioBuffers[file]) return;
|
702 |
+
|
703 |
+
// 既存のソースがあれば停止
|
704 |
+
if (audioSources[file]) {
|
705 |
+
try {
|
706 |
+
audioSources[file].stop();
|
707 |
+
} catch(e) {
|
708 |
+
console.log("Audio source already stopped");
|
709 |
+
}
|
710 |
+
}
|
711 |
+
|
712 |
+
const source = audioContext.createBufferSource();
|
713 |
+
source.buffer = audioBuffers[file];
|
714 |
+
|
715 |
+
// SoundTouch プロセッサーを作成
|
716 |
+
soundTouchNodes[file] = new soundtouch.SoundTouch(audioBuffers[file].sampleRate);
|
717 |
+
soundTouchNodes[file].tempo = currentPlaybackRate;
|
718 |
+
soundTouchNodes[file].pitch = 1; // ピッチ変更なし
|
719 |
+
|
720 |
+
// SimpleFilter を作成し、Web Audio Node を取得
|
721 |
+
const soundTouchProcessor = new soundtouch.SimpleFilter(audioContext, source, soundTouchNodes[file]);
|
722 |
+
const soundTouchNode = soundTouchProcessor.getWebAudioNode();
|
723 |
+
|
724 |
+
// ボリュームスライダーの値を取得
|
725 |
+
const volumeSlider = document.querySelector(`.audio-slider[data-audio="${file}"]`);
|
726 |
+
const volume = parseFloat(volumeSlider.value) * parseFloat(globalVolumeSlider.value);
|
727 |
+
|
728 |
+
// ゲインノードを設定
|
729 |
+
gainNodes[file].gain.value = volume;
|
730 |
+
|
731 |
+
// 接続
|
732 |
+
soundTouchNode.connect(gainNodes[file]);
|
733 |
+
gainNodes[file].connect(audioContext.destination);
|
734 |
+
|
735 |
+
// 再生
|
736 |
+
const duration = video.duration || videoDuration;
|
737 |
+
const endTime = parseFloat(endTimeInput.value) || duration;
|
738 |
+
const loop = loopCheckbox.checked;
|
739 |
+
|
740 |
+
// 再生範囲を計算
|
741 |
+
const playStartTime = Math.max(startTime, parseFloat(startTimeInput.value) || 0);
|
742 |
+
const playEndTime = Math.min(endTime, duration);
|
743 |
+
const playDuration = playEndTime - playStartTime;
|
744 |
+
|
745 |
+
// 再生時間が正の場合のみ再生
|
746 |
+
if (playDuration > 0) {
|
747 |
+
source.start(0, playStartTime, playDuration);
|
748 |
+
}
|
749 |
+
|
750 |
+
// ループ設定
|
751 |
+
if (loop) {
|
752 |
+
source.loop = true;
|
753 |
+
source.loopStart = parseFloat(startTimeInput.value) || 0;
|
754 |
+
source.loopEnd = endTime;
|
755 |
+
}
|
756 |
+
|
757 |
+
audioSources[file] = source;
|
758 |
+
}
|
759 |
|
760 |
// 再生関数
|
761 |
function playMedia() {
|