soiz1 commited on
Commit
a4d3d5d
·
1 Parent(s): f930612

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +82 -51
index.html CHANGED
@@ -444,7 +444,6 @@
444
  const audioBuffers = {};
445
  const audioSources = {};
446
  const gainNodes = {};
447
- const pitchShiftNodes = {};
448
 
449
  // 音声ファイル名の配列
450
  const audioFiles = ['p', 'a', 't', 's', 'k'];
@@ -454,7 +453,6 @@
454
  let isPlaying = false;
455
  let isVideoPlaying = false;
456
  let lastVolume = 1;
457
- let shouldPlayFromStartTime = false;
458
 
459
  // 動画のメタデータが読み込まれたら
460
  video.addEventListener('loadedmetadata', function() {
@@ -485,15 +483,25 @@
485
  }
486
 
487
  // 動画の時間更新イベント
488
- video.addEventListener('timeupdate', updateTimeDisplay);
 
 
 
 
 
 
 
 
 
 
 
489
 
490
  // 動画終了時の処理
491
  video.addEventListener('ended', function() {
492
- const startTime = parseFloat(startTimeInput.value) || 0;
493
  if (!loopCheckbox.checked) {
494
- stopMedia();
495
- video.currentTime = startTime;
496
- updateTimeDisplay();
497
  }
498
  });
499
 
@@ -552,21 +560,23 @@
552
 
553
  // 動画クリックで再生/一時停止
554
  video.addEventListener('click', function() {
555
- if (isVideoPlaying) {
556
- pauseMedia();
557
- } else {
558
- playMedia();
559
- }
560
  });
561
 
562
  // 再生/一時停止ボタン
563
- playPauseBtn.addEventListener('click', function() {
 
 
 
 
 
 
564
  if (isVideoPlaying) {
565
  pauseMedia();
566
  } else {
567
  playMedia();
568
  }
569
- });
570
 
571
  // 音量コントロール
572
  volumeSlider.addEventListener('input', function() {
@@ -617,13 +627,14 @@
617
  updatePlaybackRate(speed);
618
  });
619
 
620
- // 再生速度を更新 (音の高さを維持)
621
  function updatePlaybackRate(speed) {
622
  video.playbackRate = speed;
623
 
624
- // 音声の再生速度も更新 (音の高さは維持)
625
  audioFiles.forEach(file => {
626
  if (audioSources[file]) {
 
627
  audioSources[file].playbackRate.value = speed;
628
  }
629
  });
@@ -675,6 +686,15 @@
675
  function playAudio(file, startTime) {
676
  if (!audioBuffers[file]) return;
677
 
 
 
 
 
 
 
 
 
 
678
  const source = audioContext.createBufferSource();
679
  source.buffer = audioBuffers[file];
680
 
@@ -690,26 +710,28 @@
690
  gainNodes[file].connect(audioContext.destination);
691
 
692
  // 再生
693
- const currentTime = video.currentTime;
694
  const duration = video.duration || videoDuration;
695
  const endTime = parseFloat(endTimeInput.value) || duration;
696
  const loop = loopCheckbox.checked;
697
 
698
  // 再生範囲を計算
699
  const playStartTime = Math.max(startTime, parseFloat(startTimeInput.value) || 0);
700
- const playDuration = Math.min(endTime, duration) - playStartTime;
 
701
 
702
- source.start(0, playStartTime, playDuration);
 
 
 
703
 
704
  // ループ設定
705
- source.loop = loop;
706
  if (loop) {
707
- const start = parseFloat(startTimeInput.value) || 0;
708
- source.loopStart = start;
709
  source.loopEnd = endTime;
710
  }
711
 
712
- // 再生速度を同期 (音の高さは維持)
713
  source.playbackRate.value = video.playbackRate;
714
 
715
  audioSources[file] = source;
@@ -717,33 +739,29 @@
717
 
718
  // 再生関数
719
  function playMedia() {
720
- const startTime = shouldPlayFromStartTime ? (parseFloat(startTimeInput.value) || 0) : video.currentTime;
721
- let endTime = parseFloat(endTimeInput.value) || videoDuration;
722
- shouldPlayFromStartTime = false;
723
 
724
  // 終了時間が動画の長さを超えないように
725
- endTime = Math.min(endTime, videoDuration);
726
-
727
- // 動画を設定
728
- video.currentTime = startTime;
729
- video.muted = true;
730
 
731
- // 音声を再生
732
- audioFiles.forEach(file => {
733
- if (audioBuffers[file]) {
734
- // 既存のソースがあれば停止
735
- if (audioSources[file]) {
736
- audioSources[file].stop();
737
- }
738
- playAudio(file, startTime);
739
- }
740
- });
741
 
742
  // 動画を再生
743
  video.play();
744
  isPlaying = true;
745
  isVideoPlaying = true;
746
  playPauseBtn.textContent = '⏸';
 
 
 
 
 
 
 
747
  }
748
 
749
  // 一時停止関数
@@ -753,7 +771,11 @@
753
  video.pause();
754
  audioFiles.forEach(file => {
755
  if (audioSources[file]) {
756
- audioSources[file].stop();
 
 
 
 
757
  audioSources[file] = null;
758
  }
759
  });
@@ -761,15 +783,6 @@
761
  isPlaying = false;
762
  isVideoPlaying = false;
763
  playPauseBtn.textContent = '▶';
764
- shouldPlayFromStartTime = true;
765
- }
766
-
767
- // 停止関数
768
- function stopMedia() {
769
- pauseMedia();
770
- const startTime = parseFloat(startTimeInput.value) || 0;
771
- video.currentTime = startTime;
772
- updateTimeDisplay();
773
  }
774
 
775
  // ボリュームスライダーのイベント
@@ -801,6 +814,24 @@
801
  }
802
  });
