Spaces:
Running
Running
Update index.html
Browse files- index.html +123 -25
index.html
CHANGED
@@ -82,6 +82,7 @@
|
|
82 |
background: #001133;
|
83 |
margin-bottom: 10px;
|
84 |
cursor: pointer;
|
|
|
85 |
}
|
86 |
|
87 |
.progress-bar {
|
@@ -104,6 +105,20 @@
|
|
104 |
box-shadow: 0 0 5px #00ccff;
|
105 |
}
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
.buttons-container {
|
108 |
display: flex;
|
109 |
align-items: center;
|
@@ -415,6 +430,19 @@
|
|
415 |
transform: rotate(360deg);
|
416 |
}
|
417 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
</style>
|
419 |
</head>
|
420 |
|
@@ -573,7 +601,7 @@
|
|
573 |
</div>
|
574 |
<div class="control-group">
|
575 |
<label for="speedRange">再生速度:</label>
|
576 |
-
<input type="range" id="speedRange" min="0.0001" max="
|
577 |
<input type="number" id="speedInput" min="0.0001" step="0.0001" value="1">
|
578 |
</div>
|
579 |
<div class="control-group">
|
@@ -585,6 +613,10 @@
|
|
585 |
<label for="loopCheckbox">ループ再生:</label>
|
586 |
<input type="checkbox" id="loopCheckbox" checked>
|
587 |
</div>
|
|
|
|
|
|
|
|
|
588 |
<!-- 字幕設定セクション -->
|
589 |
<div class="subtitle-settings">
|
590 |
<div class="control-group">
|
@@ -615,6 +647,7 @@
|
|
615 |
<div class="progress-container" id="progressContainer">
|
616 |
<div class="progress-bar" id="progressBar">
|
617 |
</div>
|
|
|
618 |
</div>
|
619 |
<div class="buttons-container">
|
620 |
<div class="left-controls">
|
@@ -627,39 +660,67 @@
|
|
627 |
<input type="range" class="volume-slider" id="volumeSlider" min="0" max="1" step="0.01" value="1">
|
628 |
</div>
|
629 |
<button class="control-btn" id="subtitleBtn" title="字幕">🔤</button>
|
|
|
630 |
<button class="control-btn" id="fullscreenBtn">⛶</button>
|
631 |
</div>
|
632 |
</div>
|
633 |
</div>
|
634 |
</div>
|
635 |
<script>
|
636 |
-
|
637 |
const videoSelect = document.getElementById('videoSelect');
|
638 |
const speedRange = document.getElementById('speedRange');
|
639 |
const speedInput = document.getElementById('speedInput');
|
640 |
const volumeRange = document.getElementById('volumeRange');
|
641 |
const volumeInput = document.getElementById('volumeInput');
|
642 |
const loopCheckbox = document.getElementById('loopCheckbox');
|
|
|
643 |
const playPauseBtn = document.getElementById('playPauseBtn');
|
644 |
const progressBar = document.getElementById('progressBar');
|
645 |
const progressContainer = document.getElementById('progressContainer');
|
|
|
646 |
const timeDisplay = document.getElementById('timeDisplay');
|
647 |
const volumeBtn = document.getElementById('volumeBtn');
|
648 |
const volumeSlider = document.getElementById('volumeSlider');
|
649 |
const fullscreenBtn = document.getElementById('fullscreenBtn');
|
650 |
const subtitleBtn = document.getElementById('subtitleBtn');
|
|
|
651 |
const subtitleToggle = document.getElementById('subtitleToggle');
|
652 |
const subtitleSize = document.getElementById('subtitleSize');
|
653 |
const subtitleSizeInput = document.getElementById('subtitleSizeInput');
|
654 |
const subtitleTrack = document.getElementById('subtitleTrack');
|
655 |
const subtitleTrackElement = document.getElementById('subtitleTrackElement');
|
656 |
const videoContainer = document.querySelector('.video-container');
|
|
|
657 |
|
658 |
// 初期設定
|
659 |
video.controls = false;
|
660 |
let isDragging = false;
|
661 |
let subtitlesEnabled = true;
|
662 |
let normalVideoWidth = videoContainer.clientWidth;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
|
664 |
function updatePlaybackRate(value) {
|
665 |
const speed = parseFloat(value);
|
@@ -746,32 +807,62 @@
|
|
746 |
updateVolume(volumeSlider.value);
|
747 |
}
|
748 |
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
|
|
771 |
}
|
772 |
}
|
773 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
774 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
775 |
|
776 |
// 全画面変更時の字幕サイズ調整
|
777 |
function updateSubtitleScaleForFullscreen() {
|
@@ -847,6 +938,9 @@
|
|
847 |
video.loop = loopCheckbox.checked;
|
848 |
});
|
849 |
|
|
|
|
|
|
|
850 |
subtitleToggle.addEventListener('change', toggleSubtitles);
|
851 |
subtitleTrack.addEventListener('change', changeSubtitleTrack);
|
852 |
subtitleBtn.addEventListener('click', toggleSubtitleMenu);
|
@@ -885,6 +979,10 @@
|
|
885 |
document.documentElement.style.setProperty('--subtitle-scale', '1');
|
886 |
document.documentElement.style.setProperty('--subtitle-border-radius', '10px');
|
887 |
document.documentElement.style.setProperty('--fullscreen-scale', '1');
|
|
|
|
|
|
|
|
|
888 |
</script>
|
889 |
</body>
|
890 |
|
|
|
82 |
background: #001133;
|
83 |
margin-bottom: 10px;
|
84 |
cursor: pointer;
|
85 |
+
position: relative;
|
86 |
}
|
87 |
|
88 |
.progress-bar {
|
|
|
105 |
box-shadow: 0 0 5px #00ccff;
|
106 |
}
|
107 |
|
108 |
+
/* ホバー時の時間表示 */
|
109 |
+
.hover-time {
|
110 |
+
position: absolute;
|
111 |
+
top: -30px;
|
112 |
+
transform: translateX(-50%);
|
113 |
+
background: rgba(0, 20, 40, 0.8);
|
114 |
+
color: #00ccff;
|
115 |
+
padding: 3px 6px;
|
116 |
+
border-radius: 4px;
|
117 |
+
font-size: 12px;
|
118 |
+
pointer-events: none;
|
119 |
+
display: none;
|
120 |
+
}
|
121 |
+
|
122 |
.buttons-container {
|
123 |
display: flex;
|
124 |
align-items: center;
|
|
|
430 |
transform: rotate(360deg);
|
431 |
}
|
432 |
}
|
433 |
+
|
434 |
+
/* 動画非表示モード用スタイル */
|
435 |
+
.audio-only-mode video {
|
436 |
+
display: none;
|
437 |
+
}
|
438 |
+
.audio-only-mode .video-container {
|
439 |
+
background: transparent;
|
440 |
+
border: none;
|
441 |
+
box-shadow: none;
|
442 |
+
}
|
443 |
+
.audio-only-mode .controls {
|
444 |
+
margin-top: 0;
|
445 |
+
}
|
446 |
</style>
|
447 |
</head>
|
448 |
|
|
|
601 |
</div>
|
602 |
<div class="control-group">
|
603 |
<label for="speedRange">再生速度:</label>
|
604 |
+
<input type="range" id="speedRange" min="0.0001" max="10" step="0.0001" value="1" style="width:700px !important;">
|
605 |
<input type="number" id="speedInput" min="0.0001" step="0.0001" value="1">
|
606 |
</div>
|
607 |
<div class="control-group">
|
|
|
613 |
<label for="loopCheckbox">ループ再生:</label>
|
614 |
<input type="checkbox" id="loopCheckbox" checked>
|
615 |
</div>
|
616 |
+
<div class="control-group">
|
617 |
+
<label for="audioOnlyCheckbox">音声のみモード:</label>
|
618 |
+
<input type="checkbox" id="audioOnlyCheckbox">
|
619 |
+
</div>
|
620 |
<!-- 字幕設定セクション -->
|
621 |
<div class="subtitle-settings">
|
622 |
<div class="control-group">
|
|
|
647 |
<div class="progress-container" id="progressContainer">
|
648 |
<div class="progress-bar" id="progressBar">
|
649 |
</div>
|
650 |
+
<div class="hover-time" id="hoverTime"></div>
|
651 |
</div>
|
652 |
<div class="buttons-container">
|
653 |
<div class="left-controls">
|
|
|
660 |
<input type="range" class="volume-slider" id="volumeSlider" min="0" max="1" step="0.01" value="1">
|
661 |
</div>
|
662 |
<button class="control-btn" id="subtitleBtn" title="字幕">🔤</button>
|
663 |
+
<button class="control-btn" id="audioOnlyBtn" title="音声のみ">🎵</button>
|
664 |
<button class="control-btn" id="fullscreenBtn">⛶</button>
|
665 |
</div>
|
666 |
</div>
|
667 |
</div>
|
668 |
</div>
|
669 |
<script>
|
670 |
+
const video = document.getElementById('videoPlayer');
|
671 |
const videoSelect = document.getElementById('videoSelect');
|
672 |
const speedRange = document.getElementById('speedRange');
|
673 |
const speedInput = document.getElementById('speedInput');
|
674 |
const volumeRange = document.getElementById('volumeRange');
|
675 |
const volumeInput = document.getElementById('volumeInput');
|
676 |
const loopCheckbox = document.getElementById('loopCheckbox');
|
677 |
+
const audioOnlyCheckbox = document.getElementById('audioOnlyCheckbox');
|
678 |
const playPauseBtn = document.getElementById('playPauseBtn');
|
679 |
const progressBar = document.getElementById('progressBar');
|
680 |
const progressContainer = document.getElementById('progressContainer');
|
681 |
+
const hoverTime = document.getElementById('hoverTime');
|
682 |
const timeDisplay = document.getElementById('timeDisplay');
|
683 |
const volumeBtn = document.getElementById('volumeBtn');
|
684 |
const volumeSlider = document.getElementById('volumeSlider');
|
685 |
const fullscreenBtn = document.getElementById('fullscreenBtn');
|
686 |
const subtitleBtn = document.getElementById('subtitleBtn');
|
687 |
+
const audioOnlyBtn = document.getElementById('audioOnlyBtn');
|
688 |
const subtitleToggle = document.getElementById('subtitleToggle');
|
689 |
const subtitleSize = document.getElementById('subtitleSize');
|
690 |
const subtitleSizeInput = document.getElementById('subtitleSizeInput');
|
691 |
const subtitleTrack = document.getElementById('subtitleTrack');
|
692 |
const subtitleTrackElement = document.getElementById('subtitleTrackElement');
|
693 |
const videoContainer = document.querySelector('.video-container');
|
694 |
+
const controls = document.querySelector('.controls');
|
695 |
|
696 |
// 初期設定
|
697 |
video.controls = false;
|
698 |
let isDragging = false;
|
699 |
let subtitlesEnabled = true;
|
700 |
let normalVideoWidth = videoContainer.clientWidth;
|
701 |
+
let audioOnlyMode = false;
|
702 |
+
|
703 |
+
// ホバー時の時間表示
|
704 |
+
function setupHoverTime() {
|
705 |
+
progressContainer.addEventListener('mousemove', (e) => {
|
706 |
+
if (!video.duration) return;
|
707 |
+
|
708 |
+
const rect = progressContainer.getBoundingClientRect();
|
709 |
+
const pos = (e.clientX - rect.left) / rect.width;
|
710 |
+
const time = pos * video.duration;
|
711 |
+
|
712 |
+
hoverTime.style.display = 'block';
|
713 |
+
hoverTime.style.left = `${e.clientX - rect.left}px`;
|
714 |
+
|
715 |
+
const minutes = Math.floor(time / 60);
|
716 |
+
const seconds = Math.floor(time % 60).toString().padStart(2, '0');
|
717 |
+
hoverTime.textContent = `${minutes}:${seconds}`;
|
718 |
+
});
|
719 |
+
|
720 |
+
progressContainer.addEventListener('mouseleave', () => {
|
721 |
+
hoverTime.style.display = 'none';
|
722 |
+
});
|
723 |
+
}
|
724 |
|
725 |
function updatePlaybackRate(value) {
|
726 |
const speed = parseFloat(value);
|
|
|
807 |
updateVolume(volumeSlider.value);
|
808 |
}
|
809 |
|
810 |
+
function goFullscreen() {
|
811 |
+
if (
|
812 |
+
document.fullscreenElement ||
|
813 |
+
document.webkitFullscreenElement ||
|
814 |
+
document.msFullscreenElement
|
815 |
+
) {
|
816 |
+
// フルスクリーンを解除
|
817 |
+
if (document.exitFullscreen) {
|
818 |
+
document.exitFullscreen();
|
819 |
+
} else if (document.webkitExitFullscreen) {
|
820 |
+
document.webkitExitFullscreen();
|
821 |
+
} else if (document.msExitFullscreen) {
|
822 |
+
document.msExitFullscreen();
|
823 |
+
}
|
824 |
+
} else {
|
825 |
+
// フルスクリーンにする
|
826 |
+
if (videoContainer.requestFullscreen) {
|
827 |
+
videoContainer.requestFullscreen();
|
828 |
+
} else if (videoContainer.webkitRequestFullscreen) {
|
829 |
+
videoContainer.webkitRequestFullscreen();
|
830 |
+
} else if (videoContainer.msRequestFullscreen) {
|
831 |
+
videoContainer.msRequestFullscreen();
|
832 |
+
}
|
833 |
}
|
834 |
}
|
835 |
+
|
836 |
+
// 全画面時の右クリックメニュー
|
837 |
+
function setupFullscreenContextMenu() {
|
838 |
+
videoContainer.addEventListener('contextmenu', (e) => {
|
839 |
+
e.preventDefault();
|
840 |
+
|
841 |
+
// 全画面モードかどうかをチェック
|
842 |
+
const isFullscreen = document.fullscreenElement ||
|
843 |
+
document.webkitFullscreenElement ||
|
844 |
+
document.msFullscreenElement;
|
845 |
+
|
846 |
+
if (isFullscreen) {
|
847 |
+
// コントロールパネルを表示
|
848 |
+
controls.style.display = controls.style.display === 'none' ? 'flex' : 'none';
|
849 |
+
}
|
850 |
+
});
|
851 |
+
}
|
852 |
|
853 |
+
// 動画非表示モード
|
854 |
+
function toggleAudioOnlyMode() {
|
855 |
+
audioOnlyMode = !audioOnlyMode;
|
856 |
+
audioOnlyCheckbox.checked = audioOnlyMode;
|
857 |
+
|
858 |
+
if (audioOnlyMode) {
|
859 |
+
videoContainer.classList.add('audio-only-mode');
|
860 |
+
audioOnlyBtn.textContent = '🎬'; // 動画表示アイコンに変更
|
861 |
+
} else {
|
862 |
+
videoContainer.classList.remove('audio-only-mode');
|
863 |
+
audioOnlyBtn.textContent = '🎵'; // 音声のみアイコンに戻す
|
864 |
+
}
|
865 |
+
}
|
866 |
|
867 |
// 全画面変更時の字幕サイズ調整
|
868 |
function updateSubtitleScaleForFullscreen() {
|
|
|
938 |
video.loop = loopCheckbox.checked;
|
939 |
});
|
940 |
|
941 |
+
audioOnlyCheckbox.addEventListener('change', toggleAudioOnlyMode);
|
942 |
+
audioOnlyBtn.addEventListener('click', toggleAudioOnlyMode);
|
943 |
+
|
944 |
subtitleToggle.addEventListener('change', toggleSubtitles);
|
945 |
subtitleTrack.addEventListener('change', changeSubtitleTrack);
|
946 |
subtitleBtn.addEventListener('click', toggleSubtitleMenu);
|
|
|
979 |
document.documentElement.style.setProperty('--subtitle-scale', '1');
|
980 |
document.documentElement.style.setProperty('--subtitle-border-radius', '10px');
|
981 |
document.documentElement.style.setProperty('--fullscreen-scale', '1');
|
982 |
+
|
983 |
+
// 初期設定
|
984 |
+
setupHoverTime();
|
985 |
+
setupFullscreenContextMenu();
|
986 |
</script>
|
987 |
</body>
|
988 |
|