Last active
August 16, 2022 01:20
-
-
Save danibram/1c74dc3bcf8c465e0445f3345f7d1e41 to your computer and use it in GitHub Desktop.
Simple jquery video player (dblclick to fullscreen, play sound icons, play on screen etc...)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let VideoPlayer = {}; | |
const pauseSVG = ` | |
<svg width="26" height="32" viewBox="0 0 24 24"> | |
<path fill="currentColor" | |
d="M8 19c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2v10c0 1.1.9 2 2 2zm6-12v10c0 1.1.9 2 2 2s2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2z" /> | |
</svg> | |
`; | |
const playSVG = ` | |
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="32" viewBox="0 0 24 24"> | |
<path fill="currentColor" | |
d="M8 6.82v10.36c0 .79.87 1.27 1.54.84l8.14-5.18a1 1 0 0 0 0-1.69L9.54 5.98A.998.998 0 0 0 8 6.82z" /> | |
</svg> | |
`; | |
const muteSVG = ` | |
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="32" viewBox="0 0 24 24"> | |
<path fill="currentColor" | |
d="M3.63 3.63a.996.996 0 0 0 0 1.41L7.29 8.7L7 9H4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71v-4.17l4.18 4.18c-.49.37-1.02.68-1.6.91c-.36.15-.58.53-.58.92c0 .72.73 1.18 1.39.91c.8-.33 1.55-.77 2.22-1.31l1.34 1.34a.996.996 0 1 0 1.41-1.41L5.05 3.63c-.39-.39-1.02-.39-1.42 0zM19 12c0 .82-.15 1.61-.41 2.34l1.53 1.53c.56-1.17.88-2.48.88-3.87c0-3.83-2.4-7.11-5.78-8.4c-.59-.23-1.22.23-1.22.86v.19c0 .38.25.71.61.85C17.18 6.54 19 9.06 19 12zm-8.71-6.29l-.17.17L12 7.76V6.41c0-.89-1.08-1.33-1.71-.7zM16.5 12A4.5 4.5 0 0 0 14 7.97v1.79l2.48 2.48c.01-.08.02-.16.02-.24z" /> | |
</svg> | |
`; | |
const soundSVG = ` | |
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="32" viewBox="0 0 24 24"> | |
<path fill="currentColor" | |
d="M3 10v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1zm13.5 2A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 4.45v.2c0 .38.25.71.6.85C17.18 6.53 19 9.06 19 12s-1.82 5.47-4.4 6.5c-.36.14-.6.47-.6.85v.2c0 .63.63 1.07 1.21.85C18.6 19.11 21 15.84 21 12s-2.4-7.11-5.79-8.4c-.58-.23-1.21.22-1.21.85z" /> | |
</svg> | |
`; | |
VideoPlayer = { | |
internal: { | |
isInViewport: element => { | |
const bounding = element.getBoundingClientRect(); | |
return ( | |
bounding.top >= 0 && | |
bounding.left >= 0 && | |
bounding.bottom <= | |
(window.innerHeight || | |
document.documentElement.clientHeight) && | |
bounding.right <= | |
(window.innerWidth || document.documentElement.clientWidth) | |
); | |
}, | |
clickOrDblClick: (clickFn, dblClick) => { | |
let lastTap = 0; | |
let timeout; | |
return function detectDoubleTap(e) { | |
const curTime = new Date().getTime(); | |
const tapLen = curTime - lastTap; | |
if (tapLen < 200 && tapLen > 0) { | |
timeout && clearTimeout(timeout); | |
dblClick(e); | |
} else { | |
timeout = setTimeout(() => { | |
clickFn(e); | |
clearTimeout(timeout); | |
}, 200); | |
} | |
lastTap = curTime; | |
}; | |
} | |
}, | |
handleFullscreen: e => { | |
e.preventDefault(); | |
const video = e.currentTarget; | |
if ( | |
(document.fullscreenElement || | |
document.webkitFullscreenElement || | |
document.mozFullScreenElement || | |
document.msFullscreenElement) && | |
document.exitFullscreen | |
) { | |
if (video.exitFullscreen) { | |
video.exitFullscreen(); | |
} else if (video.webkitExitFullscreen) { | |
video.webkitExitFullscreen(); | |
} else if (video.mozExitFullscreen) { | |
video.mozExitFullscreen(); | |
} else if (video.msExitFullscreen) { | |
video.msExitFullscreen(); | |
} | |
} else { | |
if ( | |
document.fullscreenEnabled || | |
document.webkitFullscreenEnabled || | |
document.mozFullScreenEnabled || | |
document.msFullscreenEnabled | |
) { | |
if (video.requestFullscreen) { | |
video.requestFullscreen(); | |
} else if (video.webkitRequestFullscreen) { | |
video.webkitRequestFullscreen(); | |
} else if (video.mozRequestFullScreen) { | |
video.mozRequestFullScreen(); | |
} else if (video.msRequestFullscreen) { | |
video.msRequestFullscreen(); | |
} | |
} else { | |
console.log("Fullscreen not supported"); | |
} | |
} | |
}, | |
toogleVideo: e => { | |
const video = e.currentTarget; | |
// on fullscreen bypass the event to native player | |
if ( | |
!( | |
document.fullscreenElement || | |
document.webkitFullscreenElement || | |
document.mozFullScreenElement || | |
document.msFullscreenElement | |
) | |
) { | |
e.preventDefault(); | |
if (video.paused) { | |
video.play(); | |
} else { | |
video.pause(); | |
} | |
} | |
}, | |
handleMute: e => { | |
e.preventDefault(); | |
const video = $(e.currentTarget).siblings("video")[0]; | |
if (video) video.muted = false; | |
}, | |
handleSound: e => { | |
e.preventDefault(); | |
const video = $(e.currentTarget).siblings("video")[0]; | |
if (video) video.muted = true; | |
}, | |
handlePlay: e => { | |
e.preventDefault(); | |
const video = $(e.currentTarget).siblings("video")[0]; | |
if (video) video.play(); | |
}, | |
handlePause: e => { | |
e.preventDefault(); | |
const video = $(e.currentTarget).siblings("video")[0]; | |
if (video) video.pause(); | |
}, | |
startIntersectionObserver: () => { | |
const videoContainers = document.querySelectorAll( | |
".simple-video-player" | |
); | |
videoContainers.forEach(videoContainer => { | |
const video = videoContainer.querySelector("video"); | |
video.muted = true; | |
const muteButton = $(video).siblings(".mute_btn"); | |
if (muteButton) muteButton.removeClass("hide"); | |
const playPromise = video.play(); | |
if (playPromise !== undefined) { | |
playPromise.then(_ => { | |
const observer = new IntersectionObserver( | |
entries => { | |
entries.forEach(entry => { | |
if (!entry.isIntersecting && !video.paused) { | |
video.pause(); | |
} else if (video.paused) { | |
video.play(); | |
} | |
}); | |
}, | |
{ threshold: 0.2 } | |
); | |
observer.observe(video); | |
}); | |
} | |
}); | |
}, | |
init: () => { | |
// IntersectionObserver is not supported | |
if ( | |
!("IntersectionObserver" in window) || | |
!("IntersectionObserverEntry" in window) || | |
!( | |
"intersectionRatio" in | |
window.IntersectionObserverEntry.prototype | |
) || | |
!("isIntersecting" in window.IntersectionObserverEntry.prototype) | |
) { | |
console.log("No IntersectionObserver, playing all videos"); | |
const videoContainers = document.querySelectorAll( | |
".simple-video-player" | |
); | |
videoContainers.forEach(videoContainer => { | |
const video = videoContainer.querySelector("video"); | |
video.muted = true; | |
const muteButton = $(video).siblings(".mute_btn"); | |
if (muteButton) muteButton.removeClass("hide"); | |
video.play(); | |
}); | |
} else { | |
console.log("IntersectionObserver found!"); | |
VideoPlayer.startIntersectionObserver(); | |
} | |
}, | |
binds: () => { | |
document.querySelectorAll("video").forEach(video => { | |
$(video).on("playing", () => { | |
const playButton = $(video).siblings(".play_btn"); | |
const pauseButton = $(video).siblings(".pause_btn"); | |
if (playButton) playButton.addClass("hide"); | |
if (pauseButton) pauseButton.removeClass("hide"); | |
console.log(video.src, !video.paused); | |
}); | |
$(video).on("pause", () => { | |
const playButton = $(video).siblings(".play_btn"); | |
const pauseButton = $(video).siblings(".pause_btn"); | |
if (playButton) playButton.removeClass("hide"); | |
if (pauseButton) pauseButton.addClass("hide"); | |
console.log(video.src, !video.paused); | |
}); | |
$(video).on("volumechange", () => { | |
const muteButton = $(video).siblings(".mute_btn"); | |
const soundButton = $(video).siblings(".sound_btn"); | |
if (video.muted) { | |
if (muteButton) muteButton.removeClass("hide"); | |
if (soundButton) soundButton.addClass("hide"); | |
} else { | |
if (muteButton) muteButton.addClass("hide"); | |
if (soundButton) soundButton.removeClass("hide"); | |
} | |
console.log(video.src, "muted:", video.muted); | |
}); | |
}); | |
$("video").on( | |
"click", | |
VideoPlayer.internal.clickOrDblClick( | |
VideoPlayer.toogleVideo, | |
VideoPlayer.handleFullscreen | |
) | |
); | |
$("video").on( | |
"touchend", | |
VideoPlayer.internal.clickOrDblClick( | |
VideoPlayer.toogleVideo, | |
VideoPlayer.handleFullscreen | |
) | |
); | |
$(".mute_btn").on("click", VideoPlayer.handleMute); | |
$(".sound_btn").on("click", VideoPlayer.handleSound); | |
$(".play_btn").on("click", VideoPlayer.handlePlay); | |
$(".pause_btn").on("click", VideoPlayer.handlePause); | |
$(".mute_btn").on("touchend", VideoPlayer.handleMute); | |
$(".sound_btn").on("touchend", VideoPlayer.handleSound); | |
$(".play_btn").on("touchend", VideoPlayer.handlePlay); | |
$(".pause_btn").on("touchend", VideoPlayer.handlePause); | |
$(".pause_btn").html(pauseSVG); | |
$(".play_btn").html(playSVG); | |
$(".mute_btn").html(muteSVG); | |
$(".sound_btn").html(soundSVG); | |
// debug | |
} | |
}; | |
$(document).ready(function() { | |
VideoPlayer.binds(); | |
VideoPlayer.init(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment