diff --git a/README.md b/README.md index c0fdacd..429220a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Better YouTube + works to improve the YouTube experience by providing quick acce
* It allows quick thumbnail access of the video. * It allows setting the loop mode easily. + * It allows setting the loop mode to a ranged set. * It allows the video to be toggled to fixed or floating with drag functionality. * It allows volume control through the mouse-wheel when hovering over the player. * It allows for quick access to the YouTube video slug. @@ -11,5 +12,7 @@ Better YouTube + works to improve the YouTube experience by providing quick acce # Download https://addons.mozilla.org/en-US/firefox/addon/better-youtube-plus/ -# Version: 1.3.0 -Fixed video player in full-screen being behind controls. +# Version: 1.3.5 +Added ranged loop feature. +Fixed finally floating video issues. +Removed non-working image onerror signals. diff --git a/src/manifest.json b/src/manifest.json index f8858c9..32e5c25 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Better Youtube +", - "version": "1.3.0", + "version": "1.3.5", "description": "Enhancements for Youtube to have a better experience.", "applications": { diff --git a/src/scripts/betterYoutube.js b/src/scripts/betterYoutube.js index 7c20fce..100fa96 100644 --- a/src/scripts/betterYoutube.js +++ b/src/scripts/betterYoutube.js @@ -1,4 +1,4 @@ -const betterYoutubePlus = () => { +(function() { // Declare variables let slugInputTag, ytThumbImgMenu, ytEnhancerMenu; // Menu systems @@ -7,24 +7,39 @@ const betterYoutubePlus = () => { let mastHead, mainContentArea, playerWindow; // Youtube Player container let video, containerOfPlyrWndow, poppedContainer; // Video accessor - let vdoPlyrAtts; // Player attributes let part, videoSlug, temp; // Image part + let videoTimeLength, videoTimeCurent, ytRangeStart, ytRangeEnd, + ytdVideoIntervalLoop; + let loopingInterval = false; let count = 0; const preSetupProc = () => { video = document.getElementsByTagName("video")[0]; // Video Controler slugInputTag = document.createElement("INPUT"); + ytRangeEnd = document.createElement("INPUT"); + slugInputTag.id = "slugCopyZone"; + ytRangeEnd.id = "rangeEndID"; slugInputTag.type = "text"; + ytRangeEnd.type = "text"; + + // We need to wait for info to load before getting full duration + setTimeout(function () { + videoTimeLength = document.getElementsByClassName("ytp-time-duration")[0].innerHTML; + if (!document.getElementById("rangeEndID")) { + } else { + ytRangeEnd = document.getElementById("rangeEndID"); + } + ytRangeEnd.value = videoTimeLength; + }, 1000); if (!document.getElementById("slugCopyZone")) { document.body.appendChild(slugInputTag); } else { - slugInputTag = document.getElementById("slugCopyZone"); + slugInputTag = document.getElementById("slugCopyZone"); } - vdoPlyrAtts = video.baseURI; // Used for setting up thumbnails - slugInputTag.value = vdoPlyrAtts.slice(32, 32+11); + slugInputTag.value = video.baseURI.slice(32, 32+11); } const setupProc = () => { @@ -42,6 +57,11 @@ const betterYoutubePlus = () => { ytAHqDefaultImg = document.createElement("A"); ytAMedDefaultImg = document.createElement("A"); ytASdDefaultImg = document.createElement("A"); + ytIfrm = document.createElement("IFRAME"); + + // Loop range controls + ytRangeSection = document.createElement("SECTION"); + ytRangeStart = document.createElement("INPUT"); // Get nodes for page work containerOfPlyrWndow = document.getElementById("player-container"); // Container of actual player - Used for floating window @@ -51,12 +71,18 @@ const betterYoutubePlus = () => { ytThumbnailBttn.title = "Video Thumbnails..."; ytLoopBttn.title = "Start Loop..."; ytFloatBttn.title = "Float Video Container"; - - ytEnhancerMenu.appendChild(ytThumbnailBttn); - ytEnhancerMenu.appendChild(ytLoopBttn); - ytEnhancerMenu.appendChild(ytFloatBttn); + ytRangeStart.title = "Loop Range Start"; + ytRangeEnd.title = "Loop Range End"; + ytRangeStart.type = "text"; + ytRangeStart.value = "0:00"; // Insert + ytEnhancerMenu.appendChild(ytThumbnailBttn); + ytEnhancerMenu.appendChild(ytLoopBttn); + ytEnhancerMenu.appendChild(ytRangeSection); + ytEnhancerMenu.appendChild(ytFloatBttn); + ytRangeSection.append(ytRangeStart); + ytRangeSection.append(ytRangeEnd); document.body.appendChild(poppedContainer); document.body.appendChild(ytThumbImgMenu); document.body.appendChild(ytEnhancerMenu); @@ -68,6 +94,7 @@ const betterYoutubePlus = () => { ytThumbImgMenu.appendChild(ytAHqDefaultImg); ytThumbImgMenu.appendChild(ytAMedDefaultImg); ytThumbImgMenu.appendChild(ytASdDefaultImg); + poppedContainer.appendChild(ytIfrm); // Set onclick actions ytThumbnailBttn.addEventListener("click", showThumbImageVew); @@ -100,7 +127,16 @@ const betterYoutubePlus = () => { ytFloatBttn.className = "imageStyle"; ytEnhancerMenu.id = "enhancerMenuIDRef"; poppedContainer.id = "draggable"; + ytRangeStart.id = "rangeStartID"; + ytRangeEnd.id = "rangeEndID"; poppedContainer.style.display = "none"; + + ytIfrm.setAttribute("allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"); + ytIfrm.setAttribute("frameborder", "0"); + ytIfrm.setAttribute("autoplay", ""); + ytIfrm.setAttribute("allowfullscreen", "true"); + ytIfrm.setAttribute("width", "650px"); + ytIfrm.setAttribute("height", "400px"); } // Functions @@ -124,11 +160,6 @@ const betterYoutubePlus = () => { ytMqDefaultImg.title = "Medium Quality Default"; ytSdDefaultImg.title = "Standard Quality Default"; - ytMaxDefaultImg.onerror = function() { ytMaxDefaultImg.src = "/icons/missing.png"; } - ytHqDefaultImg.onerror = function() { ytHqDefaultImg.src = "/icons/missing.png"; } - ytAMedDefaultImg.onerror = function() { ytAMedDefaultImg.src = "/icons/missing.png"; } - ytASdDefaultImg.onerror = function() { ytASdDefaultImg.src = "/icons/missing.png"; } - ytThumbnailBttn.src = browser.extension.getURL("/icons/thumbnailOn.png"); ytThumbImgMenu.style.display = "block"; } @@ -136,31 +167,93 @@ const betterYoutubePlus = () => { } const setLoop = (e) => { - if (video.loop == false) { - video.loop = true; - ytLoopBttn.title = "Stop Loop..."; - ytLoopBttn.src = browser.extension.getURL("/icons/loopTrue.png"); - } else { + let start = ytRangeStart.value.trim(); + let end = ytRangeEnd.value.trim(); + + if (loopingInterval) { + console.log("Unsetting interval for loop check..."); + clearInterval(ytdVideoIntervalLoop); + loopingInterval = false; ytLoopBttn.title = "Start Loop..."; - video.loop = false; ytLoopBttn.src = browser.extension.getURL("/icons/loopFalse.png"); + return ; + } + + if (start.includes("0:00") && end.includes(videoTimeLength)) { + if (video.loop == false) { + console.log("Setting default loop marker..."); + video.loop = true; + ytLoopBttn.title = "Stop Loop..."; + ytLoopBttn.src = browser.extension.getURL("/icons/loopTrue.png"); + } else { + console.log("Unsetting default loop marker..."); + video.loop = false; + ytLoopBttn.title = "Start Loop..."; + ytLoopBttn.src = browser.extension.getURL("/icons/loopFalse.png"); + } + return ; + } else { + const getTotalSize = (array) => { + let size = 0.0; + let hours = 0.0; + let minutes = 0.0; + let seconds = 0.0; + + if (array.length === 2) { + minutes = parseFloat(array[0]) * 60.0; + seconds = parseFloat(array[1]); + size = minutes + seconds; + } else if (array.length === 3) { + hours = parseFloat(array[0]) * 3600.0; + minutes = parseFloat(array[1]) * 60.0; + seconds = parseFloat(array[2]); + size = hours + minutes + seconds; + } + return size; + } + + const checkLoopStuff = () => { + videoTimeCurent = video.currentTime; + if (videoTimeCurent > totalEnd || + videoTimeCurent < totalStart) { + video.currentTime = totalStart; + } + } + + + // Make sure start and end are proper + let totalStart = getTotalSize(start.split(":")); + let totalEnd = getTotalSize(end.split(":")); + if (totalStart < 0.0 || totalStart > video.duration) { return ; } + if (totalEnd < 0.0 || totalEnd > video.duration) { return ; } + + // Setup interval check for 1 sec and compare value of current pos to end + ytLoopBttn.title = "Stop Loop..."; + ytLoopBttn.src = browser.extension.getURL("/icons/loopTrue.png"); + loopingInterval = true; + + console.log("Setting interval for loop check..."); + ytdVideoIntervalLoop = setInterval(checkLoopStuff, 1000); } - return; } const toggleFloat = () => { - let playerWindow = document.getElementById("movie_player"); // Actual player + let mainPlayer = document.getElementById("player-container-outer"); + var ifrmBody = (ytIfrm.contentWindow || ytIfrm.contentDocument); + if (ifrmBody.document) ifrmBody = ifrmBody.document; - if(poppedContainer.style.display == "none"){ - setVideoStyle("auto", "auto", "50%"); - poppedContainer.appendChild(playerWindow); + if (poppedContainer.style.display == "none"){ + video.pause(); + mainPlayer.style.display = "none"; + ytIfrm.src = "https://www.youtube.com/embed/" + video.baseURI.slice(32, 32+11) + + "?autoplay=1&start=" + Math.floor(video.currentTime); poppedContainer.style.display = "block"; - } else { - setVideoStyle(containerOfPlyrWndow.offsetWidth + "px", - containerOfPlyrWndow.offsetHeight + "px", ""); - containerOfPlyrWndow.append(playerWindow); + video.currentTime = ifrmBody.getElementsByTagName("video")[0].currentTime; poppedContainer.style.display = "none"; + mainPlayer.style.display = ""; + ytIfrm.src = ""; + video.play(); } } @@ -250,6 +343,4 @@ const betterYoutubePlus = () => { // Start init checkPg(); -} - -betterYoutubePlus(); +}()); diff --git a/src/styles/betterYoutube.css b/src/styles/betterYoutube.css index b7ba844..38dd336 100644 --- a/src/styles/betterYoutube.css +++ b/src/styles/betterYoutube.css @@ -56,7 +56,10 @@ bottom: 0px; width: 650px; height: 400px; - background: black; + padding-top: 50px; + border-style: solid; + border-color: rgba(0, 232, 255, 0.64); + background: rgba(64, 64, 64, 0.64) }