Spaces:
Running
Running
<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'); | |
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) { | |
const msg = "音量増幅機能が使用できません: " + e.message; | |
audioWarning.textContent = msg; | |
audioWarning.style.display = 'block'; | |
alert(msg); | |
} | |
} | |
function updatePlaybackRate(value) { | |
const speed = parseFloat(value); | |
if (isNaN(speed) || speed <= 0) { | |
const msg = "再生速度が不正です: " + value; | |
alert(msg); | |
return; | |
} | |
speedInput.value = speed; | |
speedRange.value = speed; | |
video.playbackRate = speed; | |
} | |
function updateVolume(value) { | |
const volume = parseFloat(value); | |
if (isNaN(volume) || volume < 0) { | |
const msg = "音量の値が不正です: " + value; | |
alert(msg); | |
return; | |
} | |
volumeInput.value = volume; | |
volumeRange.value = volume; | |
if (audioInitialized && gainNode) { | |
try { | |
gainNode.gain.value = volume / 100; | |
} catch (e) { | |
const msg = "音量設定中にエラーが発生しました: " + e.message; | |
alert(msg); | |
} | |
} else { | |
try { | |
video.volume = Math.min(volume / 100, 1); | |
} catch (e) { | |
const msg = "標準音量設定に失敗しました: " + e.message; | |
alert(msg); | |
} | |
} | |
} | |
['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() { | |
try { | |
if (video.requestFullscreen) { | |
video.requestFullscreen(); | |
} else if (video.webkitRequestFullscreen) { | |
video.webkitRequestFullscreen(); | |
} else if (video.msRequestFullscreen) { | |
video.msRequestFullscreen(); | |
} else { | |
alert("全画面表示はこのブラウザではサポートされていません。"); | |
} | |
} catch (e) { | |
alert("全画面モードに失敗しました: " + e.message); | |
} | |
} | |
video.addEventListener('play', () => { | |
if (!audioInitialized) { | |
setupAudio(); | |
} else if (audioContext && audioContext.state === 'suspended') { | |
audioContext.resume().catch(e => { | |
const msg = "AudioContextの再開に失敗しました: " + e.message; | |
alert(msg); | |
}); | |
} | |
}); | |
video.addEventListener('loadedmetadata', () => { | |
try { | |
updatePlaybackRate(speedRange.value); | |
updateVolume(volumeRange.value); | |
video.loop = loopCheckbox.checked; | |
} catch (e) { | |
alert("動画のメタデータ読み込み処理でエラーが発生しました: " + e.message); | |
} | |
}); | |
// 初期警告表示 | |
audioWarning.style.display = 'block'; | |
alert("音量増幅機能を使用するには、動画を再生してください"); | |
</script> | |