soiz1 commited on
Commit
5ab9fd1
·
1 Parent(s): 9b4b517

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +87 -63
index.html CHANGED
@@ -1247,7 +1247,7 @@ document.addEventListener('DOMContentLoaded', function() {
1247
  let controlsVisible = true;
1248
  let isCheckingSync = false;
1249
  let isInBackgroundTab = false;
1250
- let isBlankMode = false; // 消画モードフラグ
1251
 
1252
  try {
1253
  audioContext = new (window.AudioContext || window.webkitAudioContext)();
@@ -1381,7 +1381,12 @@ document.addEventListener('DOMContentLoaded', function() {
1381
  const tempoSpeedValue = document.getElementById('tempo-speed-value');
1382
  const videoControls = document.querySelector('.video-controls');
1383
  const applyTimeBtn = document.getElementById('apply-time-btn');
1384
- const blankModeBtn = document.getElementById('blank-mode-btn'); // 消画モードボタン
 
 
 
 
 
1385
 
1386
  // 音声オブジェクトを作成
1387
  const audioElements = {};
@@ -1390,8 +1395,6 @@ document.addEventListener('DOMContentLoaded', function() {
1390
  let combinedAudioElement = null;
1391
  let isAudioCombined = false;
1392
  let currentVolumes = { p: 0, a: 1, t: 1, s: 1, k: 0 };
1393
- let appliedStartTime = 0;
1394
- let appliedEndTime = 0;
1395
 
1396
  // 初期化
1397
  let videoDuration = 0;
@@ -1399,22 +1402,7 @@ document.addEventListener('DOMContentLoaded', function() {
1399
  let lastVolume = 1;
1400
  let currentPlaybackRate = 1;
1401
  let isFullscreen = false;
1402
-
1403
- // 消画モード切り替え
1404
- function toggleBlankMode() {
1405
- isBlankMode = !isBlankMode;
1406
- if (isBlankMode) {
1407
- video.style.backgroundColor = 'black';
1408
- video.style.opacity = '0';
1409
- blankModeBtn.textContent = '消画モード: ON';
1410
- blankModeBtn.classList.add('active');
1411
- } else {
1412
- video.style.backgroundColor = '';
1413
- video.style.opacity = '1';
1414
- blankModeBtn.textContent = '消画モード: OFF';
1415
- blankModeBtn.classList.remove('active');
1416
- }
1417
- }
1418
 
1419
  async function enterPiP() {
1420
  if (!document.pictureInPictureElement && !video.paused) {
@@ -1435,7 +1423,7 @@ document.addEventListener('DOMContentLoaded', function() {
1435
  }
1436
  }
1437
  }
1438
-
1439
  // 動画のバッファリング状態を監視
1440
  video.addEventListener('waiting', function() {
1441
  isBuffering = true;
@@ -1496,6 +1484,9 @@ document.addEventListener('DOMContentLoaded', function() {
1496
  }
1497
 
1498
  applyTimeBtn.addEventListener('click', function() {
 
 
 
1499
  // 現在再生中なら一時停止
1500
  const wasPlaying = isPlaying;
1501
  if (isPlaying) {
@@ -1503,21 +1494,21 @@ document.addEventListener('DOMContentLoaded', function() {
1503
  }
1504
 
1505
  // 開始時間と終了時間を取得
1506
- appliedStartTime = parseFloat(startTimeInput.value) || 0;
1507
- appliedEndTime = parseFloat(endTimeInput.value) || video.duration;
1508
 
1509
  // 現在位置が開始時間より前なら開始時間に移動
1510
- if (video.currentTime < appliedStartTime) {
1511
- video.currentTime = appliedStartTime;
1512
  if (combinedAudioElement) {
1513
- combinedAudioElement.currentTime = appliedStartTime;
1514
  }
1515
  }
1516
  // 現在位置が終了時間より後なら開始時間に移動
1517
- else if (video.currentTime > appliedEndTime) {
1518
- video.currentTime = appliedStartTime;
1519
  if (combinedAudioElement) {
1520
- combinedAudioElement.currentTime = appliedStartTime;
1521
  }
1522
  }
1523
 
@@ -1575,11 +1566,9 @@ document.addEventListener('DOMContentLoaded', function() {
1575
 
1576
  // 音声を結合する関数
1577
  async function combineAudio() {
1578
- // 既存の音声を停止して解放
1579
- if (combinedAudioElement) {
1580
- combinedAudioElement.pause();
1581
- combinedAudioElement.src = '';
1582
- combinedAudioElement = null;
1583
  }
1584
 
1585
  combineButton.disabled = true;
@@ -1661,6 +1650,10 @@ document.addEventListener('DOMContentLoaded', function() {
1661
  const url = URL.createObjectURL(blob);
1662
 
1663
  // 新しいaudio要素を作成
 
 
 
 
1664
  combinedAudioElement = new Audio(url);
1665
  combinedAudioElement.preservesPitch = true;
1666
  combinedAudioElement.mozPreservesPitch = true;
@@ -1668,6 +1661,7 @@ document.addEventListener('DOMContentLoaded', function() {
1668
  combinedAudioElement.playbackRate = currentPlaybackRate;
1669
 
1670
  isAudioCombined = true;
 
1671
  combineStatus.textContent = "音声の合成が完了しました";
1672
  enablePlayerControls();
1673
 
@@ -1730,7 +1724,7 @@ document.addEventListener('DOMContentLoaded', function() {
1730
 
1731
  // 動画終了時に自動的にPiPを閉じる(次回再開のため)
1732
  video.addEventListener('ended', exitPiP);
1733
-
1734
  // 合成後に音量と再生速度を適用
1735
  applyVolume();
1736
  applyPlaybackRate();
@@ -1848,7 +1842,7 @@ document.addEventListener('DOMContentLoaded', function() {
1848
  setEndTimeBtn.disabled = false;
1849
  playbackSpeedSlider.disabled = false;
1850
  applyTimeBtn.disabled = false;
1851
- blankModeBtn.disabled = false;
1852
  }
1853
 
1854
  // プレビュー再生
@@ -1904,6 +1898,7 @@ document.addEventListener('DOMContentLoaded', function() {
1904
  endTimeInput.max = videoDuration;
1905
  startTimeInput.max = videoDuration - 0.1;
1906
  updateTimeDisplay();
 
1907
  checkLoadingComplete();
1908
  } catch (error) {
1909
  handleError(error, '動画メタデータ読み込み中にエラーが発生しました');
@@ -1917,11 +1912,15 @@ document.addEventListener('DOMContentLoaded', function() {
1917
 
1918
  // 再生ボタンクリック
1919
  playPauseBtn.addEventListener('click', function() {
1920
- if (video.currentTime >= appliedEndTime) {
1921
- video.currentTime = appliedStartTime;
1922
- if (combinedAudioElement) {
1923
- combinedAudioElement.currentTime = appliedStartTime;
1924
- }
 
 
 
 
1925
  }
1926
  togglePlayPause();
1927
  });
@@ -1966,9 +1965,11 @@ document.addEventListener('DOMContentLoaded', function() {
1966
  function playMedia() {
1967
  try {
1968
  const duration = video.duration || videoDuration;
 
 
1969
 
1970
- if (video.currentTime >= appliedEndTime) {
1971
- video.currentTime = appliedStartTime;
1972
  }
1973
 
1974
  const playPromise = video.play();
@@ -2017,17 +2018,24 @@ document.addEventListener('DOMContentLoaded', function() {
2017
 
2018
  // 時間更新時の処理
2019
  video.addEventListener('timeupdate', function() {
 
 
2020
  const duration = video.duration || videoDuration;
 
2021
 
2022
- if (video.currentTime >= appliedEndTime && appliedEndTime > 0) {
2023
  if (loopCheckbox.checked) {
2024
- video.currentTime = appliedStartTime;
 
2025
  if (combinedAudioElement) {
2026
- combinedAudioElement.currentTime = appliedStartTime;
2027
  }
2028
  } else {
2029
  pauseMedia();
2030
- video.currentTime = appliedEndTime;
 
 
 
2031
  }
2032
  }
2033
 
@@ -2049,7 +2057,10 @@ document.addEventListener('DOMContentLoaded', function() {
2049
  function seekMedia(time) {
2050
  try {
2051
  const duration = video.duration || videoDuration;
2052
- const seekTime = Math.max(appliedStartTime, Math.min(time, appliedEndTime));
 
 
 
2053
  video.currentTime = seekTime;
2054
 
2055
  if (combinedAudioElement) {
@@ -2352,8 +2363,22 @@ document.addEventListener('DOMContentLoaded', function() {
2352
  }
2353
  }
2354
 
2355
- // 消画モードボタンのクリック処理
2356
- blankModeBtn.addEventListener('click', toggleBlankMode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2357
 
2358
  // 合成ボタンクリック
2359
  combineButton.addEventListener('click', combineAudio);
@@ -2408,7 +2433,7 @@ document.addEventListener('DOMContentLoaded', function() {
2408
 
2409
  // タイムマーカー関連のコード
2410
  document.addEventListener('DOMContentLoaded', function() {
2411
- // 必要なDOM要素を取得
2412
  const startMarker = document.getElementById('start-marker');
2413
  const endMarker = document.getElementById('end-marker');
2414
  const video = document.getElementById('video');
@@ -2505,21 +2530,20 @@ document.addEventListener('DOMContentLoaded', function() {
2505
  const endTime = parseFloat(endTimeInput.value) || duration;
2506
 
2507
  if (duration > 0) {
2508
- if(startMarker) startMarker.style.left = `${(startTime / duration) * 100}%`;
2509
- if(endMarker) endMarker.style.left = `${(endTime / duration) * 100}%`;
2510
-
2511
  // 開始時間が0の場合はマーカーを非表示
2512
- if(startTime <= 0 && startMarker) {
2513
- startMarker.style.display = 'none';
2514
- } else if(startMarker) {
2515
- startMarker.style.display = 'block';
 
2516
  }
2517
-
2518
  // 終了時間が動画の長さと同じ場合はマーカーを非表示
2519
- if(endTime >= duration && endMarker) {
2520
- endMarker.style.display = 'none';
2521
- } else if(endMarker) {
2522
- endMarker.style.display = 'block';
 
2523
  }
2524
  }
2525
  }
 
1247
  let controlsVisible = true;
1248
  let isCheckingSync = false;
1249
  let isInBackgroundTab = false;
1250
+ let isBlackVideoMode = false; // 消画モードフラグ
1251
 
1252
  try {
1253
  audioContext = new (window.AudioContext || window.webkitAudioContext)();
 
1381
  const tempoSpeedValue = document.getElementById('tempo-speed-value');
1382
  const videoControls = document.querySelector('.video-controls');
1383
  const applyTimeBtn = document.getElementById('apply-time-btn');
1384
+ const blackVideoToggle = document.createElement('button');
1385
+ blackVideoToggle.className = 'control-button';
1386
+ blackVideoToggle.id = 'black-video-btn';
1387
+ blackVideoToggle.textContent = '消画モード';
1388
+ blackVideoToggle.title = '動画を黒画面に切り替え(読み込み遅延防止)';
1389
+ document.querySelector('.main-controls').appendChild(blackVideoToggle);
1390
 
1391
  // 音声オブジェクトを作成
1392
  const audioElements = {};
 
1395
  let combinedAudioElement = null;
1396
  let isAudioCombined = false;
1397
  let currentVolumes = { p: 0, a: 1, t: 1, s: 1, k: 0 };
 
 
1398
 
1399
  // 初期化
1400
  let videoDuration = 0;
 
1402
  let lastVolume = 1;
1403
  let currentPlaybackRate = 1;
1404
  let isFullscreen = false;
1405
+ let isTimeApplied = false; // 時間設定が適用されたかどうか
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1406
 
1407
  async function enterPiP() {
1408
  if (!document.pictureInPictureElement && !video.paused) {
 
1423
  }
1424
  }
1425
  }
1426
+
1427
  // 動画のバッファリング状態を監視
1428
  video.addEventListener('waiting', function() {
1429
  isBuffering = true;
 
1484
  }
1485
 
1486
  applyTimeBtn.addEventListener('click', function() {
1487
+ // 時間設定を適用
1488
+ isTimeApplied = true;
1489
+
1490
  // 現在再生中なら一時停止
1491
  const wasPlaying = isPlaying;
1492
  if (isPlaying) {
 
1494
  }
1495
 
1496
  // 開始時間と終了時間を取得
1497
+ const startTime = parseFloat(startTimeInput.value) || 0;
1498
+ const endTime = parseFloat(endTimeInput.value) || video.duration;
1499
 
1500
  // 現在位置が開始時間より前なら開始時間に移動
1501
+ if (video.currentTime < startTime) {
1502
+ video.currentTime = startTime;
1503
  if (combinedAudioElement) {
1504
+ combinedAudioElement.currentTime = startTime;
1505
  }
1506
  }
1507
  // 現在位置が終了時間より後なら開始時間に移動
1508
+ else if (video.currentTime > endTime) {
1509
+ video.currentTime = startTime;
1510
  if (combinedAudioElement) {
1511
+ combinedAudioElement.currentTime = startTime;
1512
  }
1513
  }
1514
 
 
1566
 
1567
  // 音声を結合する関数
1568
  async function combineAudio() {
1569
+ // 再生中なら停止
1570
+ if (isPlaying) {
1571
+ pauseMedia();
 
 
1572
  }
1573
 
1574
  combineButton.disabled = true;
 
1650
  const url = URL.createObjectURL(blob);
1651
 
1652
  // 新しいaudio要素を作成
1653
+ if (combinedAudioElement) {
1654
+ combinedAudioElement.pause();
1655
+ URL.revokeObjectURL(combinedAudioElement.src);
1656
+ }
1657
  combinedAudioElement = new Audio(url);
1658
  combinedAudioElement.preservesPitch = true;
1659
  combinedAudioElement.mozPreservesPitch = true;
 
1661
  combinedAudioElement.playbackRate = currentPlaybackRate;
1662
 
1663
  isAudioCombined = true;
1664
+ isTimeApplied = false; // 音声再合成時に時間設定をリセット
1665
  combineStatus.textContent = "音声の合成が完了しました";
1666
  enablePlayerControls();
1667
 
 
1724
 
1725
  // 動画終了時に自動的にPiPを閉じる(次回再開のため)
1726
  video.addEventListener('ended', exitPiP);
1727
+
1728
  // 合成後に音量と再生速度を適用
1729
  applyVolume();
1730
  applyPlaybackRate();
 
1842
  setEndTimeBtn.disabled = false;
1843
  playbackSpeedSlider.disabled = false;
1844
  applyTimeBtn.disabled = false;
1845
+ blackVideoToggle.disabled = false;
1846
  }
1847
 
1848
  // プレビュー再生
 
1898
  endTimeInput.max = videoDuration;
1899
  startTimeInput.max = videoDuration - 0.1;
1900
  updateTimeDisplay();
1901
+ updateProgressMarkers(); // マーカーを初期化
1902
  checkLoadingComplete();
1903
  } catch (error) {
1904
  handleError(error, '動画メタデータ読み込み中にエラーが発生しました');
 
1912
 
1913
  // 再生ボタンクリック
1914
  playPauseBtn.addEventListener('click', function() {
1915
+ if (!isTimeApplied) {
1916
+ alert('時間設定を適用してください');
1917
+ return;
1918
+ }
1919
+
1920
+ const endTime = parseFloat(endTimeInput.value) || videoDuration;
1921
+ if (video.currentTime >= endTime) {
1922
+ const startTime = parseFloat(startTimeInput.value) || 0;
1923
+ seekMedia(startTime);
1924
  }
1925
  togglePlayPause();
1926
  });
 
1965
  function playMedia() {
1966
  try {
1967
  const duration = video.duration || videoDuration;
1968
+ const startTime = parseFloat(startTimeInput.value) || 0;
1969
+ const endTime = parseFloat(endTimeInput.value) || duration;
1970
 
1971
+ if (video.currentTime >= endTime) {
1972
+ video.currentTime = startTime;
1973
  }
1974
 
1975
  const playPromise = video.play();
 
2018
 
2019
  // 時間更新時の処理
2020
  video.addEventListener('timeupdate', function() {
2021
+ if (!isTimeApplied) return;
2022
+
2023
  const duration = video.duration || videoDuration;
2024
+ const endTime = parseFloat(endTimeInput.value) || duration;
2025
 
2026
+ if (video.currentTime >= endTime && endTime > 0) {
2027
  if (loopCheckbox.checked) {
2028
+ const startTime = parseFloat(startTimeInput.value) || 0;
2029
+ video.currentTime = startTime;
2030
  if (combinedAudioElement) {
2031
+ combinedAudioElement.currentTime = startTime;
2032
  }
2033
  } else {
2034
  pauseMedia();
2035
+ video.currentTime = endTime;
2036
+ if (combinedAudioElement) {
2037
+ combinedAudioElement.currentTime = endTime;
2038
+ }
2039
  }
2040
  }
2041
 
 
2057
  function seekMedia(time) {
2058
  try {
2059
  const duration = video.duration || videoDuration;
2060
+ const startTime = parseFloat(startTimeInput.value) || 0;
2061
+ const endTime = parseFloat(endTimeInput.value) || duration;
2062
+
2063
+ const seekTime = Math.max(startTime, Math.min(time, endTime));
2064
  video.currentTime = seekTime;
2065
 
2066
  if (combinedAudioElement) {
 
2363
  }
2364
  }
2365
 
2366
+ // 消画モード切り替え
2367
+ blackVideoToggle.addEventListener('click', function() {
2368
+ isBlackVideoMode = !isBlackVideoMode;
2369
+
2370
+ if (isBlackVideoMode) {
2371
+ // 消画モードON
2372
+ video.style.filter = 'brightness(0)';
2373
+ this.style.backgroundColor = '#64ffda';
2374
+ this.style.color = '#0a192f';
2375
+ } else {
2376
+ // 消画モードOFF
2377
+ video.style.filter = '';
2378
+ this.style.backgroundColor = '';
2379
+ this.style.color = '';
2380
+ }
2381
+ });
2382
 
2383
  // 合成ボタンクリック
2384
  combineButton.addEventListener('click', combineAudio);
 
2433
 
2434
  // タイムマーカー関連のコード
2435
  document.addEventListener('DOMContentLoaded', function() {
2436
+ // まず必要なDOM要素を取得
2437
  const startMarker = document.getElementById('start-marker');
2438
  const endMarker = document.getElementById('end-marker');
2439
  const video = document.getElementById('video');
 
2530
  const endTime = parseFloat(endTimeInput.value) || duration;
2531
 
2532
  if (duration > 0) {
 
 
 
2533
  // 開始時間が0の場合はマーカーを非表示
2534
+ if (startTime <= 0) {
2535
+ if(startMarker) startMarker.style.display = 'none';
2536
+ } else {
2537
+ if(startMarker) startMarker.style.left = `${(startTime / duration) * 100}%`;
2538
+ if(startMarker) startMarker.style.display = 'block';
2539
  }
2540
+
2541
  // 終了時間が動画の長さと同じ場合はマーカーを非表示
2542
+ if (endTime >= duration) {
2543
+ if(endMarker) endMarker.style.display = 'none';
2544
+ } else {
2545
+ if(endMarker) endMarker.style.left = `${(endTime / duration) * 100}%`;
2546
+ if(endMarker) endMarker.style.display = 'block';
2547
  }
2548
  }
2549
  }