您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Copy video titles, dates, and views - simplest version.
// ==UserScript== // @name Copy YouTube Channel Video Info (Simplest) // @match https://www.youtube.com/*/videos // @grant none // @version 1 // @author lmdw // @description Copy video titles, dates, and views - simplest version. // @namespace https://greasyfork.org/users/1436006 // ==/UserScript== (function() { 'use strict'; // --- CẤU HÌNH --- const SCROLL_DELAY = 1500; const LOAD_CHECK_DELAY = 3000; const MAX_CHECK_ATTEMPTS = 5; const OUTPUT_FORMAT = "{title} / {date} / {views}"; // --- HẾT PHẦN CẤU HÌNH --- function countVideoTitles() { return document.querySelectorAll('a#video-title-link yt-formatted-string#video-title').length; } function getVideoInfo() { const videoContainers = document.querySelectorAll('ytd-rich-grid-media'); let videoData = []; for (const container of videoContainers) { const titleElement = container.querySelector('a#video-title-link yt-formatted-string#video-title'); const title = titleElement ? titleElement.innerText.trim() : "Không có tiêu đề"; const metaBlocks = container.querySelectorAll(".inline-metadata-item.style-scope.ytd-video-meta-block"); let date = "Không có ngày"; let views = "Không có lượt xem"; if (metaBlocks.length >= 2) { date = metaBlocks[1] ? metaBlocks[1].innerText.trim() : "Không có ngày"; views = metaBlocks[0] ? metaBlocks[0].innerText.trim() : "Không có lượt xem"; } let output = OUTPUT_FORMAT .replace("{title}", title) .replace("{date}", date) .replace("{views}", views); videoData.push(output); } return videoData; } function copyVideoInfoToClipboard(videoData, message) { if (videoData.length === 0) { alert("Không tìm thấy video nào."); return; } const allVideoInfo = videoData.join('\n'); navigator.clipboard.writeText(allVideoInfo) .then(() => { alert(message); }) .catch(err => { console.error('Lỗi khi copy:', err); alert("Có lỗi xảy ra khi copy. Vui lòng thử lại."); }); } function scrollToBottomAndLoad(callback) { let initialTitleCount = countVideoTitles(); let checkAttempts = 0; function scrollAndWait() { window.scrollTo(0, document.documentElement.scrollHeight); console.log("Đang cuộn..."); setTimeout(checkIfLoaded, LOAD_CHECK_DELAY); } function checkIfLoaded() { let newTitleCount = countVideoTitles(); if (newTitleCount > initialTitleCount) { // Đã load thêm, tiếp tục cuộn initialTitleCount = newTitleCount; checkAttempts = 0; scrollAndWait(); } else { // Không load thêm checkAttempts++; if (checkAttempts >= MAX_CHECK_ATTEMPTS) { // Copy ngay lập tức những gì hiện có callback(getVideoInfo(), "Đã dừng cuộn và copy thông tin video hiện có."); return; } else { console.log("Chưa load thêm, thử lại sau " + LOAD_CHECK_DELAY + "ms. Lần thử: ", checkAttempts); setTimeout(checkIfLoaded, LOAD_CHECK_DELAY); } } } //Bắt đầu if(initialTitleCount === 0){ alert("Không tìm thấy video nào"); return; } scrollAndWait(); } function startCopyProcess() { const shouldScroll = confirm("Bạn có muốn cuộn trang để tải thêm video không?"); if (shouldScroll) { scrollToBottomAndLoad(copyVideoInfoToClipboard); //Truyền callback vào } else { const videoData = getVideoInfo(); if (videoData.length > 0){ copyVideoInfoToClipboard(videoData, "Đã copy thông tin video hiện có."); } else{ alert("Không tìm thấy video nào"); } } } // --- Thêm nút Copy --- const button = document.createElement('button'); button.textContent = 'Copy Video Info'; button.style.position = 'fixed'; button.style.top = '10px'; button.style.right = '10px'; button.style.zIndex = '9999'; button.style.backgroundColor = '#4CAF50'; button.style.border = 'none'; button.style.color = 'white'; button.style.padding = '10px 20px'; button.style.textAlign = 'center'; button.style.textDecoration = 'none'; button.style.display = 'inline-block'; button.style.fontSize = '16px'; button.style.cursor = 'pointer'; button.addEventListener('click', startCopyProcess); document.body.appendChild(button); })();