diff --git a/mpv-opener.desktop b/desktopFiles/mpv-opener.desktop similarity index 100% rename from mpv-opener.desktop rename to desktopFiles/mpv-opener.desktop diff --git a/desktopFiles/ytdlp-downloader.desktop b/desktopFiles/ytdlp-downloader.desktop new file mode 100755 index 0000000..8e56910 --- /dev/null +++ b/desktopFiles/ytdlp-downloader.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Application +Name=Video Downloader +Exec=bash -c 'arg=$0; arg=${arg/"https//"/"https://"}; clean_url=${arg:19}; echo "Download URL: $clean_url"; yt-dlp -f "best[height<=1080]/best" --output "$HOME/Downloads/%(title)s.%(ext)s" "$clean_url" || (echo "ERROR: Download failed for URL: $clean_url" && echo "Raw arg: $arg"; echo "Raw link:" $0 && sleep 5)' "%u" +StartupNotify=true +MimeType=x-scheme-handler/ytdlp-downloader +Terminal=true # Change to false after testing for background runs +Hidden=false +Icon=download diff --git a/userscript/mpvOdysee.js b/userscript/mpvOdysee.js new file mode 100644 index 0000000..f7de8ee --- /dev/null +++ b/userscript/mpvOdysee.js @@ -0,0 +1,90 @@ +// ==UserScript== +// @name Odysee MPV Player +// @version 0.2 +// @description This little script opens any Odysee video in MPV with a simple button click +// @author TibixDev +// @match https://odysee.com/* +// @icon https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Odysee_Logo.svg/1200px-Odysee_Logo.svg.png +// @grant GM_addStyle +// ==/UserScript== + +(async function () { + 'use strict'; + console.log("[YTMPV] Odysee MPV player script loaded"); + let urlRegex = /^https:\/\/(www\.)?odysee\.com\/@[^:]+:[^\/]+\/[^:]+:[^\/]*$/ + + function setButtonInterval() { + return setInterval(() => { + //console.log("pooling menu container"); + if (document.querySelector(".card__body>.media__subtitle--between>.media__actions")) { + console.log("[YTMPV] Menu container found, executing..."); + addMpvButton() + } + }, 2000); + } + + let waitForButtons = null; + + let location = window.location.href;; + if (location.match(urlRegex)) { + waitForButtons = setButtonInterval(); + console.log("[YTMPV] Starting video link correct: " + location); + } + + function handleVideoUrlChange(newUrl) { + if (location !== newUrl && window.location.href.match(urlRegex) && !waitForButtons) { + console.log("[YTMPV] Video URL detected, toggling waitForButtons..."); + waitForButtons = setButtonInterval(); + location = newUrl; + } + } + + document.addEventListener('click', (e) => { + //console.log("click"); + // Optional: Skip if clicking your button or specific elements + + if (e.target.id === "mpv-button") { + return; // Don't refresh on MPV button clicks + } + setTimeout(() => { + handleVideoUrlChange(window.location.href); + }, 100); + }, true); + + function addMpvButton() { + clearInterval(waitForButtons); + waitForButtons = null; + const ytButtons = document.querySelector(".card__body>.media__subtitle--between>.media__actions"); + const ytButton = document.createElement("button"); + ytButton.id = "mpv-button"; + ytButton.classList.add("button", "button--no-style", "button--file-action"); + const mpvBtnStyle = ` + #mpv-button { + margin-right: 10px; + }` + + const styleElem = document.createElement("style"); + if (styleElem.styleSheet) { + styleElem.styleSheet.cssText = mpvBtnStyle; + } else { + styleElem.appendChild(document.createTextNode(mpvBtnStyle)); + } + document.getElementsByTagName('head')[0].appendChild(styleElem); + //ytButton.style.cssText = "margin-right: 10px;"; + ytButton.textContent = "▶ MPV"; + ytButton.addEventListener("click", () => { + document.querySelector("video").pause(); + document.location = "mpv://" + document.location.href; + ytButton.textContent = "⌛ Opening..."; + ytButton.style.cssText = "background-color: #0a6dab;"; + setTimeout(() => { + ytButton.textContent = "▶ MPV"; + ytButton.style.cssText = ""; + }, 3000); + }); + + ytButtons.appendChild(ytButton); + console.log("[YTMPV] MPV button added"); + console.log(ytButton, ytButtons); + } +})(); \ No newline at end of file diff --git a/userscript/mpv.js b/userscript/mpvYouTube.js similarity index 63% rename from userscript/mpv.js rename to userscript/mpvYouTube.js index b60305a..9844ad8 100644 --- a/userscript/mpv.js +++ b/userscript/mpvYouTube.js @@ -14,56 +14,49 @@ function setButtonInterval() { return setInterval(() => { - if (document.querySelector("#info>#menu-container>#menu>ytd-menu-renderer>#top-level-buttons-computed>ytd-toggle-button-renderer")) { + if (document.querySelector("#actions>#actions-inner>#menu>ytd-menu-renderer>#top-level-buttons-computed>yt-button-view-model")) { console.log("[YTMPV] Menu container found, executing..."); addMpvButton() } - }, 1000); + }, 2000); } - // let waitForButtons = setButtonInterval(); let waitForButtons = null; - let location = window.location.href;; + let location = window.location.href; if (location.match(/^https:\/\/www\.youtube\.com\/watch\?v=([^&]*)/)) { waitForButtons = setButtonInterval(); + console.log("[YTMPV] Video link correct: " + location); } - let waitForUrlChange = setInterval(() => { - if (location !== window.location.href && window.location.href.includes("watch?v=") && !waitForButtons) { + function handleVideoUrlChange(newUrl) { + if (location !== newUrl && newUrl.includes("watch?v=") && !waitForButtons) { console.log("[YTMPV] Video URL detected, toggling waitForButtons..."); waitForButtons = setButtonInterval(); - location = window.location.href; + location = newUrl; } - }, 1000); + } + + // Listen for YouTube's navigation finish event + window.addEventListener('yt-navigate-finish', () => { + // Small delay to ensure URL and content are settled + setTimeout(() => { + handleVideoUrlChange(window.location.href); + }, 100); + }); function addMpvButton() { clearInterval(waitForButtons); waitForButtons = null; - const ytButtons = document.querySelector("#info>#menu-container>#menu>ytd-menu-renderer>#top-level-buttons-computed"); + const ytButtons = document.querySelector("#actions>#actions-inner>#menu>ytd-menu-renderer>#top-level-buttons-computed"); const ytButton = document.createElement("button"); ytButton.id = "mpv-button"; + ytButton.classList.add("ytSpecButtonViewModelHost", "style-scope", "ytd-menu-renderer", "yt-spec-button-shape-next", "yt-spec-button-shape-next--tonal", "yt-spec-button-shape-next--mono", "yt-spec-button-shape-next--size-m", "yt-spec-button-shape-next--icon-leading", "yt-spec-button-shape-next--enable-backdrop-filter-experiment"); const mpvBtnStyle = ` #mpv-button { - color: white; - cursor: pointer; - background-color: #043565; - border-radius: 10px; margin-left: 10px; - margin-right: 10px; - padding-left: 10px; - padding-right: 10px; - font-size: var(--ytd-tab-system-font-size); - font-weight: var(--ytd-tab-system-font-weight); - font-family: Roboto, Arial, sans-serif; - border: 0; - transition: all 0.2s ease-in-out; - } - - #mpv-button:hover { - background-color: #0a6dab; }` - + const styleElem = document.createElement("style"); if (styleElem.styleSheet) { styleElem.styleSheet.cssText = mpvBtnStyle; @@ -71,7 +64,7 @@ styleElem.appendChild(document.createTextNode(mpvBtnStyle)); } document.getElementsByTagName('head')[0].appendChild(styleElem); - // ytButton.style.cssText = mpvBtnStyle; + //ytButton.style.cssText = "margin-left: 10px;"; ytButton.textContent = "▶ MPV"; ytButton.addEventListener("click", () => { document.querySelector("video").pause(); @@ -83,7 +76,7 @@ ytButton.style.cssText = ""; }, 3000); }); - + ytButtons.appendChild(ytButton); console.log("[YTMPV] MPV button added"); console.log(ytButton, ytButtons); diff --git a/userscript/youtubeDownloader.js b/userscript/youtubeDownloader.js new file mode 100644 index 0000000..a1822a4 --- /dev/null +++ b/userscript/youtubeDownloader.js @@ -0,0 +1,84 @@ +// ==UserScript== +// @name YouTube Downloader +// @version 0.3 +// @description This little script downloads any YouTube video +// @author TibixDev +// @match https://www.youtube.com/* +// @grant GM_addStyle +// ==/UserScript== + +(async function () { + 'use strict'; + console.log("[YTDL] YouTube downloader script loaded"); + + function setButtonInterval() { + return setInterval(() => { + if (document.querySelector("#actions>#actions-inner>#menu>ytd-menu-renderer>#top-level-buttons-computed>yt-button-view-model")) { + console.log("[YTDL] Menu container found, executing..."); + addDlButton() + } + }, 2000); + } + + let waitForButtons = null; + + let location = window.location.href; + if (location.match(/^https:\/\/www\.youtube\.com\/watch\?v=([^&]*)/)) { + waitForButtons = setButtonInterval(); + console.log("[YTDL] Video link correct: " + location); + } + + function handleVideoUrlChange(newUrl) { + if (location !== newUrl && newUrl.includes("watch?v=") && !waitForButtons) { + console.log("[YTDL] Video URL detected, toggling waitForButtons..."); + waitForButtons = setButtonInterval(); + location = newUrl; + } + } + + // Listen for YouTube's navigation finish event + window.addEventListener('yt-navigate-finish', () => { + // Small delay to ensure URL and content are settled + setTimeout(() => { + handleVideoUrlChange(window.location.href); + }, 100); + }); + + function addDlButton() { + clearInterval(waitForButtons); + waitForButtons = null; + const ytButtons = document.querySelector("#actions>#actions-inner>#menu>ytd-menu-renderer>#top-level-buttons-computed"); + const ytButton = document.createElement("button"); + ytButton.id = "ytdlp-button"; + ytButton.classList.add("ytSpecButtonViewModelHost", "style-scope", "ytd-menu-renderer", "yt-spec-button-shape-next", "yt-spec-button-shape-next--tonal", "yt-spec-button-shape-next--mono", "yt-spec-button-shape-next--size-m", "yt-spec-button-shape-next--icon-leading", "yt-spec-button-shape-next--enable-backdrop-filter-experiment"); + const mpvBtnStyle = ` + #ytdlp-button { + margin-left: 10px; + padding: 0px 40px; + }` + + const styleElem = document.createElement("style"); + if (styleElem.styleSheet) { + styleElem.styleSheet.cssText = mpvBtnStyle; + } else { + styleElem.appendChild(document.createTextNode(mpvBtnStyle)); + } + document.getElementsByTagName('head')[0].appendChild(styleElem); + //ytButton.style.cssText = "margin-left: 10px;"; + ytButton.textContent = "📥 DOWNLOAD"; + ytButton.addEventListener("click", () => { + document.querySelector("video").pause(); + document.location = "ytdlp-downloader://" + document.location.href; + ytButton.textContent = "📥 DOWNLOAD"; + //ytButton.style.cssText = "background-color: #0a6dab;"; + setTimeout(() => { + ytButton.textContent = "Downloading..."; + ytButton.style.cssText = ""; + }, 3000); + }); + + ytButtons.appendChild(ytButton); + console.log("[YTDL] DOWNLOAD button added"); + console.log(ytButton, ytButtons); + } +})(); \ No newline at end of file