Copy YouTube Transcript 3

Add a button to copy YouTube transcript to clipboard. Cần thêm điều kiện chỉ add nút ở trang phát video, thêm điều kiện đợi load transcript (nếu bấm được show thì đợi load), cần thêm điều kiện thoát khỏi lặp nếu như không tìm thấy transcript

当前为 2025-02-17 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Copy YouTube Transcript 3
// @namespace    http://tampermonkey.net/
// @version      3
// @description  Add a button to copy YouTube transcript to clipboard. Cần thêm điều kiện chỉ add nút ở trang phát video, thêm điều kiện đợi load transcript (nếu bấm được show thì đợi load), cần thêm điều kiện thoát khỏi lặp nếu như không tìm thấy transcript
// @author       lmdw
// @match        https://www.youtube.com/*
// @grant        GM_setClipboard
// ==/UserScript==

(function () {
    'use strict';

    // Add button to the page
    function addButton() {
        // Check if the button already exists
        if (document.querySelector('#copy-transcript-button')) return;

        // Find the container for the button (below video player)
        const videoContainer = document.querySelector('#above-the-fold #title');

        if (!videoContainer) return;

        // Create the button
        const button = document.createElement('button');
        button.id = 'copy-transcript-button';
        button.textContent = 'Copy Transcript';
        button.className = 'yt-spec-button-shape-next yt-spec-button-shape-next--outline yt-spec-button-shape-next--call-to-action yt-spec-button-shape-next--size-m';
        button.style.marginTop = '8px'; // Add slight spacing

        // Append the button to the container
        videoContainer.parentNode.insertBefore(button, videoContainer.nextSibling);

        // Add click event to the button
        button.addEventListener('click', handleTranscriptCopy);
    }

    // Handle transcript copy process
    async function handleTranscriptCopy() {
        await clickExpandDescription();
        await clickShowTranscript();

        const transcript = getTranscript();

        if (!transcript || transcript.length === 0) {
            alert('No transcript available for this video.');
            return;
        }

        // Use GM_setClipboard to copy to clipboard
        GM_setClipboard(transcript);

        alert('Transcript copied to clipboard!');
    }

    // Click the "More" button to expand description
    async function clickExpandDescription() {
        const expandButton = document.querySelector('#expand');
        if (expandButton) {
            expandButton.click();
            await new Promise(resolve => setTimeout(resolve, 500)); // Wait for UI to update
        }
    }

    // Click the "Show Transcript" button
    async function clickShowTranscript() {
        const showTranscriptButton = document.querySelector("#primary-button > ytd-button-renderer > yt-button-shape > button");
        if (showTranscriptButton) {
            showTranscriptButton.click();
            await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for transcript to load
        }
    }

    // Fetch transcript text
    function getTranscript() {
        // Find the container for transcript segments
        const transcriptContainer = document.querySelector('#segments-container');

        if (!transcriptContainer) {
            return null;
        }

        // Collect all transcript lines
        const lines = Array.from(
            transcriptContainer.querySelectorAll('.segment-text')
        );

        // Extract and join text content
        return lines.map(line => line.textContent.trim()).join('\n');
    }

    // Observe changes to the page and add button dynamically
    const observer = new MutationObserver(addButton);
    observer.observe(document.body, { childList: true, subtree: true });
})();