soiz1 commited on
Commit
cee2a0c
·
verified ·
1 Parent(s): eb2d501

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +125 -2
index.html CHANGED
@@ -26,7 +26,7 @@
26
  .video-container {
27
  position: relative;
28
  max-width: 800px;
29
- margin-bottom: 20px;
30
  border: 2px solid #0066ff;
31
  box-shadow: 0 0 15px rgba(0, 102, 255, 0.5);
32
  background: #000;
@@ -37,6 +37,30 @@
37
  display: block;
38
  }
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  /* カスタム動画コントロール */
41
  video::-webkit-media-controls {
42
  display: none !important;
@@ -53,6 +77,7 @@
53
  flex-direction: column;
54
  opacity: 0;
55
  transition: opacity 0.3s;
 
56
  }
57
 
58
  .video-container:hover .custom-controls {
@@ -270,6 +295,11 @@
270
  <input type="number" id="volumeInput" min="0" max="1" step="0.01" value="1">
271
  </div>
272
 
 
 
 
 
 
273
  <div class="control-group">
274
  <label for="loopCheckbox">ループ再生:</label>
275
  <input type="checkbox" id="loopCheckbox" checked>
@@ -279,7 +309,12 @@
279
  </div>
280
 
281
  <div class="video-container">
282
- <video id="videoPlayer" src="v.mp4"></video>
 
 
 
 
 
283
  <div class="custom-controls">
284
  <div class="progress-container" id="progressContainer">
285
  <div class="progress-bar" id="progressBar"></div>
@@ -308,6 +343,7 @@
308
  const volumeRange = document.getElementById('volumeRange');
309
  const volumeInput = document.getElementById('volumeInput');
310
  const loopCheckbox = document.getElementById('loopCheckbox');
 
311
  const playPauseBtn = document.getElementById('playPauseBtn');
312
  const progressBar = document.getElementById('progressBar');
313
  const progressContainer = document.getElementById('progressContainer');
@@ -315,10 +351,84 @@
315
  const volumeBtn = document.getElementById('volumeBtn');
316
  const volumeSlider = document.getElementById('volumeSlider');
317
  const fullscreenBtn = document.getElementById('fullscreenBtn');
 
 
 
318
 
319
  // 初期設定
320
  video.controls = false;
321
  let isDragging = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
323
  function updatePlaybackRate(value) {
324
  const speed = parseFloat(value);
@@ -383,6 +493,9 @@
383
  const durationSeconds = Math.floor(video.duration % 60).toString().padStart(2, '0');
384
 
385
  timeDisplay.textContent = `${currentMinutes}:${currentSeconds} / ${durationMinutes}:${durationSeconds}`;
 
 
 
386
  }
387
 
388
  function setProgress(e) {
@@ -407,6 +520,13 @@
407
  updateVolume(volumeSlider.value);
408
  }
409
 
 
 
 
 
 
 
 
410
  function goFullscreen() {
411
  const container = document.querySelector('.video-container');
412
  if (container.requestFullscreen) {
@@ -433,6 +553,8 @@
433
  video.loop = loopCheckbox.checked;
434
  });
435
 
 
 
436
  playPauseBtn.addEventListener('click', togglePlayPause);
437
  video.addEventListener('click', togglePlayPause);
438
  video.addEventListener('play', () => playPauseBtn.textContent = '⏸');
@@ -451,6 +573,7 @@
451
  updateVolume(volumeRange.value);
452
  video.loop = loopCheckbox.checked;
453
  updateProgress();
 
454
  });
455
  </script>
456
  </body>
 
26
  .video-container {
27
  position: relative;
28
  max-width: 800px;
29
+ margin: 30px 0 20px 0;
30
  border: 2px solid #0066ff;
31
  box-shadow: 0 0 15px rgba(0, 102, 255, 0.5);
32
  background: #000;
 
37
  display: block;
38
  }
39
 
40
+ /* 字幕スタイル */
41
+ .caption-container {
42
+ position: absolute;
43
+ bottom: 60px;
44
+ left: 0;
45
+ right: 0;
46
+ text-align: center;
47
+ padding: 10px;
48
+ z-index: 10;
49
+ }
50
+
51
+ .caption-text {
52
+ display: inline-block;
53
+ background-color: rgba(0, 0, 0, 0.7);
54
+ color: #00ffcc;
55
+ font-family: 'Courier New', monospace;
56
+ font-size: 18px;
57
+ padding: 8px 15px;
58
+ border-radius: 4px;
59
+ border: 1px solid #0066ff;
60
+ text-shadow: 0 0 5px #0066ff;
61
+ max-width: 80%;
62
+ }
63
+
64
  /* カスタム動画コントロール */
65
  video::-webkit-media-controls {
66
  display: none !important;
 
77
  flex-direction: column;
78
  opacity: 0;
79
  transition: opacity 0.3s;
80
+ z-index: 5;
81
  }
82
 
83
  .video-container:hover .custom-controls {
 
295
  <input type="number" id="volumeInput" min="0" max="1" step="0.01" value="1">
296
  </div>
297
 
298
+ <div class="control-group">
299
+ <label for="captionCheckbox">字幕表示:</label>
300
+ <input type="checkbox" id="captionCheckbox" checked>
301
+ </div>
302
+
303
  <div class="control-group">
304
  <label for="loopCheckbox">ループ再生:</label>
305
  <input type="checkbox" id="loopCheckbox" checked>
 
309
  </div>
310
 
311
  <div class="video-container">
312
+ <video id="videoPlayer" src="v.mp4">
313
+ <track id="captionTrack" kind="subtitles" src="v.vtt" srclang="ja" label="日本語" default>
314
+ </video>
315
+ <div class="caption-container" id="captionContainer">
316
+ <div class="caption-text" id="captionText"></div>
317
+ </div>
318
  <div class="custom-controls">
319
  <div class="progress-container" id="progressContainer">
320
  <div class="progress-bar" id="progressBar"></div>
 
343
  const volumeRange = document.getElementById('volumeRange');
344
  const volumeInput = document.getElementById('volumeInput');
345
  const loopCheckbox = document.getElementById('loopCheckbox');
346
+ const captionCheckbox = document.getElementById('captionCheckbox');
347
  const playPauseBtn = document.getElementById('playPauseBtn');
348
  const progressBar = document.getElementById('progressBar');
349
  const progressContainer = document.getElementById('progressContainer');
 
351
  const volumeBtn = document.getElementById('volumeBtn');
352
  const volumeSlider = document.getElementById('volumeSlider');
353
  const fullscreenBtn = document.getElementById('fullscreenBtn');
354
+ const captionContainer = document.getElementById('captionContainer');
355
+ const captionText = document.getElementById('captionText');
356
+ const captionTrack = document.getElementById('captionTrack');
357
 
358
  // 初期設定
359
  video.controls = false;
360
  let isDragging = false;
361
+ let captions = [];
362
+ let activeCaption = null;
363
+
364
+ // 字幕データを読み込む
365
+ function loadCaptions() {
366
+ fetch('v.vtt')
367
+ .then(response => response.text())
368
+ .then(data => {
369
+ const lines = data.split('\n');
370
+ captions = [];
371
+ let currentCaption = null;
372
+
373
+ for (let i = 0; i < lines.length; i++) {
374
+ const line = lines[i].trim();
375
+
376
+ if (line.includes('-->')) {
377
+ if (currentCaption) {
378
+ captions.push(currentCaption);
379
+ }
380
+ const times = line.split('-->');
381
+ currentCaption = {
382
+ start: parseTime(times[0].trim()),
383
+ end: parseTime(times[1].trim()),
384
+ text: ''
385
+ };
386
+ } else if (line && currentCaption && !line.startsWith('WEBVTT')) {
387
+ currentCaption.text += line + '\n';
388
+ }
389
+ }
390
+
391
+ if (currentCaption) {
392
+ captions.push(currentCaption);
393
+ }
394
+ })
395
+ .catch(error => console.error('字幕の読み込みに失敗しました:', error));
396
+ }
397
+
398
+ // 時間文字列を秒に変換
399
+ function parseTime(timeStr) {
400
+ const parts = timeStr.split(':');
401
+ if (parts.length === 3) {
402
+ return parseFloat(parts[0]) * 3600 +
403
+ parseFloat(parts[1]) * 60 +
404
+ parseFloat(parts[2]);
405
+ }
406
+ return parseFloat(timeStr);
407
+ }
408
+
409
+ // 現在の字幕を更新
410
+ function updateCaption() {
411
+ if (!captionCheckbox.checked) {
412
+ captionText.textContent = '';
413
+ activeCaption = null;
414
+ return;
415
+ }
416
+
417
+ const currentTime = video.currentTime;
418
+ let newCaption = null;
419
+
420
+ for (const caption of captions) {
421
+ if (currentTime >= caption.start && currentTime <= caption.end) {
422
+ newCaption = caption;
423
+ break;
424
+ }
425
+ }
426
+
427
+ if (newCaption !== activeCaption) {
428
+ activeCaption = newCaption;
429
+ captionText.textContent = newCaption ? newCaption.text.trim() : '';
430
+ }
431
+ }
432
 
433
  function updatePlaybackRate(value) {
434
  const speed = parseFloat(value);
 
493
  const durationSeconds = Math.floor(video.duration % 60).toString().padStart(2, '0');
494
 
495
  timeDisplay.textContent = `${currentMinutes}:${currentSeconds} / ${durationMinutes}:${durationSeconds}`;
496
+
497
+ // 字幕更新
498
+ updateCaption();
499
  }
500
 
501
  function setProgress(e) {
 
520
  updateVolume(volumeSlider.value);
521
  }
522
 
523
+ function toggleCaptions() {
524
+ captionContainer.style.display = captionCheckbox.checked ? 'block' : 'none';
525
+ if (!captionCheckbox.checked) {
526
+ captionText.textContent = '';
527
+ }
528
+ }
529
+
530
  function goFullscreen() {
531
  const container = document.querySelector('.video-container');
532
  if (container.requestFullscreen) {
 
553
  video.loop = loopCheckbox.checked;
554
  });
555
 
556
+ captionCheckbox.addEventListener('change', toggleCaptions);
557
+
558
  playPauseBtn.addEventListener('click', togglePlayPause);
559
  video.addEventListener('click', togglePlayPause);
560
  video.addEventListener('play', () => playPauseBtn.textContent = '⏸');
 
573
  updateVolume(volumeRange.value);
574
  video.loop = loopCheckbox.checked;
575
  updateProgress();
576
+ loadCaptions();
577
  });
578
  </script>
579
  </body>