Spaces:
Running
Running
Update index.html
Browse files- index.html +55 -13
index.html
CHANGED
@@ -633,6 +633,13 @@
|
|
633 |
const frameTime = document.getElementById('frameTime');
|
634 |
const contextMenu = document.getElementById('contextMenu');
|
635 |
const audioOnlyModeIndicator = document.getElementById('audioOnlyModeIndicator');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
636 |
|
637 |
// 初期設定
|
638 |
video.controls = false;
|
@@ -688,9 +695,10 @@
|
|
688 |
}
|
689 |
}
|
690 |
|
|
|
691 |
function handleVideoChange() {
|
692 |
const selected = videoSelect.value;
|
693 |
-
|
694 |
if (selected === 'v-2.mp4') {
|
695 |
const confirmPlay = confirm("この動画は音量が大きいです。あらかじめ、デバイスの音量をある程度下げてください。また、音割れが起きます。再生してもよろしいですか?");
|
696 |
if (!confirmPlay) {
|
@@ -698,20 +706,14 @@
|
|
698 |
return;
|
699 |
}
|
700 |
}
|
701 |
-
|
702 |
video.src = selected;
|
|
|
703 |
video.load();
|
|
|
704 |
video.play().then(() => {
|
705 |
playPauseBtn.textContent = '⏸';
|
706 |
}).catch(e => console.log(e));
|
707 |
-
|
708 |
-
// 新しい動画のBlobをキャッシュ
|
709 |
-
fetch(selected)
|
710 |
-
.then(response => response.blob())
|
711 |
-
.then(blob => {
|
712 |
-
videoBlob = blob;
|
713 |
-
frameCache = {}; // キャッシュをクリア
|
714 |
-
});
|
715 |
}
|
716 |
|
717 |
function togglePlayPause() {
|
@@ -946,14 +948,54 @@
|
|
946 |
progressContainer.addEventListener('click', setProgress);
|
947 |
progressContainer.addEventListener('mousedown', () => isDragging = true);
|
948 |
document.addEventListener('mouseup', () => isDragging = false);
|
949 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
950 |
if (isDragging) {
|
951 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
952 |
} else {
|
953 |
-
|
954 |
}
|
955 |
});
|
956 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
957 |
// プログレスバーのホバーイベント
|
958 |
progressContainer.addEventListener('mouseenter', () => {
|
959 |
isHoveringProgress = true;
|
|
|
633 |
const frameTime = document.getElementById('frameTime');
|
634 |
const contextMenu = document.getElementById('contextMenu');
|
635 |
const audioOnlyModeIndicator = document.getElementById('audioOnlyModeIndicator');
|
636 |
+
const contextMenu = document.getElementById('contextMenu');
|
637 |
+
const previewContainer = document.getElementById('previewContainer');
|
638 |
+
const preview = document.getElementById('preview');
|
639 |
+
const previewTime = document.getElementById('previewTime');
|
640 |
+
const VideoForThumbnail = document.getElementById('video-for-thumbnail');
|
641 |
+
const canvas = document.getElementById('canvas');
|
642 |
+
const ctx = canvas.getContext('2d');
|
643 |
|
644 |
// 初期設定
|
645 |
video.controls = false;
|
|
|
695 |
}
|
696 |
}
|
697 |
|
698 |
+
// 動画ソース変更時にサムネイル用動画も更新
|
699 |
function handleVideoChange() {
|
700 |
const selected = videoSelect.value;
|
701 |
+
|
702 |
if (selected === 'v-2.mp4') {
|
703 |
const confirmPlay = confirm("この動画は音量が大きいです。あらかじめ、デバイスの音量をある程度下げてください。また、音割れが起きます。再生してもよろしいですか?");
|
704 |
if (!confirmPlay) {
|
|
|
706 |
return;
|
707 |
}
|
708 |
}
|
709 |
+
|
710 |
video.src = selected;
|
711 |
+
VideoForThumbnail.src = selected;
|
712 |
video.load();
|
713 |
+
VideoForThumbnail.load();
|
714 |
video.play().then(() => {
|
715 |
playPauseBtn.textContent = '⏸';
|
716 |
}).catch(e => console.log(e));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
717 |
}
|
718 |
|
719 |
function togglePlayPause() {
|
|
|
948 |
progressContainer.addEventListener('click', setProgress);
|
949 |
progressContainer.addEventListener('mousedown', () => isDragging = true);
|
950 |
document.addEventListener('mouseup', () => isDragging = false);
|
951 |
+
// 音声/字幕のみモード
|
952 |
+
function toggleAudioOnlyMode() {
|
953 |
+
document.body.classList.toggle('audio-only-mode');
|
954 |
+
contextMenu.style.display = 'none';
|
955 |
+
}
|
956 |
+
|
957 |
+
// マウスホバー時のプレビュー表示
|
958 |
+
progressContainer.addEventListener('mousemove', function(e) {
|
959 |
if (isDragging) {
|
960 |
+
const width = progressContainer.clientWidth;
|
961 |
+
const clickX = e.offsetX;
|
962 |
+
const duration = video.duration;
|
963 |
+
const previewTime = (clickX / width) * duration;
|
964 |
+
|
965 |
+
// プレビュー位置を更新
|
966 |
+
previewContainer.style.left = `${e.clientX - 100}px`;
|
967 |
+
previewContainer.style.bottom = '60px';
|
968 |
+
previewContainer.style.display = 'block';
|
969 |
+
|
970 |
+
// 時間表示を更新
|
971 |
+
const minutes = Math.floor(previewTime / 60);
|
972 |
+
const seconds = Math.floor(previewTime % 60).toString().padStart(2, '0');
|
973 |
+
document.getElementById('previewTime').textContent = `${minutes}:${seconds}`;
|
974 |
+
|
975 |
+
// サムネイル画像を更新
|
976 |
+
updateThumbnail(previewTime);
|
977 |
} else {
|
978 |
+
previewContainer.style.display = 'none';
|
979 |
}
|
980 |
});
|
981 |
|
982 |
+
progressContainer.addEventListener('mouseleave', function() {
|
983 |
+
previewContainer.style.display = 'none';
|
984 |
+
});
|
985 |
+
|
986 |
+
// サムネイル画像更新関数
|
987 |
+
function updateThumbnail(time) {
|
988 |
+
VideoForThumbnail.currentTime = time;
|
989 |
+
|
990 |
+
VideoForThumbnail.addEventListener('seeked', function() {
|
991 |
+
canvas.width = VideoForThumbnail.videoWidth;
|
992 |
+
canvas.height = VideoForThumbnail.videoHeight;
|
993 |
+
ctx.drawImage(VideoForThumbnail, 0, 0, canvas.width, canvas.height);
|
994 |
+
preview.src = canvas.toDataURL('image/jpeg');
|
995 |
+
}, { once: true });
|
996 |
+
}
|
997 |
+
|
998 |
+
|
999 |
// プログレスバーのホバーイベント
|
1000 |
progressContainer.addEventListener('mouseenter', () => {
|
1001 |
isHoveringProgress = true;
|