您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows a list of the playlist video names/channels/URLs in plaintext to be easily copied
当前为
// ==UserScript== // @name Export Youtube Playlist in plaintext // @namespace 1N07 // @version 0.9.1 // @description Shows a list of the playlist video names/channels/URLs in plaintext to be easily copied // @author 1N07 // @license unlicense // @compatible firefox Likely to work on other userscript managers, but not tested // @compatible firefox v0.9 Tested on Firefox v134.0.1 and Tampermonkey 5.3.3 // @compatible chrome Likely to work on other userscript managers, but not tested // @compatible chrome v0.9 Tested on Chrome v132.0.6834.84 and Tampermonkey 5.3.3 // @compatible opera untested, but likely works with at least Tampermonkey // @compatible edge untested, but likely works with at least Tampermonkey // @compatible safari untested, but likely works with at least Tampermonkey // @icon https://www.google.com/s2/favicons?domain=youtube.com // @match https://www.youtube.com/* // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // ==/UserScript== (() => { let getVideoTitle = GM_getValue("getVideoTitle", true); let getVideoChannel = GM_getValue("getVideoChannel", false); let getVideoURL = GM_getValue("getVideoURL", false); let videoListSeperator = GM_getValue("videoListSeperator", " ; "); let listCreationAllowed = true; let urlAtLastCheck = ""; let buttonInsertInterval; //add some CSS GM_addStyle(` tp-yt-paper-listbox#items { overflow-x: hidden; } #exportPlainTextList { cursor: pointer; height: 36px; width: 100%; display: flex; align-items: center; } #exportPlainTextList > img { height: 24px; width: 24px; color: rgb(144, 144, 144); padding: 0 13px 0 16px; filter: contrast(0%); } #exportPlainTextList > span { font-family: "Roboto","Arial",sans-serif; color: #d9d9d9; white-space: nowrap; font-size: 1.4rem; line-height: 2rem; font-weight: 400; } #exportPlainTextList:hover { background-color: rgba(255,255,255,0.1); } ytd-menu-popup-renderer.ytd-popup-container { overflow-x: hidden !important; max-height: none !important; } #listDisplayContainer { position: fixed; z-index: 9999; margin: 0 auto; background-color: #464646; padding: 10px; border-radius: 5px; left: 0; right: 0; max-width: 100vw; width: 1200px; height: 900px; max-height: 90vh; top: 5vh; resize: both; overflow: hidden; } #listDisplayContainer p { text-align: center; } #listDisplayContainer .title { font-size: 21px; font-weight: bold; color: #d9d9d9; } #listDisplayContainer ul { list-style: none; font-size: 12px; scale: 1.4; color: #d9d9d9; width: -moz-fit-content; width: fit-content; margin: 40px auto; } #listDisplayContainer > textarea { box-sizing: border-box; width: 100%; margin: 10px 0; height: calc(100% - 40px); background-color: #262626; border: none; color: #EEE; border-radius: 5px; resize: none; } #listDisplayContainer #listDisplayGetListButton { position: relative; margin: 10px 0; font-size: 13px; left: 50%; transform: translateX(-50%); } #closeTheListThing { float: right; font-weight: bold; background-color: RGBA(255,255,255,0.25); border: none; font-size: 17px; border-radius: 10px; height: 25px; width: 25px; cursor: pointer; } #closeTheListThing:hover { background-color: rgba(255,255,255,0.5); } tp-yt-iron-dropdown.ytd-popup-container #contentWrapper > yt-sheet-view-model.ytd-popup-container { max-height: unset !important; } .yt-pl-export-loading-popup { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #262626; padding: 20px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); z-index: 9999; border-radius: 8px; text-align: center; } .yt-pl-export-loading-popup-message { font-size: 2rem; color: #d9d9d9; } `); setInterval(() => { if (urlAtLastCheck !== window.location.href) { urlAtLastCheck = window.location.href; if (urlAtLastCheck.includes("/playlist?list=")) InsertButtonASAP(); else clearInterval(buttonInsertInterval); } }, 100); function InsertButtonASAP() { buttonInsertInterval = setInterval(() => { //wait for possible previous buttons to stop existing (due to how youtube loads pages) and for the space for the new button to be available if (!document.getElementById("exportPlainTextList")) { let place = document.querySelector("tp-yt-iron-dropdown.ytd-popup-container .yt-list-view-model-wiz[role='menu']"); if (!place) place = document.querySelector("tp-yt-iron-dropdown.ytd-popup-container tp-yt-paper-listbox.ytd-menu-popup-renderer[role='listbox']"); if (place) { const div = document.createElement('div'); div.id = 'exportPlainTextList'; const img = document.createElement('img'); img.src = 'https://i.imgur.com/emlur3a.png'; div.appendChild(img); const span = document.createElement('span'); span.textContent = 'Export Playlist'; div.appendChild(span); place.appendChild(div); div.addEventListener('click', ScrollUntillAllVisible); } } }, 100); } function ScrollUntillAllVisible() { if (!listCreationAllowed) return; document.querySelector("ytd-browse[page-subtype='playlist']").click(); const popup = createPopup("Scrolling to load all videos in the playlist. Please wait..."); listCreationAllowed = false; const scrollInterval = setInterval(() => { if (document.querySelector("ytd-continuation-item-renderer.ytd-playlist-video-list-renderer")) { window.scrollTo(0, (document.documentElement || document.body).scrollHeight); } else { popup.close(); DisplayListOptions(); clearInterval(scrollInterval); } }, 100); } function DisplayListOptions() { //#region listDisplayContainer // Create elements programmatically to avoid inline HTML generation const container = document.createElement('div'); container.id = 'listDisplayContainer'; // Create the content structure const p = document.createElement('p'); const span = document.createElement('span'); span.classList.add('title'); span.textContent = 'Playlist in plain text'; const closeButton = document.createElement('button'); closeButton.id = 'closeTheListThing'; closeButton.textContent = 'X'; p.appendChild(span); p.appendChild(closeButton); container.appendChild(p); const textarea = document.createElement('textarea'); textarea.style.display = 'none'; container.appendChild(textarea); const ul = document.createElement('ul'); ul.id = 'listDisplayOptions'; // Helper function to create a list item with a checkbox function createListItem(labelText, checkboxId, checked) { const li = document.createElement('li'); const label = document.createElement('label'); const input = document.createElement('input'); input.type = 'checkbox'; input.id = checkboxId; input.name = checkboxId; input.value = checkboxId; if (checked) input.checked = true; label.appendChild(input); label.appendChild(document.createTextNode(labelText)); li.appendChild(label); return li; } // Add list items ul.appendChild(createListItem('Get titles', 'getVideoTitleCB', getVideoTitle)); ul.appendChild(createListItem('Get channel names', 'getVideoChannelCB', getVideoChannel)); ul.appendChild(createListItem('Get URLs', 'getVideoURLCB', getVideoURL)); const nameSeparatorInput = document.createElement('input'); nameSeparatorInput.type = 'text'; nameSeparatorInput.id = 'videoListSeperatorInput'; nameSeparatorInput.name = 'videoListSeperatorInput'; nameSeparatorInput.value = videoListSeperator; nameSeparatorInput.style.width = '40px'; nameSeparatorInput.style.textAlign = 'center'; const nameSeparatorLabel = document.createElement('label'); nameSeparatorLabel.appendChild(nameSeparatorInput); nameSeparatorLabel.appendChild(document.createTextNode(' Name/Author/URL separator')); const nameSeparatorLi = document.createElement('li'); nameSeparatorLi.appendChild(nameSeparatorLabel); ul.appendChild(nameSeparatorLi); const getListButton = document.createElement('button'); getListButton.id = 'listDisplayGetListButton'; getListButton.textContent = 'Get list'; const buttonLi = document.createElement('li'); buttonLi.appendChild(getListButton); ul.appendChild(buttonLi); container.appendChild(ul); // Append the container to the body document.body.appendChild(container); //#endregion document.getElementById("getVideoTitleCB").addEventListener("change", function () { getVideoTitle = this.checked; GM_setValue("getVideoTitle", getVideoTitle); }); document.getElementById("getVideoChannelCB").addEventListener("change", function () { getVideoChannel = this.checked; GM_setValue("getVideoChannel", getVideoChannel); }); document.getElementById("getVideoURLCB").addEventListener("change", function () { getVideoURL = this.checked; GM_setValue("getVideoURL", getVideoURL); }); document.getElementById("videoListSeperatorInput").addEventListener("change", function () { videoListSeperator = this.value; GM_setValue("videoListSeperator", videoListSeperator); }); document.getElementById("listDisplayGetListButton").addEventListener("click", BuildAndDisplayList); document.getElementById("closeTheListThing").addEventListener("click", () => { document.getElementById("listDisplayContainer").remove(); listCreationAllowed = true; }); } function BuildAndDisplayList() { document.getElementById("listDisplayOptions").style.display = "none"; document.querySelector("#listDisplayContainer > textarea").style.display = "block"; const videoTitleArr = []; const videoChannelArr = []; const videoURLArr = []; let videoCount = 0; for (const element of document.querySelectorAll("ytd-playlist-video-list-renderer > #contents.ytd-playlist-video-list-renderer > ytd-playlist-video-renderer #content")) { if (getVideoTitle) videoTitleArr.push(element.querySelector("#video-title").getAttribute("title")); if (getVideoURL) videoURLArr.push(`https://www.youtube.com${element.querySelector("#video-title").getAttribute("href").split("&")[0]}`); if (getVideoChannel) videoChannelArr.push(element.querySelector("#channel-name yt-formatted-string.ytd-channel-name > a").textContent); videoCount++; } let list = ""; for (let i = 0; i < videoCount; i++) { if (getVideoTitle) list += videoTitleArr[i]; if (getVideoChannel) list += (getVideoTitle ? `${videoListSeperator}` : "") + videoChannelArr[i]; if (getVideoURL) list += (getVideoTitle || getVideoChannel ? `${videoListSeperator}` : "") + videoURLArr[i]; list += "\n"; } document.querySelector("#listDisplayContainer > textarea").value = list; } function createPopup(message) { // Create the popup container const popup = document.createElement('div'); popup.classList.add('yt-pl-export-loading-popup'); // Apply the popup class // Create the message element const messageElem = document.createElement('p'); messageElem.classList.add("yt-pl-export-loading-popup-message"); // Apply the message class messageElem.textContent = message; popup.appendChild(messageElem); // Append the popup to the body document.body.appendChild(popup); // Return an object that can be used to close the popup later return { close: closePopup }; // Function to close the popup function closePopup() { document.body.removeChild(popup); } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址