- // ==UserScript==
- // @name Simple HTML5 video player
- // @description Replaces any default HTML5 player with custom controls
- // @grant GM_addStyle
- // @include *
- // @run-at document-load
- // @version 8
- // @namespace https://greasyfork.org/users/3167
- // @license MIT
- // ==/UserScript==
-
- var videowrapper_init = false;
-
- function HHMMSS(num) {
- num = num || 0;
- var sec_num = Math.floor(num);
-
- var hours = Math.floor(sec_num / 3600);
- var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
- var seconds = sec_num - (hours * 3600) - (minutes * 60);
-
- if (hours < 10) {hours = "0"+hours;}
- if (minutes < 10) {minutes = "0"+minutes;}
- if (seconds < 10) {seconds = "0"+seconds;}
-
- if (hours<1) {
- return minutes+':'+seconds;
- }
- return hours+':'+minutes+':'+seconds;
- }
-
- function fs_status() {
- if (document.fullscreenElement) {
- return 1;
- }
- else if (document.webkitFullscreenElement) {
- return 1;
- }
- else if (document.mozFullScreenElement) {
- return 1;
- }
- else return -1;
- }
-
- function init_videowrapper() {
-
- var videos = document.getElementsByTagName('video');
- for (var i=0; i<videos.length; i++) {
-
- (function(video) {
- if (video.controls==true && !video.iswrapped) {
- var spacing = 4;
-
- var computedStyle = window.getComputedStyle(video);
-
- video.controls_timeout=false;
-
-
- video.controls=false;
- video.iswrapped=true;
-
- var videowrapper = document.createElement('videowrapper');
- videowrapper.className=video.className;
-
- var showui = function() {
- videowrapper.classList.add("showui");
- }
- var hideui = function() {
- videowrapper.classList.remove("showui");
- }
- var peekui = function(duration) {
- duration = duration || 1000;
-
- showui();
- if (video.controls_timeout) {
- clearTimeout(video.controls_timeout);
- }
-
- video.controls_timeout = setTimeout(hideui, duration);
- }
-
-
- var showosd = function() {
- videowrapper.classList.add("showosd");
- }
- var hideosd = function() {
- videowrapper.classList.remove("showosd");
- }
- var peekosd = function(duration) {
- duration = duration || 1000;
-
- showosd();
- if (video.osd_timeout) {
- clearTimeout(video.osd_timeout);
- }
-
- video.osd_timeout = setTimeout(hideosd, duration);
- }
-
- var setosd = function(content) {
- videowrapper.setAttribute("data-osd", content)
- }
-
- setosd('Loading');
-
- if (computedStyle.position == "absolute") {
- videowrapper.className="absolute";
- } else {
- videowrapper.className="relative";
- }
-
- if (video.height>0) {
- videowrapper.style.height=video.height;
- }
- if (video.width>0) {
- videowrapper.style.width=video.width;
- }
-
- video.classList.add("iswrapped");
-
- if (video.parentNode==document.body && document.body.childNodes.length==1) {
- //document.body.style.display="flex";
- //document.body.style.alignItems="center";
- //document.body.style.justifyContent="center";
- //document.body.style.margin="auto";
- //document.body.style.height="100vh";
- document.body.className="videobody";
- }
-
- if (video.parentNode!=videowrapper) {
- video.parentNode.insertBefore(videowrapper, video);
- videowrapper.appendChild(video);
- }
-
- var controls = document.createElement('controls');
- video.parentNode.insertBefore(controls, video.nextSibling);
-
- var playbutton = document.createElement('button');
- controls.appendChild(playbutton);
- playbutton.innerHTML="▶";
-
- playbutton.style.left = spacing + "px";
-
- var timestamp = document.createElement('span');
- controls.appendChild(timestamp);
- timestamp.innerHTML="0:00/0:00";
-
- timestamp.style.left = (spacing + playbutton.clientWidth + spacing) + "px";
-
-
- var fsbutton = document.createElement('button');
- controls.appendChild(fsbutton);
- fsbutton.innerHTML="□";
-
- fsbutton.style.right = spacing + "px";
-
- var volumebar = document.createElement('input');
- controls.appendChild(volumebar);
- volumebar.type="range";
- volumebar.min=0;
- volumebar.max=1;
-
- volumebar.step=0.01;
- volumebar.value=0.5;
- volumebar.innerHTML="";
-
- volumebar.style.width="50px";
- volumebar.style.right= (spacing + fsbutton.clientWidth + spacing) + "px";
-
-
- var mutebutton = document.createElement('button');
- controls.appendChild(mutebutton);
- mutebutton.innerHTML="🔊";
- mutebutton.style.right=(spacing + volumebar.clientWidth + spacing + fsbutton.clientWidth + spacing) + "px";
-
-
- var seekbar = document.createElement('input');
- controls.appendChild(seekbar);
- seekbar.type="range";
- seekbar.value=0;
- seekbar.step=0.01;
- seekbar.innerHTML="";
-
- seekbar.hidden = true;
-
- var header = document.createElement('header');
- video.parentNode.insertBefore(header, video.nextSibling);
-
- var label = document.createElement('label');
- header.appendChild(label);
- label.innerHTML="Loading...";
-
- /*
- var savebutton = document.createElement('a');
- controls.appendChild(savebutton);
- savebutton.innerHTML="🡇";
- savebutton.style.lineHeight="32px";
- savebutton.style.position="absolute";
- savebutton.style.right="8px";
- savebutton.style.bottom="0";
- savebutton.style.border="none";
- savebutton.style.paddingTop="0";
- savebutton.style.paddingBottom="0";
- savebutton.style.paddingLeft="4px";
- savebutton.style.paddingRight="4px";
- savebutton.style.background="none";
- savebutton.style.fontFamily="Segoe UI Symbol";
- savebutton.style.fontSize="18px";
- savebutton.style.margin="0";
- savebutton.style.height="32px";
-
- savebutton.href=video.currentSrc;
- savebutton.download="";
-
- */
- var playvideo = function() {
- video.play();
- if (video.livemode) {
- video.currentTime = video.duration - 3;
- }
- }
-
- playbutton.addEventListener("click", function() {
- if (video.paused == true) {
- playvideo();
- } else {
- video.pause();
- }
-
- });
-
- video.addEventListener("click", function() {
- if (video.paused == true) {
- playvideo();
- } else {
- if (!video.livemode) {
- video.pause();
- }
- }
- });
-
- video.addEventListener("play", function() {
- setosd(playbutton.innerHTML);
- peekosd(1000);
-
- playbutton.innerHTML = "❚❚";
- //controls.className="playing";
- videowrapper.classList.remove("paused");
- videowrapper.classList.add("playing");
-
- });
-
- video.addEventListener("pause", function() {
- setosd(playbutton.innerHTML);
- peekosd(3000);
-
- playbutton.innerHTML = "▶";
- //controls.className="paused";
- videowrapper.classList.remove("playing");
- videowrapper.classList.add("paused");
- });
-
- var updatetimestamp = function() {
- if (video.livemode) {
- var buffer = Math.round(video.duration - video.currentTime);
- timestamp.innerHTML = "Buffer: " + buffer + "s";
- } else {
- timestamp.innerHTML = HHMMSS(video.currentTime) + "/" + HHMMSS(video.duration);
- }
- }
-
- video.addEventListener("timeupdate", function() {
- updatetimestamp();
- });
-
- video.addEventListener("durationchange", function() {
- updatetimestamp();
- });
-
- mutebutton.addEventListener("click", function() {
- if (video.muted == false) {
- video.muted = true;
- } else {
- video.muted = false;
- }
- });
-
- var togglefs = function() {
- if (fs_status()>0) {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- }
- }
- else {
-
- if (videowrapper.requestFullscreen) {
- videowrapper.requestFullscreen();
- } else if (videowrapper.mozRequestFullScreen) {
- videowrapper.mozRequestFullScreen(); // Firefox
- } else if (videowrapper.webkitRequestFullscreen) {
- videowrapper.webkitRequestFullscreen(); // Chrome and Safari
- }
- }
- };
-
- fsbutton.addEventListener("click", togglefs);
-
- videowrapper.addEventListener("dblclick", togglefs);
-
- seekbar.addEventListener("input", function() {
- var time = video.duration * (seekbar.value / 100);
- video.currentTime = time;
-
- });
-
-
- video.addEventListener("timeupdate", function() {
- var value = (100 / video.duration) * video.currentTime;
- var progress = (video.currentTime / video.duration);
- seekbar.value = value;
- //seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + progress + ', var(--range-progress-color)), color-stop(' + progress + ', var(--range-background-color)))';
- });
-
- var updatebuffer = function() {
-
- if (video.duration == Infinity || video.hls || video.livemode) {
- video.livemode = true;
- }
-
- if (video.livemode) {
- seekbar.hidden = true;
-
- label.innerHTML = "Live";
- } else {
-
- var start = video.buffered.length>0 ? ( video.buffered.start(0) / video.duration) : 0;
- var end = video.buffered.length>0 ? (video.buffered.end(0) / video.duration) : 0;
-
- seekbar.hidden = false;
-
- seekbar.style.left = (spacing + playbutton.clientWidth + spacing + timestamp.clientWidth + spacing) + "px";
- seekbar.style.right= (spacing + mutebutton.clientWidth + spacing + volumebar.clientWidth + spacing + fsbutton.clientWidth + spacing) + "px";
- seekbar.style.width='calc(100% - ' + seekbar.style.left + ' - ' + seekbar.style.right + ')';
-
- seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + start + ', var(--range-background-color)), color-stop(' + start + ', var(--range-progress-color)), color-stop(' + end + ', var(--range-progress-color)), color-stop(' + end + ', var(--range-background-color)))';
-
- if (video.currentSrc && video.currentSrc.length>0) {
- label.innerHTML = decodeURIComponent(video.currentSrc.split("/").pop());
- }
- }
-
- if (video.videoHeight>0) {
- videowrapper.classList.remove("audiomode");
- videowrapper.classList.add("videomode");
- } else {
- videowrapper.classList.remove("videomode");
- videowrapper.classList.add("audiomode");
- }
-
- };
-
- video.addEventListener("timeupdate", updatebuffer);
- video.addEventListener("canplay", updatebuffer);
- video.addEventListener("progress", updatebuffer);
- video.addEventListener("canplaythrough", updatebuffer);
-
- seekbar.addEventListener("mousedown", function() {
- seekbar.paused = video.paused;
- video.pause();
- });
-
- // Play the video when the slider handle is dropped
- seekbar.addEventListener("mouseup", function() {
- if (!seekbar.paused) {
- video.play();
- }
- });
-
- volumebar.addEventListener("input", function() {
- video.volume = volumebar.value;
- });
-
- video.addEventListener('wheel', function(e) {
- e.preventDefault();
- var volumedelta = 0.10;
- if (e.deltaY < 0) {
- video.volume = Math.min(video.volume+volumedelta, 1);
- }
- if (e.deltaY > 0) {
- video.volume = Math.max(video.volume-volumedelta, 0);
- }
- volumebar.value = video.volume;
-
- var volumedata = Math.round(video.volume*100) + "%";
-
- setosd(volumedata);
- peekosd(1000);
- });
-
-
- var updatevolume = function() {
- if (video.muted || video.volume==0) {
- mutebutton.innerHTML = "🔇";
- } else {
- mutebutton.innerHTML = "🔊";
- }
- volumebar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + video.volume + ', var(--range-progress-color)), color-stop(' + video.volume + ', var(--range-background-color)))';
-
- localStorage.setItem("videovolume", video.volume);
-
- }
-
- video.addEventListener("volumechange", updatevolume);
-
- volumebar.value = localStorage.getItem("videovolume", video.volume);
- video.volume = volumebar.value;
-
- videowrapper.addEventListener("mousemove", function() {
- peekui(1000);
- //seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + progress + ', var(--range-progress-color)), color-stop(' + progress + ', var(--range-background-color)))';
- });
-
-
-
- updatebuffer();
-
- updatevolume();
-
- //seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + seekbar.value / 100 + ', var(--range-progress-color)), color-stop(' + seekbar.value / 100 + ', var(--range-background-color)))';
- //volumebar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + video.volume + ', var(--range-progress-color)), color-stop(' + video.volume + ', var(--range-background-color)))';
- }
- })(videos[i])
- }
- }
-
- var stylesheet = `
- body.videobody {
- height: 100vh;
- margin: 0;
- padding: 0;
- display: flex;
- }
- videowrapper button {
- font-family: "Segoe UI Symbol", system-ui, sans-serif !important;
- }
- videowrapper label, videowrapper:before {
- font-family: system-ui, sans-serif !important;
- }
- videowrapper {
- --background-color: rgba(0, 0, 0, 0.5);
- --controls-color: #dcdcdc;
- --range-progress-color: #8c8c8c;
- --range-background-color: #3c3c3c;
-
- display: block;
- font-size: 0px;
-
- position: relative;
- width: auto;
- height: auto;
- background: inherit;
- }
- videowrapper.absolute {
- display: flex;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- margin: auto;
- }
- .videobody videowrapper.absolute {
- position: relative;
- }
- videowrapper video.iswrapped {
- position: relative;
- max-height: 100vh;
- }
- videowrapper:-webkit-full-page-media {
- width: auto;
- height: auto;
- }
- videowrapper:-webkit-full-screen {
- width: 100%;
- height: 100%;
- }
- videowrapper video::-webkit-media-controls-enclosure {
- display:none !important;
- }
- videowrapper:-webkit-full-screen controls,
- videowrapper:-webkit-full-screen header {
- z-index: 2147483647;
- }
-
- videowrapper controls > *,
- videowrapper header > * {
- color: var(--controls-color);
- /* mix-blend-mode: difference; */
- background: none;
- outline: none;
- line-height: 32px;
- position: absolute;
- font-family: monospace;
- }
-
- videowrapper controls,
- videowrapper header {
- overflow: hidden;
- white-space: nowrap;
-
- transition: all 0.5s ease !important;
- background: var(--background-color) !important;
- height: 32px !important;
- width: 100% !important;
- display: block !important;
- position: absolute !important;
- cursor: default !important;
- font-size: 18px !important;
- user-select: none;
- }
- videowrapper controls {
- bottom: 0px !important;
- }
- videowrapper header {
- top: 0px !important;
- }
-
- videowrapper controls,
- videowrapper header {
- opacity: 1;
- }
- videowrapper.playing controls,
- videowrapper.playing header {
- opacity: 0;
- }
- videowrapper controls:hover, videowrapper.showui controls, videowrapper.paused controls, videowrapper.audiomode controls,
- videowrapper header:hover, videowrapper.showui header, videowrapper.paused header, videowrapper.audiomode header {
- opacity: 1;
- }
- videowrapper button, videowrapper label {
- line-height: 32px !important;
- position: absolute !important;
- bottom: 0px !important;
- background-color: none !important;
- font-size: 18px !important;
- height: 32px !important;
- border: none !important;
- margin: 0 !important;
- }
- videowrapper button {
- width: 32px !important;
- padding: 0 !important;
- }
- videowrapper input[type=range] {
- line-height: 32px !important;
- position: absolute !important;
- background-color: var(--range-background-color) !important;
-
- bottom: 10px !important;
- height: 10px !important;
- border: none !important;
- margin: 0px !important;
- border-radius: 6px !important;
- -webkit-appearance: none !important;
- }
- videowrapper input[type='range']::-webkit-slider-thumb {
- -webkit-appearance: none !important;
- background-color: var(--controls-color);
- border: none;
- height: 16px;
- width: 16px;
- border-radius: 50%;
- }
-
- videowrapper.audiomode video:-webkit-full-page-media {
- width: 600px;
- }
- videowrapper:before {
- content: attr(data-osd);
- position: absolute;
- left: 50%;
- top: calc(50%);
- color: white;
- -webkit-text-stroke: 3px #333333;
- font-size: 64px;
- font-weight: bold;
- font-style: normal;
- z-index: 1;
- transform: translate(-50%, -50%);
- pointer-events: none;
- opacity: 0;
- }
- videowrapper.audiomode:before,
- videowrapper.showosd:before,
- videowrapper.paused:before {
- opacity: 1;
- }
- videowrapper label {
- right: 0;
- min-width: 100%;
- text-align: left;
- box-sizing: border-box;
- width: 100% !important;
- padding: 0px 8px !important;
- }
- `;
-
- function init() {
- if (videowrapper_init) {
- console.log("Cannot init_videowrapper twice!");
- return;
- }
- videowrapper_init = true;
-
- if (typeof GM_addStyle != "undefined") {
- GM_addStyle (stylesheet);
- } else {
- var css = document.createElement("style");
- css.type = "text/css";
- css.innerHTML = stylesheet;
- document.head.appendChild(css);
- }
-
- init_videowrapper();
- if (typeof unsafeWindow != "undefined") {
- unsafeWindow.init_videowrapper = init_videowrapper;
- }
- }
-
- init();