201 lines
4.5 KiB
JavaScript
201 lines
4.5 KiB
JavaScript
// dom refs
|
|
const video=document.getElementById("video")
|
|
const play=document.getElementById("play")
|
|
const mute=document.getElementById("mute")
|
|
const seek=document.getElementById("seek")
|
|
const volume=document.getElementById("volume")
|
|
const controls=document.getElementById("controls")
|
|
const player=document.getElementById("player")
|
|
const tapUnmute=document.getElementById("tapUnmute")
|
|
const rotate=document.getElementById("rotate")
|
|
|
|
// player state
|
|
let hideTimer,resizeTimer,lastSeek=-1
|
|
let controlsVisible=false
|
|
let autoplayStartedMuted=true
|
|
let rotated=false
|
|
|
|
// device check
|
|
const isMobile=matchMedia("(pointer:coarse)").matches||window.innerWidth<=768
|
|
controls.classList.add(isMobile?"mobile-mode":"desktop-mode")
|
|
|
|
// ui sync
|
|
const syncPlayState=()=>play.textContent=video.paused?"x":"▶"
|
|
const syncRotateState=()=>rotate.textContent=rotated?"⟲":"⟳"
|
|
|
|
function syncMuteState(){
|
|
mute.textContent=video.muted||video.volume===0?"u":"a"
|
|
volume.value=video.muted?0:video.volume
|
|
}
|
|
|
|
// controls
|
|
function showControls(){
|
|
if(!controlsVisible){
|
|
controls.classList.add("visible")
|
|
controlsVisible=true
|
|
}
|
|
clearTimeout(hideTimer)
|
|
hideTimer=setTimeout(()=>{
|
|
controls.classList.remove("visible")
|
|
controlsVisible=false
|
|
},isMobile?2200:1700)
|
|
}
|
|
|
|
// prompt
|
|
const showUnmutePrompt=show=>tapUnmute.classList.toggle("visible",!!show)
|
|
|
|
// layout
|
|
function applyVideoLayout(){
|
|
if(rotated){
|
|
video.style.objectFit="contain"
|
|
video.style.transform="translateZ(0) rotate(90deg) scale(1.15)"
|
|
return
|
|
}
|
|
|
|
const landscape=video.videoWidth&&video.videoHeight?video.videoWidth>video.videoHeight:true
|
|
const portraitScreen=window.innerHeight>window.innerWidth
|
|
|
|
video.style.objectFit=isMobile&&landscape&&portraitScreen?"contain":"cover"
|
|
video.style.transform="translateZ(0) scale(1.01)"
|
|
}
|
|
|
|
// rotate
|
|
function toggleRotate(){
|
|
rotated=!rotated
|
|
syncRotateState()
|
|
applyVideoLayout()
|
|
showControls()
|
|
}
|
|
|
|
// autoplay
|
|
async function startPlayback(){
|
|
video.volume=1
|
|
video.muted=true
|
|
|
|
try{
|
|
await video.play()
|
|
}catch(e){
|
|
console.error(e)
|
|
}
|
|
|
|
showUnmutePrompt(true)
|
|
syncPlayState()
|
|
syncMuteState()
|
|
syncRotateState()
|
|
}
|
|
|
|
// audio enable
|
|
function enableSoundAndPlay(){
|
|
video.muted=false
|
|
if(video.volume===0)video.volume=1
|
|
video.play().catch(()=>{})
|
|
autoplayStartedMuted=false
|
|
showUnmutePrompt(false)
|
|
syncMuteState()
|
|
syncPlayState()
|
|
}
|
|
|
|
// video events
|
|
video.addEventListener("play",()=>{syncPlayState();showControls()})
|
|
video.addEventListener("pause",()=>{syncPlayState();showControls()})
|
|
video.addEventListener("ended",()=>{syncPlayState();showControls()})
|
|
|
|
video.addEventListener("loadedmetadata",()=>{
|
|
applyVideoLayout()
|
|
|
|
requestIdleCallback?.(()=>{
|
|
const t=document.querySelector(".video-text")
|
|
if(t)t.textContent=""
|
|
})
|
|
|
|
syncMuteState()
|
|
syncPlayState()
|
|
})
|
|
|
|
video.addEventListener("timeupdate",()=>{
|
|
if(!video.duration)return
|
|
const value=((video.currentTime/video.duration)*100)|0
|
|
if(value===lastSeek)return
|
|
lastSeek=value
|
|
seek.value=value
|
|
})
|
|
|
|
// controls
|
|
play.addEventListener("click",async e=>{
|
|
e.stopPropagation()
|
|
if(video.paused){
|
|
try{await video.play()}catch{}
|
|
}else{
|
|
video.pause()
|
|
}
|
|
})
|
|
|
|
mute.addEventListener("click",e=>{
|
|
e.stopPropagation()
|
|
|
|
if(video.muted||video.volume===0){
|
|
video.muted=false
|
|
if(video.volume===0)video.volume=.5
|
|
autoplayStartedMuted=false
|
|
showUnmutePrompt(false)
|
|
}else{
|
|
video.muted=true
|
|
}
|
|
|
|
syncMuteState()
|
|
})
|
|
|
|
seek.addEventListener("input",e=>{
|
|
e.stopPropagation()
|
|
if(video.duration)video.currentTime=(e.target.value/100)*video.duration
|
|
})
|
|
|
|
volume.addEventListener("input",e=>{
|
|
e.stopPropagation()
|
|
video.volume=parseFloat(e.target.value)
|
|
video.muted=video.volume===0
|
|
|
|
if(video.volume>0){
|
|
autoplayStartedMuted=false
|
|
showUnmutePrompt(false)
|
|
}
|
|
|
|
syncMuteState()
|
|
})
|
|
|
|
rotate.addEventListener("click",e=>{
|
|
e.stopPropagation()
|
|
toggleRotate()
|
|
})
|
|
|
|
tapUnmute.addEventListener("click",e=>{
|
|
e.stopPropagation()
|
|
enableSoundAndPlay()
|
|
})
|
|
|
|
controls.addEventListener("click",e=>e.stopPropagation())
|
|
|
|
player.addEventListener("click",()=>{
|
|
showControls()
|
|
if(autoplayStartedMuted&&video.muted)enableSoundAndPlay()
|
|
},{passive:true})
|
|
|
|
player.addEventListener("mousemove",showControls)
|
|
player.addEventListener("mouseenter",showControls)
|
|
player.addEventListener("touchstart",showControls,{passive:true})
|
|
|
|
// resize
|
|
window.addEventListener("resize",()=>{
|
|
clearTimeout(resizeTimer)
|
|
resizeTimer=setTimeout(applyVideoLayout,100)
|
|
})
|
|
|
|
window.addEventListener("orientationchange",applyVideoLayout)
|
|
|
|
// init
|
|
syncPlayState()
|
|
syncMuteState()
|
|
syncRotateState()
|
|
startPlayback()
|
|
|