Update index.html
Browse files- index.html +78 -27
index.html
CHANGED
@@ -820,18 +820,24 @@
|
|
820 |
window.alert(`${message}\n\nエラー詳細: ${error.message}`);
|
821 |
}
|
822 |
|
823 |
-
//
|
824 |
function setPreservesPitch(el, value) {
|
825 |
try {
|
826 |
if (el.preservesPitch !== undefined) {
|
827 |
el.preservesPitch = value;
|
828 |
-
}
|
829 |
-
if (el.webkitPreservesPitch !== undefined) {
|
830 |
el.webkitPreservesPitch = value;
|
831 |
-
}
|
832 |
-
if (el.mozPreservesPitch !== undefined) {
|
833 |
el.mozPreservesPitch = value;
|
834 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
835 |
} catch (error) {
|
836 |
handleError(error, 'ピッチ設定中にエラーが発生しました');
|
837 |
}
|
@@ -1176,9 +1182,14 @@
|
|
1176 |
// 音声の再生速度を変更
|
1177 |
audioFiles.forEach(file => {
|
1178 |
if (audioElements[file]) {
|
1179 |
-
|
1180 |
-
// ピッチ保持を確実に設定
|
1181 |
setPreservesPitch(audioElements[file], true);
|
|
|
|
|
|
|
|
|
|
|
|
|
1182 |
}
|
1183 |
});
|
1184 |
} catch (error) {
|
@@ -1242,7 +1253,7 @@
|
|
1242 |
}
|
1243 |
});
|
1244 |
|
1245 |
-
// 音声ファイルをロード
|
1246 |
function loadAudioFiles() {
|
1247 |
audioFiles.forEach(file => {
|
1248 |
try {
|
@@ -1250,28 +1261,39 @@
|
|
1250 |
audio.preload = 'auto';
|
1251 |
audio.loop = false;
|
1252 |
|
1253 |
-
//
|
1254 |
setPreservesPitch(audio, true);
|
1255 |
|
1256 |
-
// 初期音量設定
|
1257 |
-
|
1258 |
-
if (slider) {
|
1259 |
-
audio.volume = parseFloat(slider.value) * (parseFloat(globalVolumeSlider.value) / 10);
|
1260 |
-
}
|
1261 |
|
1262 |
audioElements[file] = audio;
|
1263 |
|
1264 |
// 音声が読み込まれたら
|
1265 |
-
|
1266 |
console.log(`${file}.mp3 loaded`);
|
|
|
1267 |
checkLoadingComplete();
|
1268 |
-
|
|
|
|
|
|
|
1269 |
|
1270 |
// エラー処理
|
1271 |
-
|
1272 |
handleError(audio.error, `音声ファイル読み込み中にエラーが発生しました (${file}.mp3)`);
|
1273 |
checkLoadingComplete(); // エラー時もカウント
|
1274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1275 |
} catch (error) {
|
1276 |
handleError(error, `音声ファイル初期化中にエラーが発生しました (${file}.mp3)`);
|
1277 |
checkLoadingComplete(); // エラー時もカウント
|
@@ -1279,7 +1301,7 @@
|
|
1279 |
});
|
1280 |
}
|
1281 |
|
1282 |
-
//
|
1283 |
audioSliders.forEach((slider, index) => {
|
1284 |
slider.addEventListener('input', function() {
|
1285 |
try {
|
@@ -1288,35 +1310,50 @@
|
|
1288 |
|
1289 |
if (audioElements[this.dataset.audio]) {
|
1290 |
const globalVolume = parseFloat(globalVolumeSlider.value) / 10;
|
1291 |
-
|
|
|
|
|
|
|
|
|
1292 |
}
|
1293 |
} catch (error) {
|
1294 |
handleError(error, '音声ボリューム設定中にエラーが発生しました');
|
1295 |
}
|
1296 |
});
|
|
|
|
|
|
|
|
|
1297 |
});
|
1298 |
|
1299 |
-
// 全体音量スライダーのイベント
|
1300 |
globalVolumeSlider.addEventListener('input', function() {
|
1301 |
try {
|
1302 |
const value = parseFloat(this.value);
|
1303 |
globalVolumeValue.textContent = value.toFixed(1);
|
1304 |
|
1305 |
-
// 各音声の音量を更新
|
1306 |
audioFiles.forEach(file => {
|
1307 |
if (audioElements[file]) {
|
1308 |
-
const
|
1309 |
-
if (
|
1310 |
-
const
|
1311 |
-
|
|
|
1312 |
}
|
1313 |
}
|
1314 |
});
|
|
|
|
|
|
|
1315 |
} catch (error) {
|
1316 |
handleError(error, '全体音量設定中にエラーが発生しました');
|
1317 |
}
|
1318 |
});
|
1319 |
|
|
|
|
|
|
|
|
|
1320 |
// ループ設定変更時
|
1321 |
loopCheckbox.addEventListener('change', function() {
|
1322 |
try {
|
@@ -1386,7 +1423,7 @@
|
|
1386 |
|
1387 |
sliders.forEach(slider => {
|
1388 |
if (slider) {
|
1389 |
-
slider.style.backgroundImage = 'linear-gradient(#
|
1390 |
slider.style.backgroundRepeat = 'no-repeat';
|
1391 |
}
|
1392 |
});
|
@@ -1415,6 +1452,20 @@
|
|
1415 |
volumeSlider.value = video.volume;
|
1416 |
video.controls = false;
|
1417 |
initSliderBackgrounds();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1418 |
});
|
1419 |
</script>
|
1420 |
</body>
|
|
|
820 |
window.alert(`${message}\n\nエラー詳細: ${error.message}`);
|
821 |
}
|
822 |
|
823 |
+
// ピッチ設定関数 (改良版)
|
824 |
function setPreservesPitch(el, value) {
|
825 |
try {
|
826 |
if (el.preservesPitch !== undefined) {
|
827 |
el.preservesPitch = value;
|
828 |
+
} else if (el.webkitPreservesPitch !== undefined) {
|
|
|
829 |
el.webkitPreservesPitch = value;
|
830 |
+
} else if (el.mozPreservesPitch !== undefined) {
|
|
|
831 |
el.mozPreservesPitch = value;
|
832 |
}
|
833 |
+
|
834 |
+
// ピッチ保持を確実にするための追加設定
|
835 |
+
if (el.playbackRate !== undefined) {
|
836 |
+
const rate = el.playbackRate;
|
837 |
+
// 一度1.0に戻してから再設定
|
838 |
+
el.playbackRate = 1.0;
|
839 |
+
el.playbackRate = rate;
|
840 |
+
}
|
841 |
} catch (error) {
|
842 |
handleError(error, 'ピッチ設定中にエラーが発生しました');
|
843 |
}
|
|
|
1182 |
// 音声の再生速度を変更
|
1183 |
audioFiles.forEach(file => {
|
1184 |
if (audioElements[file]) {
|
1185 |
+
// ピッチ保持を確実にする
|
|
|
1186 |
setPreservesPitch(audioElements[file], true);
|
1187 |
+
audioElements[file].playbackRate = speed;
|
1188 |
+
|
1189 |
+
// 再生速度変更後に再度ピッチ保持を確認
|
1190 |
+
setTimeout(() => {
|
1191 |
+
setPreservesPitch(audioElements[file], true);
|
1192 |
+
}, 100);
|
1193 |
}
|
1194 |
});
|
1195 |
} catch (error) {
|
|
|
1253 |
}
|
1254 |
});
|
1255 |
|
1256 |
+
// 音声ファイルをロード (改良版)
|
1257 |
function loadAudioFiles() {
|
1258 |
audioFiles.forEach(file => {
|
1259 |
try {
|
|
|
1261 |
audio.preload = 'auto';
|
1262 |
audio.loop = false;
|
1263 |
|
1264 |
+
// 初期ピッチ設定
|
1265 |
setPreservesPitch(audio, true);
|
1266 |
|
1267 |
+
// 初期音量設定 (0.5)
|
1268 |
+
audio.volume = 0.5;
|
|
|
|
|
|
|
1269 |
|
1270 |
audioElements[file] = audio;
|
1271 |
|
1272 |
// 音声が読み込まれたら
|
1273 |
+
const onLoaded = function() {
|
1274 |
console.log(`${file}.mp3 loaded`);
|
1275 |
+
setPreservesPitch(audio, true); // 再度ピッチ保持を設定
|
1276 |
checkLoadingComplete();
|
1277 |
+
audio.removeEventListener('loadedmetadata', onLoaded);
|
1278 |
+
};
|
1279 |
+
|
1280 |
+
audio.addEventListener('loadedmetadata', onLoaded);
|
1281 |
|
1282 |
// エラー処理
|
1283 |
+
const onError = function() {
|
1284 |
handleError(audio.error, `音声ファイル読み込み中にエラーが発生しました (${file}.mp3)`);
|
1285 |
checkLoadingComplete(); // エラー時もカウント
|
1286 |
+
audio.removeEventListener('error', onError);
|
1287 |
+
};
|
1288 |
+
|
1289 |
+
audio.addEventListener('error', onError);
|
1290 |
+
|
1291 |
+
// 音声ファイルの読み込みを開始
|
1292 |
+
try {
|
1293 |
+
audio.load();
|
1294 |
+
} catch (e) {
|
1295 |
+
console.error(`音声ファイル読み込みエラー (${file}.mp3):`, e);
|
1296 |
+
}
|
1297 |
} catch (error) {
|
1298 |
handleError(error, `音声ファイル初期化中にエラーが発生しました (${file}.mp3)`);
|
1299 |
checkLoadingComplete(); // エラー時もカウント
|
|
|
1301 |
});
|
1302 |
}
|
1303 |
|
1304 |
+
// ボリュームスライダ��のイベント (修正版)
|
1305 |
audioSliders.forEach((slider, index) => {
|
1306 |
slider.addEventListener('input', function() {
|
1307 |
try {
|
|
|
1310 |
|
1311 |
if (audioElements[this.dataset.audio]) {
|
1312 |
const globalVolume = parseFloat(globalVolumeSlider.value) / 10;
|
1313 |
+
const calculatedVolume = value * globalVolume;
|
1314 |
+
audioElements[this.dataset.audio].volume = calculatedVolume;
|
1315 |
+
|
1316 |
+
// スライダーの背景を更新
|
1317 |
+
updateSliderBackgrounds();
|
1318 |
}
|
1319 |
} catch (error) {
|
1320 |
handleError(error, '音声ボリューム設定中にエラーが発生しました');
|
1321 |
}
|
1322 |
});
|
1323 |
+
|
1324 |
+
// 初期値を1.00に設定
|
1325 |
+
slider.value = 1;
|
1326 |
+
volumeValues[index].textContent = '1.00';
|
1327 |
});
|
1328 |
|
1329 |
+
// 全体音量スライダーのイベント (修正版)
|
1330 |
globalVolumeSlider.addEventListener('input', function() {
|
1331 |
try {
|
1332 |
const value = parseFloat(this.value);
|
1333 |
globalVolumeValue.textContent = value.toFixed(1);
|
1334 |
|
|
|
1335 |
audioFiles.forEach(file => {
|
1336 |
if (audioElements[file]) {
|
1337 |
+
const volumeSlider = document.querySelector(`.audio-slider[data-audio="${file}"]`);
|
1338 |
+
if (volumeSlider) {
|
1339 |
+
const sliderValue = parseFloat(volumeSlider.value);
|
1340 |
+
const calculatedVolume = sliderValue * (value / 10);
|
1341 |
+
audioElements[file].volume = calculatedVolume;
|
1342 |
}
|
1343 |
}
|
1344 |
});
|
1345 |
+
|
1346 |
+
// スライダーの背景を更新
|
1347 |
+
updateSliderBackgrounds();
|
1348 |
} catch (error) {
|
1349 |
handleError(error, '全体音量設定中にエラーが発生しました');
|
1350 |
}
|
1351 |
});
|
1352 |
|
1353 |
+
// 初期全体音量を5.0に設定
|
1354 |
+
globalVolumeSlider.value = 5;
|
1355 |
+
globalVolumeValue.textContent = '5.0';
|
1356 |
+
|
1357 |
// ループ設定変更時
|
1358 |
loopCheckbox.addEventListener('change', function() {
|
1359 |
try {
|
|
|
1423 |
|
1424 |
sliders.forEach(slider => {
|
1425 |
if (slider) {
|
1426 |
+
slider.style.backgroundImage = 'linear-gradient(#64ffda, #64ffda)';
|
1427 |
slider.style.backgroundRepeat = 'no-repeat';
|
1428 |
}
|
1429 |
});
|
|
|
1452 |
volumeSlider.value = video.volume;
|
1453 |
video.controls = false;
|
1454 |
initSliderBackgrounds();
|
1455 |
+
|
1456 |
+
// 初期音量設定を適用
|
1457 |
+
setTimeout(() => {
|
1458 |
+
audioFiles.forEach(file => {
|
1459 |
+
if (audioElements[file]) {
|
1460 |
+
const volumeSlider = document.querySelector(`.audio-slider[data-audio="${file}"]`);
|
1461 |
+
if (volumeSlider) {
|
1462 |
+
const value = parseFloat(volumeSlider.value);
|
1463 |
+
const globalVolume = parseFloat(globalVolumeSlider.value) / 10;
|
1464 |
+
audioElements[file].volume = value * globalVolume;
|
1465 |
+
}
|
1466 |
+
}
|
1467 |
+
});
|
1468 |
+
}, 1000);
|
1469 |
});
|
1470 |
</script>
|
1471 |
</body>
|