Revisions
-
HT-7 revised this gist
18 minutes agoAug 12, 2023 . 1 changed file with 26 additions and 17 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,3 @@ // == Dependencies == var mediaType; // for compatibility @@ -557,6 +555,12 @@ function timeUI() { timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; left:0; bottom:0; pointer-events:none; }", timerUI.div); // play/pause symbol appendChildWithID("button","timerUI_playback_status",timerUI.div ); timerUI.status = document.getElementById("timerUI_playback_status"); timerUI.status.innerHTML="■"; addStyle("#timerUI #timerUI_playback_status { display:block; position:fixed; cursor:pointer; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div); // progress bar appendChildWithID("div","timerUI_progress_bar",timerUI.div ); timerUI.bar = document.getElementById("timerUI_progress_bar"); @@ -567,23 +571,14 @@ function timeUI() { timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; left:0; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div); // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); timerUI.time = document.getElementById("timerUI_media_timer"); timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #timerUI_media_timer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #timerUI #timerUI_media_timer .timer_linefeed { display:none; }", timerUI.div); // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); @@ -594,6 +589,12 @@ function timeUI() { addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); // media title appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;", timerUI.div); timerUI.domainRules(); // load domain rules after initializing timer elements // update timer during playback every fifteenth of a second and while mouse is dragging progress bar @@ -632,15 +633,15 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); } }; /* function dragSeekBar(m){ // currently unused m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var dragSeekBarInterval = setInterval( function() { media_element.currentTime = media_element.duration * clickPos; timerUI.update(); if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); } */ timerUI.bar_placeholder.addEventListener("mousedown", timerUI.clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); @@ -684,7 +685,10 @@ timerUI.domainRules = function() { } // activate light mode on wikis and Dailymotion due to bright backgrounds if ( isDomain("wiki") || isDomain("dailymotion.com") || isDomain("ghostarchive.org") || is_archive_library() ) { timerUI.light_mode_on(); } @@ -717,7 +721,7 @@ timerUI.titleDomainRules = function() { } // Internet Archive library only, not Wayback Machine if ( is_archive_library() ) { // get media title from page title before first colon timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) @@ -737,6 +741,11 @@ timerUI.titleDomainRules = function() { } }; function is_archive_library() { // function to check if the current page is an Archive.org library page and not the Wayback Machine return (isDomain(/^(www.)?archive.org/) && ! isDomain("web.archive.org") ); // automatically returns true if the condition is met and false otherwise } function is_WaybackEmbed() { // checks if the current page is media embedded on the Wayback Machine, for code deduplication. if ( isDomain("web.archive.org") || isDomain("wayback.archive.org") && document.title=="Wayback Machine" && document.getElementsByTagName("iframe")[0] ) { -
HT-7 revised this gist
on Jul 10Jul 10, 2023 . 1 changed file with 122 additions and 26 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -58,8 +58,10 @@ function isDomain(domain) { } // symbols var media_symbol = {}; media_symbol.play = "▶︎ "; // thin space for alignment media_symbol.pause="❚ ❚"; // instead of "⏸" due to Edge browser putting an immutable blue box around it. media_symbol.stop="■"; // mousedown status var mousedown_status; @@ -162,6 +164,18 @@ var mediafileext = { "audio":[".mp3", ".wma", ".wav", ".ogg", ".opus", ".flac", ".oga", ".wma", ".aac", ".amr", ".alac", ".m4a"] }; // "replaceAll()" polyfill for pre-2020 browsers // based on: https://stackoverflow.com/a/1144788 function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string } // renamed function to prevent interference with "replaceAll()" on browsers since 2020 function replaceAll_polyfill(str, find, replacement) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replacement); } // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists @@ -177,6 +191,7 @@ timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.default_color = "rgb(49,136,255)"; // memorize default color timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.font_pack = "din, futura, 'noto sans', 'open sans', ubuntu, 'segoe ui', verdana, tahoma, roboto, 'roboto light', arial, helvetica, 'trebuchet ms' ,'bitstream vera sans', sans-serif, consolas, monospace"; timerUI.width_breakpoint = 768; // pixels @@ -205,7 +220,7 @@ timerUI.toggle.main = function() { timerUI.div.style.display = "block"; console.log("timerUI on"); } if (timerUI.on) { timerUI.on = false; return false; } else { timerUI.on = true; return false; } } else { console.warn(timerUI.msg.notimer); timeUI(); @@ -223,7 +238,11 @@ timerUI.toggle.buffer = function() { timerUI.buffer_bar.style.display = "block"; console.log("timerUI buffer bar on"); } if (timerUI.buffer_on) { timerUI.buffer_on = false; return false; } else { timerUI.buffer_on = true; return true; } } else { console.warn(timerUI.msg.notimer); timeUI(); @@ -241,7 +260,11 @@ timerUI.toggle.title = function() { timerUI.title.style.display = "block"; console.log("timerUI title on"); } if (timerUI.title_on) { timerUI.title_on = false; return false; } else { timerUI.title_on = true; return true; } } else { console.warn(timerUI.msg.notimer); timeUI(); @@ -256,6 +279,8 @@ timerUI.getTitle = function() { if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; else { // skipping this whole part if no custom title is specified timerUI.newTitle = document.title; // replace underscores with spaces timerUI.newTitle = replaceAll_polyfill(timerUI.newTitle, "_"," "); timerUI.titleDomainRules(); } if (media_element) { @@ -270,6 +295,7 @@ timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (! media_element.videoWidth) return "audio"; // Detects files that only contain audio, even if they have a video file extension. if (media_element.videoWidth > 0) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected @@ -324,13 +350,16 @@ timerUI.update = function() { break; } if (media_element.paused) { timerUI.status.innerHTML=media_symbol.pause; } else { timerUI.status.innerHTML=media_symbol.play; } } else { timerUI.stop(); console.warn(timerUI.msg.nomedia); } }; timerUI.updateTitle = function() { if (timerUI.title) timerUI.title.innerHTML = timerUI.getTitle(); }; // update title on URL change addEventListener('popstate', timerUI.updateTitle); @@ -414,6 +443,12 @@ timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) { // colors timerUI.setColor = function(newColor) { if (! timerUI.bar) { /* prevent running function before timerUI is properly loaded into the DOM to prevent exception */ if (timerUI.debug_mode) console.debug("timerUI: setColor can not run before timerUI is properly loaded."); return false; } timerUI.previous_color = timerUI.color; // memorize previous setting newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; timerUI.bar.style.backgroundColor=timerUI.color; @@ -423,8 +458,16 @@ timerUI.setColor = function(newColor) { timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; // colour all buffer segments for (var count=0; count < timerUI.buffer_bar.childNodes.length; count++) { timerUI.buffer_bar.childNodes[count].style.backgroundColor=timerUI.color; } if (timerUI.debug_mode) console.debug("timerUI: color changed from "+timerUI.previous_color+" to "+timerUI.color); }; timerUI.setColor("default"); // prevent mixed colours if the code is run multiple times timerUI.setGradient = function(newGradient) { newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.9)" : timerUI.gradient = newGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; @@ -435,11 +478,55 @@ timerUI.setFont = function(newFont) { timerUI.title.style.fontFamily=newFont; }; // light mode timerUI.light_mode = false; // default timerUI.light_mode_on = function() { timerUI.light_mode = true; timerUI.color_before_light_mode = timerUI.color; // improves visibility: if (timerUI.setColor) /* exists*/ { timerUI.setColor("lightblue"); } else { return false; /* error */ } if (timerUI.gradient_placeholder) /* exists*/ { timerUI.gradient_placeholder.style.backgroundColor="rgba(0, 0, 0, 0.5)"; } else { return false; /* error */ } }; timerUI.light_mode_off = function() { timerUI.light_mode = false; if (timerUI.setColor) /* exists*/ { timerUI.setColor("lightblue"); } else { return false; /* error */ } if (timerUI.gradient_placeholder) /* exists*/ { timerUI.gradient_placeholder.style.backgroundColor=""; // fall back to default } else { return false; /* error */ } }; timerUI.toggle.light_mode = function() { if ( ! timerUI.light_mode ) /* if light mode is deactivated */ { timerUI.light_mode_on(); return true; } else { timerUI.light_mode_off(); return false; } }; // "stop" icon timerUI.stop = function() { timerUI.status.innerHTML=media_symbol.stop; timerUI.bar.style.width=0; timerUI.buffer_bar.style.width=0; // appearance of stopped timer consistent with the show_remaining setting if (timerUI.show_remaining == 2) { timerUI.time.innerHTML=MStimer(undefined)+" / "+MStimer(undefined); } else { timerUI.time.innerHTML=HMStimer(undefined); } }; // Additional checks to ensure the player is detected @@ -451,7 +538,6 @@ function timeUI() { // slightly different name to prevent naming collision with timerUI object checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists || timerUI.override_check ) { @@ -462,30 +548,30 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); // button styling addStyle("#timerUI button { background:none; border:none; outline:none; line-height:unset; padding:0; margin:0; } #timerUI button:hover { filter: brightness(1.2); } #timerUI button:active { filter: brightness(0.6); }", timerUI.div); // to suppress button background and border on earlier browser versions timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector // background gradient appendChildWithID("div","timerUI_bottom_gradient",timerUI.div ); timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; left:0; bottom:0; pointer-events:none; }", timerUI.div); // progress bar appendChildWithID("div","timerUI_progress_bar",timerUI.div ); timerUI.bar = document.getElementById("timerUI_progress_bar"); addStyle("#timerUI #timerUI_progress_bar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; left:0; bottom:0; }", timerUI.div); // buffer bar appendChildWithID("div","timerUI_buffer_bar",timerUI.div ); timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; left:0; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div); // media title appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;", timerUI.div); // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); @@ -502,12 +588,13 @@ function timeUI() { // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("timerUI_progress_placeholder"); addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; left:0; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.domainRules(); // load domain rules after initializing timer elements // update timer during playback every fifteenth of a second and while mouse is dragging progress bar timerUI.interval.update = setInterval( @@ -535,7 +622,7 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); }; // clickable progress bar (experimental) - "clickPos" has no "timerUI." notation because it is inside the main function. timerUI.clickSeekBar = function(m){ if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; @@ -596,6 +683,11 @@ timerUI.domainRules = function() { customTitleElement = document.getElementById("media-title"); // for unlisted videos (Dailymotion only displays the video title in the HTML page title for public videos) } // activate light mode on wikis and Dailymotion due to bright backgrounds if ( isDomain("wiki") || isDomain("dailymotion.com") || isDomain("ghostarchive.org") ) { timerUI.light_mode_on(); } // media embedded on Wayback Machine if ( is_WaybackEmbed() ) { tmp = document.getElementsByTagName("iframe")[0]; // iframe in temporary variable to deduplicate code @@ -618,19 +710,23 @@ timerUI.titleDomainRules = function() { // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); } // remove "File:" prefix on wikis and if ( isDomain("wiki") ) { if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); } // Internet Archive library only, not Wayback Machine if ( isDomain(/^(www.)?archive.org/) && ! isDomain("web.archive.org") ) { // get media title from page title before first colon timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) timerUI.archive_org_title = document.title.substring(0,document.title.search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); if (timerUI.archive_org_title.length > 0) /* only append " - " if a title exists. */ { /* only append " - " if a title exists. */ if (timerUI.newTitle != "") { timerUI.newTitle += " - "; } timerUI.newTitle += timerUI.archive_org_title; } // trim after second-last colon, -1 to remove space at end timerUI.newTitle=decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". @@ -655,4 +751,4 @@ function is_WaybackEmbed() { // == Master function == timeUI(); -
HT-7 revised this gist
on Mar 14Mar 14, 2023 . 1 changed file with 1 addition and 3 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -655,6 +655,4 @@ function is_WaybackEmbed() { // == Master function == timeUI(); -
HT-7 revised this gist
on Mar 14Mar 14, 2023 . 1 changed file with 11 additions and 8 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -158,8 +158,8 @@ function togglePlay(media_element) { // media file extension list var mediafileext = { "video":[".mp4", ".mpg", ".mpeg", ".mts", ".mt2s", ".m4v", ".ts", ".ogv", ".wmv", ".3gp", ".3gpp", ".webm"], "audio":[".mp3", ".wma", ".wav", ".ogg", ".opus", ".flac", ".oga", ".wma", ".aac", ".amr", ".alac", ".m4a"] }; // == Main code == @@ -260,7 +260,7 @@ timerUI.getTitle = function() { } if (media_element) { timerUI.updateFileIcon(); return timerUI.file_icon+" "+timerUI.newTitle; } else { return "TimerUI – designed for home cinemas"; } @@ -269,17 +269,18 @@ timerUI.getTitle = function() { timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (! media_element.videoWidth) return "audio"; // Detects files that only contain audio, even if they have a video file extension. if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected }; timerUI.updateFileIcon = function() { timerUI.file_icon = timerUI.guessMediaType(); switch(timerUI.file_icon) { case "video": timerUI.file_icon = "🎞️"; break; case "audio": timerUI.file_icon = "♫"; break; case "unknown": timerUI.file_icon = "📄"; break; } }; @@ -655,3 +656,5 @@ function is_WaybackEmbed() { // == Master function == timeUI(); } -
HT-7 revised this gist
on Nov 5, 2022Nov 5, 2022 . 1 changed file with 71 additions and 31 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -6,13 +6,18 @@ var mediaType; // for compatibility var playerExists = false; // is set to true below if player exists var checkMediaType_enabled = true; // for debugging purposes var media_element = {}; // declaring as object var tmp="",count=0; // initiating temporary variables used inside functions and loops function checkMediaType() { // checks whether it is a video or an audio tag if ( checkMediaType_enabled ) { var mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } var mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. @@ -173,7 +178,7 @@ timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.font_pack = "din, futura, 'noto sans', 'open sans', ubuntu, 'segoe ui', verdana, tahoma, roboto, 'roboto light', arial, helvetica, 'trebuchet ms' ,'bitstream vera sans', sans-serif, consolas, monospace"; timerUI.width_breakpoint = 768; // pixels // console notifications and warnings (possibly to be expanded) @@ -244,7 +249,10 @@ timerUI.toggle.title = function() { }; timerUI.getTitle = function() { if (! timerUI.domainRules_checked) /* only check domain rules once */ { timerUI.domainRules(); timerUI.domainRules_checked = true; } if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; else { // skipping this whole part if no custom title is specified timerUI.newTitle = document.title; @@ -373,15 +381,16 @@ timerUI.update_multi_buffer = function() { timerUI.generate_buffer_segments = function() { timerUI.buffer_bar.innerHTML=""; // reset to re-generate segments for (count=0; count < media_element.buffered.length; count++) { timerUI.append_buffer_segment( timerUI.get_buffer_range(count).start_pos, timerUI.get_buffer_range(count).end_pos ); } timerUI.select_segments = timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); timerUI.segment_count = timerUI.select_segments.length; }; timerUI.append_buffer_segment = function(start_pos,end_pos) { timerUI.buffer_bar.appendChild(document.createElement("div") ); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;background-color:"+timerUI.color+";"; @@ -580,38 +589,69 @@ function timeUI() { timerUI.domainRules = function() { if (isDomain("dailymotion.com") && document.location.pathname.search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. customMediaElement( document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0] ); customTitleElement = document.getElementById("media-title"); // for unlisted videos (Dailymotion only displays the video title in the HTML page title for public videos) } // media embedded on Wayback Machine if ( is_WaybackEmbed() ) { tmp = document.getElementsByTagName("iframe")[0]; // iframe in temporary variable to deduplicate code customMediaElement( tmp.contentWindow.document.getElementsByTagName("video")[0] ); // dark background for improved video visibility tmp.contentWindow.document.body.style.backgroundColor="#222"; } }; timerUI.titleDomainRules = function() { // custom domain rules for title if ( isDomain("youtube.com") || isDomain("dailymotion.com") || isDomain("wikimedia.org") || isDomain("wikipedia.org") || isDomain("wikiversity.org") || isDomain("wikibooks.org") || isDomain("mediawiki.org") ) { // negative lookahead regular expression – trim after last dash // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); } // remove "File:" prefix on wikis if ( isDomain("wiki") ) { if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); } // Internet Archive library only, not Wayback Machine if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { // get media title from page title before first colon timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) if (timerUI.newTitle != "") { timerUI.newTitle += " - "; } timerUI.newTitle += document.title.substring(0,document.title.search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); // trim after second-last colon, -1 to remove space at end timerUI.newTitle=decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". } if ( is_WaybackEmbed() ) { // Already generated by the browser inside the iframe. How convenient. Otherwise, a regular expression that matches the part after the last slash in the URL, and a decodeURI would have to be used. timerUI.newTitle = tmp.contentWindow.document.title; } }; function is_WaybackEmbed() { // checks if the current page is media embedded on the Wayback Machine, for code deduplication. if ( isDomain("web.archive.org") || isDomain("wayback.archive.org") && document.title=="Wayback Machine" && document.getElementsByTagName("iframe")[0] ) { // separate check for ID of iframe to avoid reference error if (document.getElementsByTagName("iframe")[0].id=="playback") { return true; } } else { return false; } } // == Master function == timeUI(); -
HT-7 revised this gist
on Oct 9, 2022Oct 9, 2022 . 1 changed file with 32 additions and 54 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -37,11 +37,11 @@ function checkFileExtension(ext) { if (typeof(ext) == "string") { ext = ext.toLowerCase(); // case-insensitive // string if (document.location.href.search(new RegExp(ext+"$", "i")) > -1) return true; else return false; } else if (typeof(ext) == "object") { // array – check against multiple strings for (var count=0; count < ext.length; count++) { if (document.location.href.search(new RegExp(ext[count]+"$", "i")) > -1) return true; if (count == ext.length-1) return false; // if no matches after going through them all } } @@ -167,10 +167,8 @@ timerUI.override_check = false; timerUI.on = true; timerUI.buffer_on = true; timerUI.multiBuffer = true; // multiple buffer segments timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. @@ -182,7 +180,7 @@ timerUI.width_breakpoint = 768; // pixels timerUI.msg = { "notimer": "timerUI: No timer found; checking for media element again. Please try again.", "nomedia": "timerUI: no media element found on page. Stopping." }; // text containers (no const for compatibility) var timer_linefeed = "<span class=timer_linefeed><br /></span>"; @@ -191,6 +189,7 @@ var timer_slash = " <span class=timer_slash>/</span> "; // functions timerUI.toggle = {}; timerUI.toggle.main = function() { // show and hide if (timerUI.div) { timerUI.update(); if (timerUI.on) { @@ -257,15 +256,15 @@ timerUI.getTitle = function() { } else { return "TimerUI – designed for home cinemas"; } }; timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected }; timerUI.updateFileIcon = function() { timerUI.fileIcon = timerUI.guessMediaType(); @@ -274,15 +273,15 @@ timerUI.updateFileIcon = function() { case "audio": timerUI.fileIcon = "♫"; break; case "unknown": timerUI.fileIcon = "📄"; break; } }; timerUI.adaptTitleWidth = function() { if (media_element.duration > 3600 && timerUI.show_remaining == 2 && window.innerWidth > timerUI.width_breakpoint) timerUI.title.style.maxWidth = "calc(100% - 670px)"; else timerUI.title.style.maxWidth = "calc(100% - 400px)"; }; window.addEventListener('resize', function() { if (window.innerWidth < timerUI.width_breakpoint) timerUI.title.removeAttribute("style"); @@ -320,17 +319,9 @@ timerUI.update = function() { timerUI.status.innerHTML=symbol_play : timerUI.status.innerHTML=symbol_pause; } else { timerUI.stop(); console.warn(timerUI.msg.nomedia); } }; timerUI.updateTitle = function() { if (timerUI.title) timerUI.title.innerHTML = timerUI.getTitle(); }; // update title on URL change addEventListener('popstate', timerUI.updateTitle); @@ -388,18 +379,19 @@ timerUI.generate_buffer_segments = function() { timerUI.segment_count = timerUI.select_segments.length; }; timerUI.append_buffer_segment = function(start_pos,end_pos) { if (!start_pos) start_pos=timerUI.get_buffer_range(segment_number).start_pos; if (!end_pos) end_pos=timerUI.get_buffer_range(segment_number).end_pos; timerUI.buffer_bar.appendChild(document.createElement("div") ); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;background-color:"+timerUI.color+";"; }; timerUI.get_buffer_range = function(segment_number) { return { start_pos: media_element.buffered.start(segment_number) / media_element.duration * 100, end_pos: media_element.buffered.end(segment_number) / media_element.duration * 100 }; // object with start and end percentages }; timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) { @@ -421,9 +413,6 @@ timerUI.setColor = function(newColor) { timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; }; timerUI.setGradient = function(newGradient) { @@ -486,7 +475,7 @@ function timeUI() { appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;"); // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); @@ -506,12 +495,8 @@ function timeUI() { addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); // update timer during playback every fifteenth of a second and while mouse is dragging progress bar @@ -540,25 +525,16 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); }; // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; // go to beginning if clicked in first percentile if (clickPos < 0.01 ) media_element.currentTime = 0; else media_element.currentTime = media_element.duration * clickPos; timerUI.update(); timerUI.updateBufferBar(true); } }; function dragSeekBar(m){ // currently unused m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; @@ -602,7 +578,7 @@ function timeUI() { // == Custom domain rules == timerUI.domainRules = function() { if (isDomain("dailymotion.com") && document.location.pathname.search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); customTitleElement = document.getElementById("media-title"); // for unlisted @@ -627,11 +603,13 @@ timerUI.titleDomainRules = function() { } if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) if (timerUI.newTitle != "") { timerUI.newTitle += " - "; } timerUI.newTitle += document.title.substring(0,document.title.search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); // trim after second-last colon, -1 to remove space at end decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". } }; -
HT-7 revised this gist
on Jun 1, 2022Jun 1, 2022 . 1 changed file with 30 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -167,8 +167,10 @@ timerUI.override_check = false; timerUI.on = true; timerUI.buffer_on = true; timerUI.multiBuffer = true; // multiple buffer segments timerUI.left_mode = 1; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.css = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. @@ -320,7 +322,15 @@ timerUI.update = function() { } else { timerUI.stop(); console.warn(timerUI.msg.nomedia) } }; timerUI.leftPlaybackControls timerUI.updateTitle = function() { if (timerUI.title) { switch(timerUI.left_mode) { case 1: timerUI.title.innerHTML = timerUI.getTitle(); case 2: timerUI.leftPlaybackControls(); case 3: timerUI.left_hidden(); } } // update title on URL change addEventListener('popstate', timerUI.updateTitle); @@ -411,6 +421,9 @@ timerUI.setColor = function(newColor) { timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; // additional colors timerUI.css.colors.innerHTML = "#timerUI .timerUI_buffer_segment { background-color:"+timerUI.color+"; }"; }; timerUI.setGradient = function(newGradient) { @@ -493,8 +506,12 @@ function timeUI() { addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%; } } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.css.responsive=timerUI.div.lastElementChild; appendChildWithID("style","timerUI_colors",timerUI.div); timerUI.css.colors=document.getElementById("timerUI_colors"); // update timer during playback every fifteenth of a second and while mouse is dragging progress bar @@ -523,6 +540,17 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); }; // toggle between elapsed, remaining, and elapsed/total time timerUI.title.onclick = function() { switch(timerUI.left_mode) { case 1: timerUI.left_mode = 2; break; case 2: timerUI.left_mode = 3; break; case 3: timerUI.left_mode = 1; break; } timerUI.update(); timerUI.updateBufferBar(true); }; // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ if (media_element) { -
HT-7 revised this gist
on Jun 1, 2022Jun 1, 2022 . 1 changed file with 113 additions and 46 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // TimerUI – for home cinemas // == Dependencies == @@ -40,9 +40,9 @@ function checkFileExtension(ext) { if (document.location.toString().search(new RegExp(ext+"$", "i")) > -1) return true; else return false; } else if (typeof(ext) == "object") { // array – check against multiple strings for (var count=0; count < ext.length; count++) { if (document.location.toString().search(new RegExp(ext[count]+"$", "i")) > -1) return true; if (count == ext.length-1) return false; // if no matches after going through them all } } } @@ -162,8 +162,11 @@ if (! timerUI) var timerUI = new Object({}); // create parent object if none exi // default system variables timerUI.debug_mode = false; timerUI.override_check = false; timerUI.on = true; timerUI.buffer_on = true; timerUI.multiBuffer = true; // multiple buffer segments timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. @@ -184,7 +187,8 @@ var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; // functions timerUI.toggle = {}; timerUI.toggle.main = function() { if (timerUI.div) { timerUI.update(); if (timerUI.on) { @@ -202,9 +206,9 @@ timerUI.toggle = function() { } }; timerUI.toggle.buffer = function() { if (timerUI.div) { timerUI.update(); timerUI.updateBufferBar(true); if (timerUI.buffer_on) { timerUI.buffer_bar.style.display = "none"; console.log("timerUI buffer bar off"); @@ -220,9 +224,9 @@ timerUI.toggleBuffer = function() { } }; timerUI.toggle.title = function() { if (timerUI.div) { timerUI.update(); timerUI.updateBufferBar(true); if (timerUI.title_on) { timerUI.title.style.display = "none"; console.log("timerUI title off"); @@ -245,8 +249,12 @@ timerUI.getTitle = function() { timerUI.newTitle = document.title; timerUI.titleDomainRules(); } if (media_element) { timerUI.updateFileIcon(); return timerUI.fileIcon+" "+timerUI.newTitle; } else { return "TimerUI – designed for home cinemas"; } } timerUI.guessMediaType = function() { @@ -281,10 +289,8 @@ window.addEventListener('resize', function() { timerUI.update = function() { if (media_element) { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; // buffer bar update formerly located here; removed from the scope of this function switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" @@ -322,19 +328,79 @@ addEventListener('popstate', timerUI.updateTitle); // update title fallback timerUI.interval.updateTitle = setInterval(timerUI.updateTitle, 2000); // buffer bar timerUI.updateBufferBar = function(override_paused) { if (media_element && timerUI.buffer_on && (!media_element.paused || override_paused) ) { timerUI.multiBuffer ? timerUI.update_multi_buffer() : timerUI.single_segment_buffer(); } }; // single-segment buffer bar timerUI.single_segment_buffer = function() { if (timerUI.buffer_bar.innerHTML!="") { timerUI.buffer_bar.style=""; timerUI.buffer_bar.innerHTML=""; } // reset after switching from multi-segment buffer bar // find out first buffer segment after current playback position media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if ( timerUI.buffer_segment > 0) { while (media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 1 ) { timerUI.update_single_buffer(); timerUI.buffer_segment-- ; } } }; timerUI.update_single_buffer = function() { if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" timerUI.buffer_bar.style.width=media_element.buffered.end(timerUI.buffer_segment) / media_element.duration * 100 + "%"; } else { timerUI.buffer_bar.style.width="0%"; } }; // multi-segment buffer bar – highlight all buffered parts timerUI.update_multi_buffer = function() { if (timerUI.buffer_bar.style.length < 1) { timerUI.buffer_bar.style.width="100%"; timerUI.buffer_bar.style.backgroundColor="rgba(0,0,0,0)"; } if (media_element.buffered.length > 0) { timerUI.generate_buffer_segments(); } else { timerUI.buffer_bar.style.width="0%"; } }; timerUI.generate_buffer_segments = function() { timerUI.buffer_bar.innerHTML=""; // reset to re-generate segments for (count=0; count < media_element.buffered.length; count++) { timerUI.append_buffer_segment(timerUI.get_buffer_range(count) ); } timerUI.select_segments = timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); timerUI.segment_count = timerUI.select_segments.length; }; timerUI.append_buffer_segment = function([start_pos,end_pos]) { // array function timerUI.buffer_bar.appendChild(document.createElement("div")); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;"; }; timerUI.get_buffer_range = function(segment_number) { return [ media_element.buffered.start(segment_number) / media_element.duration * 100, media_element.buffered.end(segment_number) / media_element.duration * 100 ]; // array with start and end percentages }; timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) { var selection=timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); selection[segment_number].style.left = start_pos / media_element.duration * 100 + "%"; selection[segment_number].style.width = (end_pos-start_pos) / media_element.duration * 100 + "%"; }; // colors timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; @@ -375,7 +441,7 @@ function timeUI() { checkMediaType(); timerUI.domainRules(); // load domain rules // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists || timerUI.override_check ) { // Adding elements @@ -384,50 +450,50 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); // button styling addStyle("#timerUI button { background:none; border:none; outline:none; line-height:unset; } #timerUI button:hover { filter: brightness(1.2); } #timerUI button:active { filter: brightness(0.6); }", timerUI.div); // to suppress button background and border on earlier browser versions timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector // background gradient appendChildWithID("div","timerUI_bottom_gradient",timerUI.div ); timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; bottom:0; pointer-events:none; }", timerUI.div); // progress bar appendChildWithID("div","timerUI_progress_bar",timerUI.div ); timerUI.bar = document.getElementById("timerUI_progress_bar"); addStyle("#timerUI #timerUI_progress_bar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div); // buffer bar appendChildWithID("div","timerUI_buffer_bar",timerUI.div ); timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div); // media title appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;") // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); timerUI.time = document.getElementById("timerUI_media_timer"); timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #timerUI_media_timer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #timerUI #timerUI_media_timer .timer_linefeed { display:none; }", timerUI.div); // play/pause symbol appendChildWithID("button","timerUI_playback_status",timerUI.div ); timerUI.status = document.getElementById("timerUI_playback_status"); timerUI.status.innerHTML="■"; addStyle("#timerUI #timerUI_playback_status { display:block; position:fixed; cursor:pointer; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div); // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("timerUI_progress_placeholder"); addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); @@ -440,11 +506,11 @@ function timeUI() { ); // Longer interval for buffer bar to minimize CPU usage timerUI.interval.buffer = setInterval(timerUI.updateBufferBar, 1000); // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); timerUI.updateBufferBar(true); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // toggle between elapsed, remaining, and elapsed/total time @@ -454,14 +520,15 @@ function timeUI() { case 1: timerUI.show_remaining = 2; timerUI.adaptTitleWidth(); break; case 2: timerUI.show_remaining = 0; timerUI.adaptTitleWidth(); break; } timerUI.update(); timerUI.updateBufferBar(true); }; // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; timerUI.update(); timerUI.updateBufferBar(true); } } function dragSeekBar(m){ // currently unused -
HT-7 revised this gist
on May 24, 2022May 24, 2022 . 1 changed file with 223 additions and 69 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -28,8 +28,28 @@ function customMediaElement(custom_media_element) { if (custom_media_element) { playerExists = true; media_element = custom_media_element; console.log("customMediaElement: Custom media element set. Reset using checkMediaType_enabled=true."); } else { console.error("customMediaElement: No such media element found."); } } var customTitleElement; function checkFileExtension(ext) { if (typeof(ext) == "string") { ext = ext.toLowerCase(); // case-insensitive // string if (document.location.toString().search(new RegExp(ext+"$", "i")) > -1) return true; else return false; } else if (typeof(ext) == "object") { // array – check against multiple strings for (var a=0; a < ext.length; a++) { if (document.location.toString().search(new RegExp(ext[a]+"$", "i")) > -1) return true; if (a == ext.length-1) return false; // if no matches after going through them all } } } function isDomain(domain) { // Using .search() instead of .includes() to improve browser compatibility. if (window.location.hostname.search(domain) >= 0) return true; else return false; } // symbols @@ -55,29 +75,27 @@ function addStyle(new_style,parent_element) { } // time variables var media_time = {}; // HH:MM:SS timer function HMStimer_core(seconds) { // hours media_time.HH = Math.floor( seconds/3600 ); // leading zero if ( seconds < 36000 ) media_time.HH = "0" + media_time.HH; // minutes media_time.MM = Math.floor( seconds/60%60 ); // leading zero if ( seconds%3600 < 600 ) media_time.MM = "0" + media_time.MM; // seconds media_time.SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) media_time.SS = "0" + media_time.SS; return media_time.HH+":"+media_time.MM+":"+media_time.SS; } function HMStimer(seconds) { @@ -95,16 +113,16 @@ function HMStimer(seconds) { function MStimer_core(seconds) { // minutes media_time.MM = Math.floor( seconds/60 ); // leading zero if ( seconds%3600 < 600 ) media_time.MM = "0" + media_time.MM; // seconds media_time.SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) media_time.SS = "0" + media_time.SS; return media_time.MM+":"+media_time.SS; } function MStimer(seconds) { @@ -128,23 +146,44 @@ Object.prototype.togglePlay = function togglePlay() { // new function without object prototype for compatibility function togglePlay(media_element) { if (media_element) { // validate media element first to avoid errors media_element.paused ? media_element.play() : media_element.pause(); } } // media file extension list var mediafileext = { "video":[".mp4",".mpg",".mpeg",".mts",".mt2s",".m4v",".ts",".ogv",".wmv",".3gp",".3gpp"], "audio":[".mp3",".wma",".wav",".ogg",".opus",".flac",".oga",".wma",".aac",".amr",".alac",".m4a"] }; // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists // default system variables timerUI.debug_mode = false; timerUI.on = true; timerUI.buffer_on = true; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.font_pack = "din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace"; timerUI.width_breakpoint = 768; // pixels // console notifications and warnings (possibly to be expanded) timerUI.msg = { "notimer": "timerUI: No timer found; checking for media element again. Please try again.", "nomedia": "timerUI: no media element found on page. Stopping." } // text containers (no const for compatibility) var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; // functions timerUI.toggle = function() { if (timerUI.div) { timerUI.update(); @@ -158,7 +197,7 @@ timerUI.toggle = function() { } timerUI.on ? timerUI.on = false : timerUI.on = true; } else { console.warn(timerUI.msg.notimer); timeUI(); } }; @@ -176,14 +215,71 @@ timerUI.toggleBuffer = function() { } timerUI.buffer_on ? timerUI.buffer_on = false : timerUI.buffer_on = true; } else { console.warn(timerUI.msg.notimer); timeUI(); } }; timerUI.toggleTitle = function() { if (timerUI.div) { timerUI.update(); if (timerUI.title_on) { timerUI.title.style.display = "none"; console.log("timerUI title off"); } if (! timerUI.title_on ) { timerUI.title.style.display = "block"; console.log("timerUI title on"); } timerUI.title_on ? timerUI.title_on = false : timerUI.title_on = true; } else { console.warn(timerUI.msg.notimer); timeUI(); } }; timerUI.getTitle = function() { timerUI.domainRules(); if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; else { // skipping this whole part if no custom title is specified timerUI.newTitle = document.title; timerUI.titleDomainRules(); } timerUI.updateFileIcon(); return timerUI.fileIcon+" "+timerUI.newTitle; } timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.toString().search(/^\/video\//) > -1) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected } timerUI.updateFileIcon = function() { timerUI.fileIcon = timerUI.guessMediaType(); switch(timerUI.fileIcon) { case "video": timerUI.fileIcon = "🎞️"; break; case "audio": timerUI.fileIcon = "♫"; break; case "unknown": timerUI.fileIcon = "📄"; break; } } timerUI.adaptTitleWidth = function() { if (media_element.duration > 3600 && timerUI.show_remaining == 2 && window.innerWidth > timerUI.width_breakpoint) timerUI.title.style.maxWidth = "calc(100% - 670px)"; else timerUI.title.style.maxWidth = "calc(100% - 400px)"; } window.addEventListener('resize', function() { if (window.innerWidth < timerUI.width_breakpoint) timerUI.title.removeAttribute("style"); } ); timerUI.update = function() { if (media_element) { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" @@ -215,19 +311,28 @@ timerUI.update = function() { media_element.paused == false ? timerUI.status.innerHTML=symbol_play : timerUI.status.innerHTML=symbol_pause; } else { timerUI.stop(); console.warn(timerUI.msg.nomedia) } }; timerUI.updateTitle = function() { if (timerUI.title) timerUI.title.innerHTML = timerUI.getTitle(); } // update title on URL change addEventListener('popstate', timerUI.updateTitle); // update title fallback timerUI.interval.updateTitle = setInterval(timerUI.updateTitle, 2000); timerUI.updateBufferSegment = function() { if (media_element) { // find out first buffer segment after current playback position media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if ( timerUI.buffer_on && timerUI.buffer_segment > 0) { while (media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 1 ) { timerUI.buffer_segment-- ; } } } }; timerUI.setColor = function(newColor) { @@ -239,46 +344,48 @@ timerUI.setColor = function(newColor) { // (deprecated due to new buffer bar) timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; }; timerUI.setGradient = function(newGradient) { newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.9)" : timerUI.gradient = newGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; }; timerUI.setFont = function(newFont) { timerUI.time.style.fontFamily=newFont; timerUI.title.style.fontFamily=newFont; }; timerUI.stop = function() { timerUI.status.innerHTML="■"; timerUI.bar.style.width=0; timerUI.buffer_bar.style.width=0; timerUI.time.innerHTML=HMStimer(undefined); }; // Additional checks to ensure the player is detected window.onclick = function() { checkMediaType();timeUI(); }; window.addEventListener("keydown", function() { checkMediaType();timeUI(); } ); function timeUI() { // slightly different name to prevent naming collision with timerUI object checkMediaType(); timerUI.domainRules(); // load domain rules // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists ) { // Adding elements // parent element appendChildWithID("div","timerUI"); timerUI.div = document.getElementById("timerUI"); // button styling addStyle("#timerUI button { background:none; border:none; outline:none; line-height:unset; } #timerUI button:hover { filter: brightness(1.2); } #timerUI button:active { filter: brightness(0.6); }", timerUI.div); // to suppress button background and border on earlier browser versions timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector // background gradient @@ -296,11 +403,17 @@ function timeUI() { timerUI.buffer_bar = document.getElementById("bufferBar"); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div); // media title appendChildWithID("div","mediaTitle",timerUI.div ); timerUI.title = document.getElementById("mediaTitle"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #mediaTitle { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;") // timer appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #playTimer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #playTimer .timer_linefeed { display:none; }", timerUI.div); // play/pause symbol appendChildWithID("button","playStatus",timerUI.div ); @@ -311,24 +424,23 @@ function timeUI() { // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); addStyle("#timerUI #progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #playTimer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #playStatus { bottom:10pt; } } @media (max-width:500px) { #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #mediaTitle { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #mediaTitle { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); // update timer during playback every fifteenth of a second and while mouse is dragging progress bar timerUI.interval.update = setInterval( function() { if ( ( media_element /* exists? */ && timerUI.update_during_seek && mousedown_status ) || ( media_element && timerUI.on && ! media_element.paused ) ) timerUI.update(); }, 1000/15 ); // Longer interval for buffer bar to minimize CPU usage timerUI.interval.buffer = setInterval(timerUI.updateBufferSegment, 1000); // play and pause toggle @@ -339,16 +451,18 @@ function timeUI() { timerUI.time.onclick = function() { switch(timerUI.show_remaining) { case 0: timerUI.show_remaining = 1; break; case 1: timerUI.show_remaining = 2; timerUI.adaptTitleWidth(); break; case 2: timerUI.show_remaining = 0; timerUI.adaptTitleWidth(); break; } timerUI.update(); }; // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; } } function dragSeekBar(m){ // currently unused m = m || window.event; @@ -359,7 +473,7 @@ function timeUI() { if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); } timerUI.bar_placeholder.addEventListener("mousedown", timerUI.clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); @@ -372,19 +486,59 @@ function timeUI() { window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } ); // prevent detaching from player on sites with playlists such as Internet Archive timerUI.interval.checkMedia = setInterval( checkMediaType,1000 ); // prevent indicating "▶" after playback finished timerUI.interval.checkPaused = setInterval( function() { if ( media_element /* exists? */ && media_element.paused && ! timerUI.pause_checked) { timerUI.update(); timerUI.pause_checked = true; if (timerUI.debug_mode) console.debug("timerUI: checking paused status: "+media_element.paused); } else if ( media_element && ! media_element.paused ) { timerUI.pause_checked = false; } // to avoid redundant checks while paused },1000 ); } else { // warn in console that no player exists; prevent repetition if (! playerExists && ! timerUI.noMediaWarned) { console.warn(timerUI.msg.nomedia); timerUI.noMediaWarned = true; } } } // == Custom domain rules == timerUI.domainRules = function() { if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); customTitleElement = document.getElementById("media-title"); // for unlisted } }; timerUI.titleDomainRules = function() { // custom domain rules for title if ( isDomain("youtube.com") || isDomain("dailymotion.com") || isDomain("wikimedia.org") || isDomain("wikipedia.org") || isDomain("wikiversity.org") || isDomain("wikibooks.org") || isDomain("mediawiki.org") ) { // negative lookahead regular expression – trim after last dash // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); } // remove "File:" prefix on wikis if ( isDomain("wiki") ) { if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); } if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { timerUI.newTitle = (document.location.toString()+"").substring((document.location.toString()+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) if (timerUI.newTitle != "") { timerUI.newTitle += " - " }; timerUI.newTitle += document.title.toString().substring(0,document.title.toString().search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); // trim after second-last colon, -1 to remove space at end } }; // == Master function == timeUI(); -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 19 additions and 17 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -33,9 +33,8 @@ function customMediaElement(custom_media_element) { } // symbols var symbol_play = "▶︎ "; // thin space for alignment var symbol_pause="❚ ❚"; // instead of "⏸" due to Edge browser putting an immutable blue box around it. // mousedown status var mousedown_status; @@ -225,7 +224,7 @@ timerUI.updateBufferSegment = function() { // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if (timerUI.buffer_on && timerUI.buffer_segment > 0) { while ( media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 0 ) { timerUI.buffer_segment-- ; } } @@ -279,7 +278,7 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); // button styling addStyle("#timerUI button { background:unset; border:unset; outline:unset; line-height:unset; }", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector // background gradient @@ -301,7 +300,7 @@ function timeUI() { appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #playTimer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; } #playTimer .timer_linefeed { display:none; }", timerUI.div); // play/pause symbol appendChildWithID("button","playStatus",timerUI.div ); @@ -315,7 +314,7 @@ function timeUI() { addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:768px) { #timerUI #playTimer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #playStatus { bottom:10pt; } } @media (max-width:500px) { #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash { display:none; } }", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); @@ -368,21 +367,24 @@ function timeUI() { // == Patches == // prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUI.update, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } ); // prevent detaching from player on sites with playlists such as Internet Archive timerUI.checkMediaInterval = setInterval( checkMediaType,1000 ); // prevent indicating "▶" after playback finished timerUI.checkPausedInterval = setInterval( function() { if (media_element.paused && ! timerUI.pause_checked) { timerUI.update(); timerUI.pause_checked = true; } else { timerUI.pause_checked = false; } },1000 ); } else { // warn in console that no player exists; prevent repetition if (! playerExists && ! timerUI.noMediaWarned) { console.warn("timerUI: no media element found on page."); timerUI.noMediaWarned = true; } } } -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 8 additions and 3 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -32,6 +32,11 @@ function customMediaElement(custom_media_element) { } else { console.error("timerUI: No such media element found."); } } // symbols var symbol_play = "▶︎"; var symbol_pause = "⏸︎"; // "︎" is necessary to prevent the symbols from being rendered as clip art icons bundled by vendors of browsers and devices. // mousedown status var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true; } ); @@ -209,8 +214,8 @@ timerUI.update = function() { } media_element.paused == false ? timerUI.status.innerHTML=symbol_play : timerUI.status.innerHTML=symbol_pause; }; @@ -372,7 +377,7 @@ function timeUI() { // prevent indicating "▶" after playback finished timerUI.checkPaused = setInterval( function() { if (media_element.paused && timerUI.status.innerHTML!=symbol_pause) timerUI.update(); },1000 ); } else { // warn in console that no player exists; prevent repetition -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 40 additions and 4 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -144,7 +144,7 @@ if (! timerUI) var timerUI = new Object({}); // create parent object if none exi timerUI.toggle = function() { if (timerUI.div) { timerUI.update(); if (timerUI.on) { timerUI.div.style.display = "none"; console.log("timerUI off"); } @@ -159,14 +159,32 @@ timerUI.toggle = function() { } }; timerUI.toggleBuffer = function() { if (timerUI.div) { timerUI.update(); if (timerUI.buffer_on) { timerUI.buffer_bar.style.display = "none"; console.log("timerUI buffer bar off"); } if (! timerUI.buffer_on ) { timerUI.buffer_bar.style.display = "block"; console.log("timerUI buffer bar on"); } timerUI.buffer_on ? timerUI.buffer_on = false : timerUI.buffer_on = true; } else { console.warn("timerUI: No timer found; checking for media element again. Please try again."); timeUI(); } }; var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; timerUI.update = function() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" timerUI.buffer_bar.style.width=media_element.buffered.end(timerUI.buffer_segment) / media_element.duration * 100 + "%"; } else { timerUI.buffer_bar.style.width="0%"; } switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" @@ -195,6 +213,19 @@ timerUI.update = function() { : timerUI.status.innerHTML="⏸"; }; timerUI.updateBufferSegment = function() { // find out first buffer segment after current playback position media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if (timerUI.buffer_on && timerUI.buffer_segment > 0) { while ( media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime ) { timerUI.buffer_segment-- ; } } }; timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; @@ -229,6 +260,7 @@ function timeUI() { // Declaring variables timerUI.on = true; timerUI.buffer_on = true; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar @@ -258,7 +290,7 @@ function timeUI() { // buffer bar appendChildWithID("div","bufferBar",timerUI.div ); timerUI.buffer_bar = document.getElementById("bufferBar"); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div); // timer appendChildWithID("button","playTimer",timerUI.div ); @@ -291,6 +323,10 @@ function timeUI() { }, 1000/15 ); // Longer interval for buffer bar to minimize CPU usage timerUI.updateBufferInterval = setInterval(timerUI.updateBufferSegment, 1000); // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 11 additions and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -163,6 +163,10 @@ var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; timerUI.update = function() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" timerUI.buffer_bar.style.width=media_element.buffered.end(media_element.buffered.length-1) / media_element.duration * 100 + "%"; } switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" @@ -195,8 +199,9 @@ timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.buffer_bar.style.backgroundColor=timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; // (deprecated due to new buffer bar) timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; }; @@ -250,6 +255,11 @@ function timeUI() { timerUI.bar = document.getElementById("progBar"); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div); // buffer bar appendChildWithID("div","bufferBar",timerUI.div ); timerUI.buffer_bar = document.getElementById("bufferBar"); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div); // timer appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 46 additions and 41 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -5,11 +5,11 @@ var mediaType; // for compatibility var playerExists = false; // is set to true below if player exists var checkMediaType_enabled = true; // for debugging purposes var media_element = {}; // declaring as object function checkMediaType() { // checks whether it is a video or an audio tag if ( checkMediaType_enabled ) { var mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } @@ -18,7 +18,7 @@ function checkMediaType() { // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; // Set back to false if no player is found after using customMediaElement. media_element ? playerExists=true : playerExists=false; } } @@ -28,14 +28,10 @@ function customMediaElement(custom_media_element) { if (custom_media_element) { playerExists = true; media_element = custom_media_element; console.log("timerUI: Custom media element set. Reset using checkMediaType_enabled=true."); } else { console.error("timerUI: No such media element found."); } } // mousedown status var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true; } ); @@ -137,35 +133,35 @@ function isDomain(domain) { if (window.location.hostname.search(domain) >= 0) return true; else return false; } if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); } // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists timerUI.toggle = function() { if (timerUI.div) { timerUI.update(); if (timerUI.on ) { timerUI.div.style.display = "none"; console.log("timerUI off"); } if (! timerUI.on ) { timerUI.div.style.display = "block"; console.log("timerUI on"); } timerUI.on ? timerUI.on = false : timerUI.on = true; } else { console.warn("timerUI: No timer found; checking for media element again. Please try again."); timeUI(); } }; var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; timerUI.update = function() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; switch(timerUI.show_remaining) { @@ -193,34 +189,38 @@ function timerUpdate() { media_element.paused == false ? timerUI.status.innerHTML="▶" : timerUI.status.innerHTML="⏸"; }; timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; }; timerUI.setGradient = function(newGradient) { newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.7)" : timerUI.gradient = newGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; }; timerUI.setFont = function(newFont) { timerUI.time.style.fontFamily=newFont; }; // Additional checks to ensure the player is detected window.onclick = function() { checkMediaType();timeUI(); }; window.addEventListener("keydown", function() { checkMediaType();timeUI(); } ); timeUI(); // slightly different name to prevent naming collision with timerUI object function timeUI() { checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists ) { // Declaring variables timerUI.on = true; @@ -277,12 +277,12 @@ function timeUI() { function() { if ( ( timerUI.update_during_seek && mousedown_status ) || ( timerUI.on && ! media_element.paused ) ) timerUI.update(); }, 1000/15 ); // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // toggle between elapsed, remaining, and elapsed/total time @@ -292,41 +292,46 @@ function timeUI() { case 1: timerUI.show_remaining = 2; break; case 2: timerUI.show_remaining = 0; break; } timerUI.update(); }; // clickable progress bar (experimental) - no "timerUI." notation because inside main function function clickSeekBar(m){ var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; } function dragSeekBar(m){ // currently unused m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var dragSeekBarInterval = setInterval( function() { media_element.currentTime = media_element.duration * clickPos; timerUI.update(); if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); } timerUI.bar_placeholder.addEventListener("mousedown", clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); timerUI.update(); // == Patches == // prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUI.update, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } ); // prevent detaching from player on sites with playlists such as Internet Archive timerUI.checkMediaInterval = setInterval( checkMediaType,1000 ); // prevent indicating "▶" after playback finished timerUI.checkPaused = setInterval( function() { if (media_element.paused && timerUI.status.innerHTML!="⏸") timerUI.update(); },1000 ); } else { // warn in console that no player exists; prevent repetition if (! playerExists && ! timerUI.noMediaWarned) { console.warn("timerUI: no media element found on page."); timerUI.noMediaWarned = true; } } } -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -173,8 +173,8 @@ function timerUpdate() { case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element.duration) ) { // show hours if duration exceeds one hour timerUI.time.innerHTML= MStimer(media_element.currentTime) + timer_linefeed -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 6 additions and 5 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -158,7 +158,7 @@ function timerToggle() { } timerUI.on == false ? timerUI.on = true : timerUI.on = false; } else { console.warn("timerUI: No timer found; checking for media element again. Please try again."); timeUI(); } } @@ -173,8 +173,8 @@ function timerUpdate() { case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 6000 || isNaN(media_element.duration) ) { // show hours if duration exceeds 100 minutes timerUI.time.innerHTML= MStimer(media_element.currentTime) + timer_linefeed @@ -199,6 +199,7 @@ function timerColor(setColor) { setColor == "default" ? timerUI.color="rgb(49,136,255)" : timerUI.color = setColor; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; @@ -247,7 +248,7 @@ function timeUI() { // progress bar appendChildWithID("div","progBar",timerUI.div ); timerUI.bar = document.getElementById("progBar"); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div); // timer appendChildWithID("button","playTimer",timerUI.div ); @@ -284,7 +285,7 @@ function timeUI() { timerUI.status.onclick = function() { togglePlay(media_element); timerUpdate(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // toggle between elapsed, remaining, and elapsed/total time timerUI.time.onclick = function() { switch(timerUI.show_remaining) { case 0: timerUI.show_remaining = 1; break; -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 30 additions and 25 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -3,31 +3,32 @@ // == Dependencies == var mediaType; // for compatibility var playerExists = false; // is set to true below if player exists var checkMediaType_enabled = true; // for debugging purposes var media_element = {}; function checkMediaType() { if ( checkMediaType_enabled == true ) { // checks whether it is a video or an audio tag var mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } var mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; // Set back to 0 if no player is found after using customMediaElement. media_element ? playerExists=true : playerExists=false; } } function customMediaElement(custom_media_element) { checkMediaType_enabled = false; if (custom_media_element) { playerExists = true; media_element = custom_media_element; console.log("Custom media element set. Reset using checkMediaType_enabled=true."); } else { console.error("No such media element found."); } } @@ -37,8 +38,8 @@ window.addEventListener("keydown", function() { checkMediaType();timeUI(); } ); // mousedown status var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true; } ); window.addEventListener("mouseup", function(){mousedown_status=false; } ); function appendChildWithID(tagName,tagID,parent_element) { // default parent element to document.body if unspecified @@ -53,6 +54,10 @@ function addStyle(new_style,parent_element) { parent_element.lastElementChild.innerHTML = new_style; } // time variables var time_HH = 0; var time_MM = 0; var time_SS = 0; // HH:MM:SS timer function HMStimer_core(seconds) { @@ -143,15 +148,15 @@ if (! timerUI) var timerUI = new Object({}); // create parent object if none exi function timerToggle() { if (timerUI.div) { timerUpdate(); if (timerUI.on == true) { timerUI.div.style.display = "none"; console.log("timerUI off"); } if (timerUI.on == false) { timerUI.div.style.display = "block"; console.log("timerUI on"); } timerUI.on == false ? timerUI.on = true : timerUI.on = false; } else { console.log("No timer found; checking for media element again. Please try again."); timeUI(); @@ -185,7 +190,7 @@ function timerUpdate() { break; } media_element.paused == false ? timerUI.status.innerHTML="▶" : timerUI.status.innerHTML="⏸"; } @@ -214,13 +219,13 @@ function timeUI() { checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == true ) { // Declaring variables timerUI.on = true; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.7)"; // using RGBA instead of hexadecimal for compatibility. @@ -231,7 +236,7 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); // button styling addStyle("#timerUI button \{ background:unset; border:unset; outline:unset; line-height:unset; \}", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector // background gradient @@ -259,10 +264,10 @@ function timeUI() { // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:768px) \{ #timerUI #playTimer \{ font-size:30pt; line-height:24pt; bottom:15pt; \} #timerUI #playStatus \{ bottom:10pt; \} \} @media (max-width:500px) \{ #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash \{ display:none; \} \}", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); @@ -285,7 +290,7 @@ function timeUI() { case 0: timerUI.show_remaining = 1; break; case 1: timerUI.show_remaining = 2; break; case 2: timerUI.show_remaining = 0; break; } timerUpdate(); }; -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -222,7 +222,7 @@ function timeUI() { timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = 1; // 1: update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.7)"; // using RGBA instead of hexadecimal for compatibility. // Adding elements -
HT-7 revised this gist
on May 18, 2022May 18, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -254,7 +254,7 @@ function timeUI() { appendChildWithID("button","playStatus",timerUI.div ); timerUI.status = document.getElementById("playStatus"); timerUI.status.innerHTML="■"; addStyle("#timerUI #playStatus { display:block; position:fixed; cursor:pointer; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div); // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); -
HT-7 revised this gist
on May 18, 2022May 18, 2022 . 1 changed file with 233 additions and 192 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -7,28 +7,28 @@ var playerExists = 0; // is set to 1 below if player exists var checkMediaType_enabled = 1; // for debugging purposes function checkMediaType() { if ( checkMediaType_enabled == 1 ) { // checks whether it is a video or an audio tag mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = 1; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = 1; mediaType = "audio"; } mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; // Set back to 0 if no player is found after using customMediaElement. media_element ? playerExists=1 : playerExists=0; } } function customMediaElement(custom_media_element) { checkMediaType_enabled = 0; if (custom_media_element) { playerExists = 1; media_element = custom_media_element; console.log("Custom media element set. Reset using checkMediaType_enabled=1."); } else { console.error("No such media element found."); } } // Additional checks to ensure the player is detected @@ -41,75 +41,75 @@ window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mouseup", function(){mousedown_status=false} ); function appendChildWithID(tagName,tagID,parent_element) { // default parent element to document.body if unspecified if (parent_element === undefined) parent_element = document.body; parent_element.appendChild(document.createElement(tagName)); // add div parent_element.lastElementChild.id=tagID; // give it ID } function addStyle(new_style,parent_element) { if (parent_element === undefined) parent_element = document.body; parent_element.appendChild(document.createElement("style")); // add style parent_element.lastElementChild.innerHTML = new_style; } // HH:MM:SS timer function HMStimer_core(seconds) { // hours time_HH = Math.floor( seconds/3600 ); // leading zero if ( seconds < 36000 ) time_HH = "0" + time_HH; // minutes time_MM = Math.floor( seconds/60%60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM; // seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS; return time_HH+":"+time_MM+":"+time_SS; } function HMStimer(seconds) { if (seconds >= 0) return HMStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+HMStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –:– –"; } // MM:SS timer function MStimer_core(seconds) { // minutes time_MM = Math.floor( seconds/60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM; // seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS; return time_MM+":"+time_SS; } function MStimer(seconds) { if (seconds >= 0) return MStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+MStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –"; } @@ -123,163 +123,204 @@ Object.prototype.togglePlay = function togglePlay() { // new function without object prototype for compatibility function togglePlay(media_element) { media_element.paused ? media_element.play() : media_element.pause(); } // == Custom domain rules == function isDomain(domain) { // Using .search() instead of .includes() to improve browser compatibility. if (window.location.hostname.search(domain) >= 0) return true; else return false; } if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//)==(-1) ) // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists function timerToggle() { if (timerUI.div) { timerUpdate(); if (timerUI.on == 1) { timerUI.div.style.display = "none"; console.log("timerUI off"); } if (timerUI.on == 0) { timerUI.div.style.display = "block"; console.log("timerUI on"); } timerUI.on == 0 ? timerUI.on = 1 : timerUI.on = 0; } else { console.log("No timer found; checking for media element again. Please try again."); timeUI(); } } var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; function timerUpdate() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element.duration) ) { // show hours if duration exceeds one hour timerUI.time.innerHTML= MStimer(media_element.currentTime) + timer_linefeed + timer_slash + MStimer(media_element.duration); } else { timerUI.time.innerHTML= HMStimer(media_element.currentTime) + timer_linefeed + timer_slash + HMStimer(media_element.duration); } break; } media_element.paused == 0 ? timerUI.status.innerHTML="▶" : timerUI.status.innerHTML="⏸"; } function timerColor(setColor) { setColor == "default" ? timerUI.color="rgb(49,136,255)" : timerUI.color = setColor; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; } function timerGradient(setGradient) { setGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.7)" : timerUI.gradient = setGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; } function timerFont(setFont) { timerUI.time.style.fontFamily=setFont; } timeUI(); function timeUI() { checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) { // Declaring variables timerUI.on = 1; timerUI.div; // unset yet, declaring to prevent reference errors timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = 1; // 1: update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgb(0,0,0,0.7)"; // #38F – using RGB for compatibility. // Adding elements // parent element appendChildWithID("div","timerUI"); timerUI.div = document.getElementById("timerUI"); // button styling addStyle("#timerUI button \{ background:unset; border:unset; outline:unset; line-height:unset; \}", timerUI.div) timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector // background gradient appendChildWithID("div","bottomGradient",timerUI.div ); timerUI.gradient_placeholder = document.getElementById("bottomGradient"); addStyle("#timerUI #bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; bottom:0; pointer-events:none; }", timerUI.div); // progress bar appendChildWithID("div","progBar",timerUI.div ); timerUI.bar = document.getElementById("progBar"); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div); // timer appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #playTimer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; line-height:60pt; bottom:10pt; right:25pt; text-align:right; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; } #playTimer .timer_linefeed { display:none; }", timerUI.div); // play/pause symbol appendChildWithID("button","playStatus",timerUI.div ); timerUI.status = document.getElementById("playStatus"); timerUI.status.innerHTML="■"; addStyle("#timerUI #playStatus { display:block; position:fixed; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div); // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div) // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:768px) \{ #timerUI #playTimer \{ font-size:30pt; line-height:24pt; bottom:15pt; \} #timerUI #playStatus \{ bottom:10pt; \} \} @media (max-width:500px) \{ #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash \{ display:none; \} \}", timerUI.div) timerUI.div.lastElementChild.classList.add("timerUI_responsive"); // update timer during playback every fifteenth of a second and while mouse is dragging progress bar timerUI.updateInterval = setInterval( function() { if ( ( timerUI.update_during_seek && mousedown_status ) || ( timerUI.on && ! media_element.paused ) ) timerUpdate(); }, 1000/15 ); // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUpdate(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // toggle between elapsed and remaining time timerUI.time.onclick = function() { switch(timerUI.show_remaining) { case 0: timerUI.show_remaining = 1; break; case 1: timerUI.show_remaining = 2; break; case 2: timerUI.show_remaining = 0; break; }; timerUpdate(); }; // clickable progress bar (experimental) function clickSeekBar(m){ var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; } function dragSeekBar(m){ m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var dragSeekBarInterval = setInterval( function() { media_element.currentTime = media_element.duration * clickPos; timerUpdate(); if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); } timerUI.bar_placeholder.addEventListener("mousedown", clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); timerUpdate(); // == Patches == // prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUpdate, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUpdate, 200); } ); // prevent detaching from player on sites with playlists such as Internet Archive timerUI.checkMediaInterval = setInterval( checkMediaType,1000 ); // prevent indicating "▶" after playback finished timerUI.checkPaused = setInterval( function() { if (media_element.paused && timerUI.status.innerHTML!="⏸") timerUpdate(); },1000 ); } } -
HT-7 revised this gist
on May 15, 2022May 15, 2022 . 1 changed file with 48 additions and 29 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -141,14 +141,21 @@ if (isDomain("dailymotion.com") && document.location.pathname.toString().search( var timerUI_on = 1; var timerUI_id; // unset yet, declaring to prevent reference errors var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. function timerToggle() { if (timerUI_id) { timerUpdate(); if (timerUI_on == 1) { timerUI_id.style.display = "none"; console.log("timerUI off"); } if (timerUI_on == 0) { timerUI_id.style.display = "block"; console.log("timerUI on"); } timerUI_on == 0 ? timerUI_on = 1 : timerUI_on = 0; } else { console.log("No timer found; checking for media element again. Please try again.") @@ -181,12 +188,13 @@ function timerUpdate() { } function timerColor(setColor) { setColor == "default" ? timeUI_color="rgb(49,136,255)" : timeUI_color = setColor; document.getElementById("progBar").style.backgroundColor=timeUI_color; document.getElementById("progBarPlaceholder").style.backgroundColor=timeUI_color; document.getElementById("playTimer").style.color=timeUI_color; document.getElementById("playStatus").style.color=timeUI_color; document.getElementById("bottomGradient").style.backgroundImage="linear-gradient(to top,"+timeUI_color+", rgba(0,0,0,0) )"; } function timerFont(setFont) { @@ -207,31 +215,34 @@ function timeUI() { // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) { // Adding elements // parent element appendChildWithID("div","timerUI"); var timerUI_id = document.getElementById("timerUI"); // background gradient appendChildWithID("div","bottomGradient",timerUI_id ); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }"); // progress bar appendChildWithID("div","progBar",timerUI_id ); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }"); // timer appendChildWithID("div","playTimer",timerUI_id ); document.getElementById("playTimer").innerHTML="00:00:00"; addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }"); // play/pause symbol appendChildWithID("div","playStatus",timerUI_id ); document.getElementById("playStatus").innerHTML="■"; addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }"); // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI_id ); addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }") // update timer during playback every fifteenth of a second and while mouse is dragging progress bar var timerUpdateInterval = setInterval( @@ -261,6 +272,14 @@ function timeUI() { timerUpdate(); }; // clickable progress bar (experimental) function clickSeekBar(m){ var clickPos = m.clientX / document.getElementById("progBarPlaceholder").offsetWidth; media_element.currentTime = media_element.duration * clickPos; } document.getElementById("progBarPlaceholder").addEventListener("mousedown", clickSeekBar ); document.getElementById("progBarPlaceholder").addEventListener("mouseup", clickSeekBar ); timerUpdate(); } } -
HT-7 revised this gist
on May 15, 2022May 15, 2022 . 1 changed file with 53 additions and 30 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -40,14 +40,17 @@ var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mouseup", function(){mousedown_status=false} ); function appendChildWithID(tagName,tagID,parent_element) { // default parent element to document.body if unspecified if (parent_element === undefined) var parent_element = document.body; parent_element.appendChild(document.createElement(tagName)); // add div parent_element.lastElementChild.id=tagID; // give it ID } function addStyle(new_style,parent_element) { if (parent_element === undefined) var parent_element = document.body; parent_element.appendChild(document.createElement("style")); // add style parent_element.lastElementChild.innerHTML = new_style; } @@ -136,30 +139,45 @@ if (isDomain("dailymotion.com") && document.location.pathname.toString().search( // == Main code == var timerUI_on = 1; var timerUI_id; // unset yet, declaring to prevent reference errors var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show both. var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. function timerToggle() { if (timerUI_id) { if (timerUI_on == 1) timerUI_id.style.display = "none"; if (timerUI_on == 0) timerUI_id.style.display = "block"; timerUpdate(); timerUI_on == 0 ? timerUI_on = 1 : timerUI_on = 0; } else { console.log("No timer found; checking for media element again. Please try again.") timeUI(); } } function timerUpdate() { if (timerUI_on == 1) { document.getElementById("progBar").style.width=media_element.currentTime / media_element.duration * 100 + "%"; switch(show_remaining_time) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" case 0: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime); break; case 1: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element) ) { // show hours if duration exceeds one hour document.getElementById("playTimer").innerHTML=MStimer(media_element.currentTime)+" / "+MStimer(media_element.duration); } else { document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime)+" / "+HMStimer(media_element.duration); } break; } media_element.paused == 0 ? document.getElementById("playStatus").innerHTML="▶" : document.getElementById("playStatus").innerHTML="⏸"; } } function timerColor(setColor) { @@ -181,32 +199,37 @@ window.addEventListener("keyup", function() { setTimeout(timerUpdate, 200); } ); timeUI(); var timerUI_id = document.getElementById("timerUI"); function timeUI() { checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) { // parent element appendChildWithID("div","timerUI"); var timerUI_id = document.getElementById("timerUI"); // background gradient appendChildWithID("div","bottomGradient",timerUI_id ); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }"); // progress bar appendChildWithID("div","progBar",timerUI_id ); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }"); // progress bar placeholder appendChildWithID("div","progBarPlaceholder",timerUI_id ); addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }") // timer appendChildWithID("div","playTimer",timerUI_id ); document.getElementById("playTimer").innerHTML="00:00:00"; addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }"); // play/pause symbol appendChildWithID("div","playStatus",timerUI_id ); document.getElementById("playStatus").innerHTML="■"; addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }"); -
HT-7 created this gist
on May 14, 2022May 14, 2022 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,243 @@ // TimerUI // == Dependencies == var mediaType; // for compatibility var playerExists = 0; // is set to 1 below if player exists var checkMediaType_enabled = 1; // for debugging purposes function checkMediaType() { if ( checkMediaType_enabled == 1 ) { // checks whether it is a video or an audio tag mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = 1; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = 1; mediaType = "audio"; } mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; // Set back to 0 if no player is found after using customMediaElement. media_element ? playerExists=1 : playerExists=0; } } function customMediaElement(custom_media_element) { checkMediaType_enabled = 0; if (custom_media_element) { playerExists = 1; media_element = custom_media_element; console.log("Custom media element set. Reset using checkMediaType_enabled=1."); } else { console.error("No such media element found."); } } // Additional checks to ensure the player is detected window.onclick = function() { checkMediaType();timeUI(); }; window.addEventListener("keydown", function() { checkMediaType();timeUI(); } ); // mousedown status var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mouseup", function(){mousedown_status=false} ); function appendChildWithID(tagName,tagID) { document.body.appendChild(document.createElement(tagName)); // add div document.body.lastElementChild.id=tagID; // give it ID } function addStyle(new_style) { document.body.appendChild(document.createElement("style")); // add style document.body.lastElementChild.innerHTML = new_style; } // HH:MM:SS timer function HMStimer_core(seconds) { // hours time_HH = Math.floor( seconds/3600 ); // leading zero if ( seconds < 36000 ) time_HH = "0" + time_HH; // minutes time_MM = Math.floor( seconds/60%60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM; // seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS; return time_HH+":"+time_MM+":"+time_SS; } function HMStimer(seconds) { if (seconds >= 0) return HMStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+HMStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –:– –"; } // MM:SS timer function MStimer_core(seconds) { // minutes time_MM = Math.floor( seconds/60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM; // seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS; return time_MM+":"+time_SS; } function MStimer(seconds) { if (seconds >= 0) return MStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+MStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –"; } // implements togglePlay(); – deprecated due to compatibility issues on YouTube (broken site) and Dailymotion ("not a function" error through iframe'd player). /* Object.prototype.togglePlay = function togglePlay() { return this.paused ? this.play() : this.pause(); }; */ // new function without object prototype for compatibility function togglePlay(media_element) { media_element.paused ? media_element.play() : media_element.pause(); } // == Custom domain rules == function isDomain(domain) { // Using .search() instead of .includes() to improve browser compatibility. if (window.location.hostname.search(domain) >= 0) return true; else return false; } if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//)==(-1) ) // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); // == Main code == var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show both. var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. function timerUpdate() { document.getElementById("progBar").style.width=media_element.currentTime / media_element.duration * 100 + "%"; switch(show_remaining_time) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" case 0: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime); break; case 1: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element) ) { // show hours if duration exceeds one hour document.getElementById("playTimer").innerHTML=MStimer(media_element.currentTime)+" / "+MStimer(media_element.duration); } else { document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime)+" / "+HMStimer(media_element.duration); } break; } media_element.paused == 0 ? document.getElementById("playStatus").innerHTML="▶" : document.getElementById("playStatus").innerHTML="⏸"; } function timerColor(setColor) { timeUI_color = setColor; // for debugging document.getElementById("progBar").style.backgroundColor=setColor; document.getElementById("progBarPlaceholder").style.backgroundColor=setColor; document.getElementById("playTimer").style.color=setColor; document.getElementById("playStatus").style.color=setColor; document.getElementById("bottomGradient").style.backgroundImage="linear-gradient(to top,"+setColor+", rgba(0,0,0,0) )"; } function timerFont(setFont) { document.getElementById("playTimer").style.fontFamily=setFont; } // patch: prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUpdate, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUpdate, 200); } ); timeUI(); function timeUI() { checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("progBar") ) && playerExists == 1 ) { // background gradient appendChildWithID("div","bottomGradient"); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }"); // progress bar appendChildWithID("div","progBar"); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }"); // progress bar placeholder appendChildWithID("div","progBarPlaceholder"); addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }") // timer appendChildWithID("div","playTimer"); document.getElementById("playTimer").innerHTML="00:00:00"; addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }"); // play/pause symbol appendChildWithID("div","playStatus"); document.getElementById("playStatus").innerHTML="■"; addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }"); // update timer during playback every fifteenth of a second and while mouse is dragging progress bar var timerUpdateInterval = setInterval( function() { if ( ( timer_update_during_seek && mousedown_status ) || ! media_element.paused) timerUpdate(); } , 1000/15 ); // patch: prevent detaching from player on sites with playlists such as Internet Archive var checkMediaInterval = setInterval( checkMediaType,1000 ); // patch: prevent showing "▶" after playback finished var checkPaused = setInterval( function() { if (media_element.paused && document.getElementById("playStatus").innerHTML!="⏸") timerUpdate(); },1000 ); // play and pause toggle document.getElementById("playStatus").onclick = function() { togglePlay(media_element); timerUpdate(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // toggle between elapsed and remaining time document.getElementById("playTimer").onclick = function() { switch(show_remaining_time) { case 0: show_remaining_time = 1; break; case 1: show_remaining_time = 2; break; case 2: show_remaining_time = 0; break; }; timerUpdate(); }; timerUpdate(); } }