803
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  // 初期化
805
  loadAudioFiles();
806
  updateVolumeIcon();
 
444
  const audioBuffers = {};
445
  const audioSources = {};
446
  const gainNodes = {};
 
447
 
448
  // 音声ファイル名の配列
449
  const audioFiles = ['p', 'a', 't', 's', 'k'];
 
453
  let isPlaying = false;
454
  let isVideoPlaying = false;
455
  let lastVolume = 1;
 
456
 
457
  // 動画のメタデータが読み込まれたら
458
  video.addEventListener('loadedmetadata', function() {
 
483
  }
484
 
485
  // 動画の時間更新イベント
486
+ video.addEventListener('timeupdate', function() {
487
+ updateTimeDisplay();
488
+
489
+ // ループ再生の場合、終了時間をチェック
490
+ if (loopCheckbox.checked) {
491
+ const endTime = parseFloat(endTimeInput.value) || videoDuration;
492
+ if (video.currentTime >= endTime) {
493
+ const startTime = parseFloat(startTimeInput.value) || 0;
494
+ seekMedia(startTime);
495
+ }
496
+ }
497
+ });
498
 
499
  // 動画終了時の処理
500
  video.addEventListener('ended', function() {
 
501
  if (!loopCheckbox.checked) {
502
+ const startTime = parseFloat(startTimeInput.value) || 0;
503
+ seekMedia(startTime);
504
+ pauseMedia();
505
  }
506
  });
507
 
 
560
 
561
  // 動画クリックで再生/一時停止
562
  video.addEventListener('click', function() {
563
+ togglePlayPause();
 
 
 
 
564
  });
565
 
566
  // 再生/一時停止ボタン
567
+ playPauseBtn.addEventListener('click', function(e) {
568
+ e.stopPropagation(); // 動画クリックとのバブリングを防止
569
+ togglePlayPause();
570
+ });
571
+
572
+ // 再生/一時停止をトグル
573
+ function togglePlayPause() {
574
  if (isVideoPlaying) {
575
  pauseMedia();
576
  } else {
577
  playMedia();
578
  }
579
+ }
580
 
581
  // 音量コントロール
582
  volumeSlider.addEventListener('input', function() {
 
627
  updatePlaybackRate(speed);
628
  });
629
 
630
+ // 再生速度を更新 (音の高さは変更しない)
631
  function updatePlaybackRate(speed) {
632
  video.playbackRate = speed;
633
 
634
+ // 音声の再生速度も更新
635
  audioFiles.forEach(file => {
636
  if (audioSources[file]) {
637
+ // 音声の再生速度を変更しても音の高さは変わらない
638
  audioSources[file].playbackRate.value = speed;
639
  }
640
  });
 
686
  function playAudio(file, startTime) {
687
  if (!audioBuffers[file]) return;
688
 
689
+ // 既存のソースがあれば停止
690
+ if (audioSources[file]) {
691
+ try {
692
+ audioSources[file].stop();
693
+ } catch(e) {
694
+ console.log("Audio source already stopped");
695
+ }
696
+ }
697
+
698
  const source = audioContext.createBufferSource();
699
  source.buffer = audioBuffers[file];
700
 
 
710
  gainNodes[file].connect(audioContext.destination);
711
 
712
  // 再生
 
713
  const duration = video.duration || videoDuration;
714
  const endTime = parseFloat(endTimeInput.value) || duration;
715
  const loop = loopCheckbox.checked;
716
 
717
  // 再生範囲を計算
718
  const playStartTime = Math.max(startTime, parseFloat(startTimeInput.value) || 0);
719
+ const playEndTime = Math.min(endTime, duration);
720
+ const playDuration = playEndTime - playStartTime;
721
 
722
+ // 再生時間が正の場合のみ再生
723
+ if (playDuration > 0) {
724
+ source.start(0, playStartTime, playDuration);
725
+ }
726
 
727
  // ループ設定
 
728
  if (loop) {
729
+ source.loop = true;
730
+ source.loopStart = parseFloat(startTimeInput.value) || 0;
731
  source.loopEnd = endTime;
732
  }
733
 
734
+ // 再生速度を同期
735
  source.playbackRate.value = video.playbackRate;
736
 
737
  audioSources[file] = source;
 
739
 
740
  // 再生関数
741
  function playMedia() {
742
+ const startTime = video.currentTime;
743
+ const endTime = parseFloat(endTimeInput.value) || videoDuration;
 
744
 
745
  // 終了時間が動画の長さを超えないように
746
+ const actualEndTime = Math.min(endTime, videoDuration);
 
 
 
 
747
 
748
+ // 現在位置が終了時間を超えている場合、開始位置に戻る
749
+ if (startTime >= actualEndTime) {
750
+ video.currentTime = parseFloat(startTimeInput.value) || 0;
751
+ }
 
 
 
 
 
 
752
 
753
  // 動画を再生
754
  video.play();
755
  isPlaying = true;
756
  isVideoPlaying = true;
757
  playPauseBtn.textContent = '⏸';
758
+
759
+ // 音声を再生
760
+ audioFiles.forEach(file => {
761
+ if (audioBuffers[file]) {
762
+ playAudio(file, video.currentTime);
763
+ }
764
+ });
765
  }
766
 
767
  // 一時停止関数
 
771
  video.pause();
772
  audioFiles.forEach(file => {
773
  if (audioSources[file]) {
774
+ try {
775
+ audioSources[file].stop();
776
+ } catch(e) {
777
+ console.log("Audio source already stopped");
778
+ }
779
  audioSources[file] = null;
780
  }
781
  });
 
783
  isPlaying = false;
784
  isVideoPlaying = false;
785
  playPauseBtn.textContent = '▶';
 
 
 
 
 
 
 
 
 
786
  }
787
 
788
  // ボリュームスライダーのイベント
 
814
  }
815
  });
816
 
817
+ // ループ設定変更時
818
+ loopCheckbox.addEventListener('change', function() {
819
+ if (isPlaying) {
820
+ // 再生中の場合は音声を再起動
821
+ const currentTime = video.currentTime;
822
+ audioFiles.forEach(file => {
823
+ if (audioSources[file]) {
824
+ try {
825
+ audioSources[file].stop();
826
+ } catch(e) {
827
+ console.log("Audio source already stopped");
828
+ }
829
+ playAudio(file, currentTime);
830
+ }
831
+ });
832
+ }
833
+ });
834
+
835
  // 初期化
836
  loadAudioFiles();
837
  updateVolumeIcon();