Spaces:
Running
Running
File size: 4,924 Bytes
6d8f1ee 97b8703 6d8f1ee 97b8703 6d8f1ee e26a936 03da20b e26a936 6d8f1ee e26a936 447911d e26a936 447911d 97b8703 5d4dad4 97b8703 87447a0 97b8703 87447a0 98dca72 16f24ff c730992 87447a0 c730992 97b8703 87447a0 c730992 97b8703 9746ca6 e26a936 5fa2df8 e26a936 447911d 13afb0d 447911d 16f24ff 447911d 5d4dad4 e26a936 5fa2df8 e26a936 447911d 5d4dad4 447911d 5d4dad4 447911d 06dfdc7 97b8703 447911d 16f24ff e26a936 447911d 87447a0 97b8703 447911d 6d8f1ee 87447a0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>動画プレイヤー</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: #f0f0f0;
font-family: sans-serif;
padding: 20px;
}
video {
max-width: 100%;
height: auto;
margin-bottom: 10px;
}
.controls {
display: flex;
flex-direction: column;
gap: 15px;
width: 100%;
max-width: 500px;
}
.control-group {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
input[type="range"] {
flex: 1;
}
input[type="number"] {
width: 60px;
}
#audioWarning {
color: red;
display: none;
}
</style>
</head>
<body>
<h1>動画プレイヤー</h1>
<video id="videoPlayer" src="v.mp4" controls></video>
<p id="audioWarning">音量増幅機能を使用するには、動画を再生してください</p>
<div class="controls">
<div class="control-group">
<label for="speedRange">再生速度:</label>
<input type="range" id="speedRange" min="0.0001" max="5" step="0.0001" value="1">
<input type="number" id="speedInput" min="0.0001" step="0.0001" value="1">
</div>
<div class="control-group">
<label for="volumeRange">音量:</label>
<input type="range" id="volumeRange" min="0" max="1000" step="1" value="100">
<input type="number" id="volumeInput" min="0" max="1000" step="1" value="100">%
</div>
<div class="control-group">
<label for="loopCheckbox">ループ再生:</label>
<input type="checkbox" id="loopCheckbox" checked>
</div>
<button onclick="goFullscreen()">全画面</button>
</div>
<script>
const video = document.getElementById('videoPlayer');
const speedRange = document.getElementById('speedRange');
const speedInput = document.getElementById('speedInput');
const volumeRange = document.getElementById('volumeRange');
const volumeInput = document.getElementById('volumeInput');
const loopCheckbox = document.getElementById('loopCheckbox');
const audioWarning = document.getElementById('audioWarning');
// Web Audio APIの変数
let audioContext = null;
let source = null;
let gainNode = null;
let audioInitialized = false;
function setupAudio() {
try {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
source = audioContext.createMediaElementSource(video);
gainNode = audioContext.createGain();
source.connect(gainNode);
gainNode.connect(audioContext.destination);
updateVolume(volumeRange.value);
audioInitialized = true;
audioWarning.style.display = 'none';
} catch (e) {
console.error("AudioContextの初期化に失敗しました:", e);
audioWarning.textContent = "音量増幅機能が使用できません: " + e.message;
audioWarning.style.display = 'block';
}
}
function updatePlaybackRate(value) {
const speed = parseFloat(value);
speedInput.value = speed;
speedRange.value = speed;
video.playbackRate = speed;
}
function updateVolume(value) {
const volume = parseFloat(value);
volumeInput.value = volume;
volumeRange.value = volume;
if (audioInitialized && gainNode) {
gainNode.gain.value = volume / 100;
} else {
// Web Audio APIが初期化される前は通常の音量制御を使用
video.volume = Math.min(volume / 100, 1);
}
}
// イベントリスナーの設定
['input', 'change', 'mouseup'].forEach(eventName => {
speedRange.addEventListener(eventName, () => {
updatePlaybackRate(speedRange.value);
});
volumeRange.addEventListener(eventName, () => {
updateVolume(volumeRange.value);
});
});
speedInput.addEventListener('input', () => {
updatePlaybackRate(speedInput.value);
});
volumeInput.addEventListener('input', () => {
updateVolume(volumeInput.value);
});
loopCheckbox.addEventListener('change', () => {
video.loop = loopCheckbox.checked;
});
function goFullscreen() {
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen();
} else if (video.msRequestFullscreen) {
video.msRequestFullscreen();
}
}
// 動画再生時にAudioContextを開始(重要!)
video.addEventListener('play', () => {
if (audioContext.state === 'suspended') {
audioContext.resume();
}
});
video.addEventListener('loadedmetadata', () => {
updatePlaybackRate(speedRange.value);
updateVolume(volumeRange.value);
video.loop = loopCheckbox.checked;
});
// ページ読み込み時に警告を表示
audioWarning.style.display = 'block';
</script>
</body>
</html> |