Skip to content

Instantly share code, notes, and snippets.

@danibram
Last active August 16, 2022 01:20
Show Gist options
  • Save danibram/1c74dc3bcf8c465e0445f3345f7d1e41 to your computer and use it in GitHub Desktop.
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...)
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