soiz1 commited on
Commit
60ca6fc
·
1 Parent(s): 7367d4c

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +302 -33
index.html CHANGED
@@ -46,13 +46,106 @@
46
  width: 100%;
47
  border-radius: 5px;
48
  background-color: #000;
 
49
  }
50
 
51
- .controls {
 
 
 
52
  display: flex;
53
  flex-direction: column;
54
- gap: 15px;
55
- margin-bottom: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
57
 
58
  .audio-controls {
@@ -73,7 +166,7 @@
73
  color: #64ffda;
74
  }
75
 
76
- input[type="range"] {
77
  flex-grow: 1;
78
  height: 8px;
79
  -webkit-appearance: none;
@@ -82,7 +175,7 @@
82
  outline: none;
83
  }
84
 
85
- input[type="range"]::-webkit-slider-thumb {
86
  -webkit-appearance: none;
87
  width: 18px;
88
  height: 18px;
@@ -121,22 +214,6 @@
121
  border-radius: 3px;
122
  }
123
 
124
- button {
125
- background-color: #0a192f;
126
- color: #64ffda;
127
- border: 1px solid #64ffda;
128
- padding: 10px 20px;
129
- border-radius: 5px;
130
- cursor: pointer;
131
- font-weight: bold;
132
- transition: all 0.3s;
133
- }
134
-
135
- button:hover {
136
- background-color: #64ffda;
137
- color: #0a192f;
138
- }
139
-
140
  .buttons {
141
  display: flex;
142
  gap: 10px;
@@ -149,6 +226,33 @@
149
  background: linear-gradient(90deg, transparent, #64ffda, transparent);
150
  margin: 20px 0;
151
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  </style>
153
  </head>
154
  <body>
@@ -159,6 +263,25 @@
159
  <video id="video" muted>
160
  <source src="v.mp4" type="video/mp4">
161
  </video>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  </div>
163
 
164
  <div class="tech-decoration"></div>
@@ -203,27 +326,27 @@
203
  <h2>音声コントロール</h2>
204
  <div class="audio-item">
205
  <label>p.mp3</label>
206
- <input type="range" class="volume-slider" data-audio="p" min="0" max="1" step="0.01" value="1">
207
  <span class="volume-value">1</span>
208
  </div>
209
  <div class="audio-item">
210
  <label>a.mp3</label>
211
- <input type="range" class="volume-slider" data-audio="a" min="0" max="1" step="0.01" value="1">
212
  <span class="volume-value">1</span>
213
  </div>
214
  <div class="audio-item">
215
  <label>t.mp3</label>
216
- <input type="range" class="volume-slider" data-audio="t" min="0" max="1" step="0.01" value="1">
217
  <span class="volume-value">1</span>
218
  </div>
219
  <div class="audio-item">
220
  <label>s.mp3</label>
221
- <input type="range" class="volume-slider" data-audio="s" min="0" max="1" step="0.01" value="1">
222
  <span class="volume-value">1</span>
223
  </div>
224
  <div class="audio-item">
225
  <label>k.mp3</label>
226
- <input type="range" class="volume-slider" data-audio="k" min="0" max="1" step="0.01" value="1">
227
  <span class="volume-value">1</span>
228
  </div>
229
  </div>
@@ -241,6 +364,15 @@
241
  document.addEventListener('DOMContentLoaded', function() {
242
  // 要素を取得
243
  const video = document.getElementById('video');
 
 
 
 
 
 
 
 
 
244
  const playBtn = document.getElementById('play-btn');
245
  const pauseBtn = document.getElementById('pause-btn');
246
  const stopBtn = document.getElementById('stop-btn');
@@ -250,7 +382,7 @@
250
  const playbackRateSelect = document.getElementById('playback-rate');
251
  const globalVolumeSlider = document.getElementById('global-volume');
252
  const globalVolumeValue = document.getElementById('global-volume-value');
253
- const volumeSliders = document.querySelectorAll('.volume-slider');
254
  const volumeValues = document.querySelectorAll('.volume-value');
255
 
256
  // 音声オブジェクトを作成
@@ -265,6 +397,8 @@
265
  // 初期化
266
  let videoDuration = 0;
267
  let isPlaying = false;
 
 
268
 
269
  // 動画のメタデータが読み込まれたら
270
  video.addEventListener('loadedmetadata', function() {
@@ -272,8 +406,25 @@
272
  endTimeInput.value = videoDuration.toFixed(1);
273
  endTimeInput.max = videoDuration;
274
  startTimeInput.max = videoDuration - 0.1;
 
275
  });
276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  // 音声ファイルを読み込む
278
  function loadAudioFiles() {
279
  audioFiles.forEach(file => {
@@ -319,7 +470,7 @@
319
  source.buffer = audioBuffers[file];
320
 
321
  // ボリュームスライダーの値を取得
322
- const volumeSlider = document.querySelector(`.volume-slider[data-audio="${file}"]`);
323
  const volume = parseFloat(volumeSlider.value) * globalVolume;
324
 
325
  // ゲインノードを設定
@@ -346,9 +497,12 @@
346
  // 動画を再生
347
  video.play();
348
  isPlaying = true;
 
349
 
350
  // 終了時間に達したら停止
351
  video.ontimeupdate = function() {
 
 
352
  if (video.currentTime >= endTime) {
353
  if (!loop) {
354
  stopMedia();
@@ -372,18 +526,128 @@
372
  });
373
 
374
  isPlaying = false;
 
375
  }
376
 
377
  // 停止関数
378
  function stopMedia() {
379
  pauseMedia();
380
  video.currentTime = parseFloat(startTimeInput.value) || 0;
 
381
  }
382
 
383
- // イベントリスナーを設定
384
- playBtn.addEventListener('click', playMedia);
385
- pauseBtn.addEventListener('click', pauseMedia);
386
- stopBtn.addEventListener('click', stopMedia);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
 
388
  // ボリュームスライダーのイベント
389
  volumeSliders.forEach((slider, index) => {
@@ -406,7 +670,7 @@
406
  if (isPlaying) {
407
  audioFiles.forEach(file => {
408
  if (gainNodes[file]) {
409
- const volumeSlider = document.querySelector(`.volume-slider[data-audio="${file}"]`);
410
  const volume = parseFloat(volumeSlider.value) * value;
411
  gainNodes[file].gain.value = volume;
412
  }
@@ -414,6 +678,11 @@
414
  }
415
  });
416
 
 
 
 
 
 
417
  // 初期化
418
  loadAudioFiles();
419
  });
 
46
  width: 100%;
47
  border-radius: 5px;
48
  background-color: #000;
49
+ display: block;
50
  }
51
 
52
+ .video-controls {
53
+ background-color: rgba(0, 0, 0, 0.7);
54
+ padding: 10px;
55
+ border-radius: 0 0 5px 5px;
56
  display: flex;
57
  flex-direction: column;
58
+ gap: 10px;
59
+ }
60
+
61
+ .progress-container {
62
+ width: 100%;
63
+ height: 10px;
64
+ background-color: #1e2a47;
65
+ border-radius: 5px;
66
+ cursor: pointer;
67
+ position: relative;
68
+ }
69
+
70
+ .progress-bar {
71
+ height: 100%;
72
+ background-color: #64ffda;
73
+ border-radius: 5px;
74
+ width: 0%;
75
+ position: relative;
76
+ }
77
+
78
+ .progress-time {
79
+ position: absolute;
80
+ top: -25px;
81
+ background-color: rgba(0, 0, 0, 0.8);
82
+ padding: 2px 5px;
83
+ border-radius: 3px;
84
+ font-size: 12px;
85
+ display: none;
86
+ }
87
+
88
+ .controls-row {
89
+ display: flex;
90
+ justify-content: space-between;
91
+ align-items: center;
92
+ }
93
+
94
+ .left-controls, .right-controls {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 10px;
98
+ }
99
+
100
+ .control-button {
101
+ background: none;
102
+ border: none;
103
+ color: #e6f1ff;
104
+ font-size: 16px;
105
+ cursor: pointer;
106
+ padding: 5px;
107
+ border-radius: 3px;
108
+ transition: all 0.2s;
109
+ }
110
+
111
+ .control-button:hover {
112
+ background-color: rgba(100, 255, 218, 0.2);
113
+ }
114
+
115
+ .time-display {
116
+ font-size: 14px;
117
+ color: #e6f1ff;
118
+ font-family: monospace;
119
+ }
120
+
121
+ .volume-control {
122
+ display: flex;
123
+ align-items: center;
124
+ gap: 5px;
125
+ }
126
+
127
+ .volume-slider {
128
+ width: 80px;
129
+ height: 5px;
130
+ -webkit-appearance: none;
131
+ background: #1e2a47;
132
+ border-radius: 5px;
133
+ outline: none;
134
+ opacity: 0;
135
+ transition: opacity 0.2s;
136
+ }
137
+
138
+ .volume-control:hover .volume-slider {
139
+ opacity: 1;
140
+ }
141
+
142
+ .volume-slider::-webkit-slider-thumb {
143
+ -webkit-appearance: none;
144
+ width: 12px;
145
+ height: 12px;
146
+ background: #64ffda;
147
+ border-radius: 50%;
148
+ cursor: pointer;
149
  }
150
 
151
  .audio-controls {
 
166
  color: #64ffda;
167
  }
168
 
169
+ .audio-volume-slider {
170
  flex-grow: 1;
171
  height: 8px;
172
  -webkit-appearance: none;
 
175
  outline: none;
176
  }
177
 
178
+ .audio-volume-slider::-webkit-slider-thumb {
179
  -webkit-appearance: none;
180
  width: 18px;
181
  height: 18px;
 
214
  border-radius: 3px;
215
  }
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  .buttons {
218
  display: flex;
219
  gap: 10px;
 
226
  background: linear-gradient(90deg, transparent, #64ffda, transparent);
227
  margin: 20px 0;
228
  }
229
+
230
+ .fullscreen {
231
+ position: fixed;
232
+ top: 0;
233
+ left: 0;
234
+ width: 100%;
235
+ height: 100%;
236
+ background-color: black;
237
+ z-index: 1000;
238
+ display: flex;
239
+ justify-content: center;
240
+ align-items: center;
241
+ }
242
+
243
+ .fullscreen video {
244
+ width: 100%;
245
+ height: 100%;
246
+ max-width: 100%;
247
+ max-height: 100%;
248
+ }
249
+
250
+ .fullscreen .video-container {
251
+ width: 100%;
252
+ height: 100%;
253
+ max-width: 100%;
254
+ max-height: 100%;
255
+ }
256
  </style>
257
  </head>
258
  <body>
 
263
  <video id="video" muted>
264
  <source src="v.mp4" type="video/mp4">
265
  </video>
266
+ <div class="video-controls">
267
+ <div class="progress-container" id="progress-container">
268
+ <div class="progress-bar" id="progress-bar"></div>
269
+ <div class="progress-time" id="progress-time">00:00</div>
270
+ </div>
271
+ <div class="controls-row">
272
+ <div class="left-controls">
273
+ <button class="control-button" id="play-pause-btn">▶</button>
274
+ <span class="time-display" id="time-display">00:00 / 00:00</span>
275
+ </div>
276
+ <div class="right-controls">
277
+ <div class="volume-control">
278
+ <button class="control-button" id="volume-btn">🔊</button>
279
+ <input type="range" class="volume-slider" id="video-volume" min="0" max="1" step="0.01" value="1">
280
+ </div>
281
+ <button class="control-button" id="fullscreen-btn">⛶</button>
282
+ </div>
283
+ </div>
284
+ </div>
285
  </div>
286
 
287
  <div class="tech-decoration"></div>
 
326
  <h2>音声コントロール</h2>
327
  <div class="audio-item">
328
  <label>p.mp3</label>
329
+ <input type="range" class="audio-volume-slider" data-audio="p" min="0" max="1" step="0.01" value="1">
330
  <span class="volume-value">1</span>
331
  </div>
332
  <div class="audio-item">
333
  <label>a.mp3</label>
334
+ <input type="range" class="audio-volume-slider" data-audio="a" min="0" max="1" step="0.01" value="1">
335
  <span class="volume-value">1</span>
336
  </div>
337
  <div class="audio-item">
338
  <label>t.mp3</label>
339
+ <input type="range" class="audio-volume-slider" data-audio="t" min="0" max="1" step="0.01" value="1">
340
  <span class="volume-value">1</span>
341
  </div>
342
  <div class="audio-item">
343
  <label>s.mp3</label>
344
+ <input type="range" class="audio-volume-slider" data-audio="s" min="0" max="1" step="0.01" value="1">
345
  <span class="volume-value">1</span>
346
  </div>
347
  <div class="audio-item">
348
  <label>k.mp3</label>
349
+ <input type="range" class="audio-volume-slider" data-audio="k" min="0" max="1" step="0.01" value="1">
350
  <span class="volume-value">1</span>
351
  </div>
352
  </div>
 
364
  document.addEventListener('DOMContentLoaded', function() {
365
  // 要素を取得
366
  const video = document.getElementById('video');
367
+ const playPauseBtn = document.getElementById('play-pause-btn');
368
+ const fullscreenBtn = document.getElementById('fullscreen-btn');
369
+ const progressContainer = document.getElementById('progress-container');
370
+ const progressBar = document.getElementById('progress-bar');
371
+ const progressTime = document.getElementById('progress-time');
372
+ const timeDisplay = document.getElementById('time-display');
373
+ const volumeBtn = document.getElementById('volume-btn');
374
+ const videoVolumeSlider = document.getElementById('video-volume');
375
+
376
  const playBtn = document.getElementById('play-btn');
377
  const pauseBtn = document.getElementById('pause-btn');
378
  const stopBtn = document.getElementById('stop-btn');
 
382
  const playbackRateSelect = document.getElementById('playback-rate');
383
  const globalVolumeSlider = document.getElementById('global-volume');
384
  const globalVolumeValue = document.getElementById('global-volume-value');
385
+ const volumeSliders = document.querySelectorAll('.audio-volume-slider');
386
  const volumeValues = document.querySelectorAll('.volume-value');
387
 
388
  // 音声オブジェクトを作成
 
397
  // 初期化
398
  let videoDuration = 0;
399
  let isPlaying = false;
400
+ let isFullscreen = false;
401
+ let lastVolume = 1;
402
 
403
  // 動画のメタデータが読み込まれたら
404
  video.addEventListener('loadedmetadata', function() {
 
406
  endTimeInput.value = videoDuration.toFixed(1);
407
  endTimeInput.max = videoDuration;
408
  startTimeInput.max = videoDuration - 0.1;
409
+ updateTimeDisplay();
410
  });
411
 
412
+ // 時間表示を更新
413
+ function updateTimeDisplay() {
414
+ const currentTime = video.currentTime;
415
+ const duration = video.duration;
416
+
417
+ timeDisplay.textContent = `${formatTime(currentTime)} / ${formatTime(duration)}`;
418
+ progressBar.style.width = `${(currentTime / duration) * 100}%`;
419
+ }
420
+
421
+ // 時間をフォーマット (00:00形式)
422
+ function formatTime(seconds) {
423
+ const mins = Math.floor(seconds / 60);
424
+ const secs = Math.floor(seconds % 60);
425
+ return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
426
+ }
427
+
428
  // 音声ファイルを読み込む
429
  function loadAudioFiles() {
430
  audioFiles.forEach(file => {
 
470
  source.buffer = audioBuffers[file];
471
 
472
  // ボリュームスライダーの値を取得
473
+ const volumeSlider = document.querySelector(`.audio-volume-slider[data-audio="${file}"]`);
474
  const volume = parseFloat(volumeSlider.value) * globalVolume;
475
 
476
  // ゲインノードを設定
 
497
  // 動画を再生
498
  video.play();
499
  isPlaying = true;
500
+ playPauseBtn.textContent = '⏸';
501
 
502
  // 終了時間に達したら停止
503
  video.ontimeupdate = function() {
504
+ updateTimeDisplay();
505
+
506
  if (video.currentTime >= endTime) {
507
  if (!loop) {
508
  stopMedia();
 
526
  });
527
 
528
  isPlaying = false;
529
+ playPauseBtn.textContent = '▶';
530
  }
531
 
532
  // 停止関数
533
  function stopMedia() {
534
  pauseMedia();
535
  video.currentTime = parseFloat(startTimeInput.value) || 0;
536
+ updateTimeDisplay();
537
  }
538
 
539
+ // 再生/一時停止ボタンの切り替え
540
+ playPauseBtn.addEventListener('click', function() {
541
+ if (isPlaying) {
542
+ pauseMedia();
543
+ } else {
544
+ playMedia();
545
+ }
546
+ });
547
+
548
+ // プログレスバークリックでシーク
549
+ progressContainer.addEventListener('click', function(e) {
550
+ if (!videoDuration) return;
551
+
552
+ const rect = this.getBoundingClientRect();
553
+ const pos = (e.clientX - rect.left) / rect.width;
554
+ const seekTime = pos * videoDuration;
555
+
556
+ video.currentTime = seekTime;
557
+
558
+ if (!isPlaying) {
559
+ updateTimeDisplay();
560
+ }
561
+ });
562
+
563
+ // プログレスバー上でマウス移動時に時間を表示
564
+ progressContainer.addEventListener('mousemove', function(e) {
565
+ if (!videoDuration) return;
566
+
567
+ const rect = this.getBoundingClientRect();
568
+ const pos = (e.clientX - rect.left) / rect.width;
569
+ const seekTime = pos * videoDuration;
570
+
571
+ progressTime.textContent = formatTime(seekTime);
572
+ progressTime.style.left = `${e.clientX - rect.left}px`;
573
+ progressTime.style.display = 'block';
574
+ });
575
+
576
+ progressContainer.addEventListener('mouseout', function() {
577
+ progressTime.style.display = 'none';
578
+ });
579
+
580
+ // ボリュームコントロール
581
+ volumeBtn.addEventListener('click', function() {
582
+ if (video.volume > 0) {
583
+ lastVolume = video.volume;
584
+ video.volume = 0;
585
+ videoVolumeSlider.value = 0;
586
+ volumeBtn.textContent = '🔇';
587
+ } else {
588
+ video.volume = lastVolume;
589
+ videoVolumeSlider.value = lastVolume;
590
+ volumeBtn.textContent = lastVolume > 0.5 ? '🔊' : '🔉';
591
+ }
592
+ });
593
+
594
+ videoVolumeSlider.addEventListener('input', function() {
595
+ const volume = parseFloat(this.value);
596
+ video.volume = volume;
597
+ lastVolume = volume;
598
+
599
+ if (volume === 0) {
600
+ volumeBtn.textContent = '🔇';
601
+ } else if (volume > 0.5) {
602
+ volumeBtn.textContent = '🔊';
603
+ } else {
604
+ volumeBtn.textContent = '🔉';
605
+ }
606
+ });
607
+
608
+ // フルスクリーン
609
+ fullscreenBtn.addEventListener('click', function() {
610
+ if (!isFullscreen) {
611
+ enterFullscreen();
612
+ } else {
613
+ exitFullscreen();
614
+ }
615
+ });
616
+
617
+ function enterFullscreen() {
618
+ const elem = video.parentElement;
619
+
620
+ if (elem.requestFullscreen) {
621
+ elem.requestFullscreen();
622
+ } else if (elem.webkitRequestFullscreen) {
623
+ elem.webkitRequestFullscreen();
624
+ } else if (elem.msRequestFullscreen) {
625
+ elem.msRequestFullscreen();
626
+ }
627
+
628
+ isFullscreen = true;
629
+ }
630
+
631
+ function exitFullscreen() {
632
+ if (document.exitFullscreen) {
633
+ document.exitFullscreen();
634
+ } else if (document.webkitExitFullscreen) {
635
+ document.webkitExitFullscreen();
636
+ } else if (document.msExitFullscreen) {
637
+ document.msExitFullscreen();
638
+ }
639
+
640
+ isFullscreen = false;
641
+ }
642
+
643
+ // フルスクリーン状態の変更を監視
644
+ document.addEventListener('fullscreenchange', handleFullscreenChange);
645
+ document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
646
+ document.addEventListener('msfullscreenchange', handleFullscreenChange);
647
+
648
+ function handleFullscreenChange() {
649
+ isFullscreen = !!(document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement);
650
+ }
651
 
652
  // ボリュームスライダーのイベント
653
  volumeSliders.forEach((slider, index) => {
 
670
  if (isPlaying) {
671
  audioFiles.forEach(file => {
672
  if (gainNodes[file]) {
673
+ const volumeSlider = document.querySelector(`.audio-volume-slider[data-audio="${file}"]`);
674
  const volume = parseFloat(volumeSlider.value) * value;
675
  gainNodes[file].gain.value = volume;
676
  }
 
678
  }
679
  });
680
 
681
+ // 再生ボタン
682
+ playBtn.addEventListener('click', playMedia);
683
+ pauseBtn.addEventListener('click', pauseMedia);
684
+ stopBtn.addEventListener('click', stopMedia);
685
+
686
  // 初期化
687
  loadAudioFiles();
688
  });