YouTube Stream Timestamp Logger

Logs the current YouTube stream URL, timestamp, and timestamped URL in shortened format

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         YouTube Stream Timestamp Logger
// @namespace    http://tampermonkey.net/
// @version      420.69
// @description  Logs the current YouTube stream URL, timestamp, and timestamped URL in shortened format
// @author       Kai Amamiya / ModernDisappointment | using the help of ChatGPT 3.0
// @license      MIT
// @match        *://www.youtube.com/watch*
// ==/UserScript==

(function() {
    'use strict';

    // Function to convert seconds to HH:MM:SS.sss format
    function formatTime(seconds) {
        let hours = Math.floor(seconds / 3600);
        let minutes = Math.floor((seconds % 3600) / 60);
        let secs = (seconds % 60).toFixed(3);
        return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(6, '0')}`;
    }

    // Function to convert seconds to URL timestamp format
    function secondsToURLTimestamp(seconds) {
        return Math.floor(seconds); // Round down to the nearest whole number
    }

    // Function to copy text to clipboard
    function copyToClipboard(text) {
        const textarea = document.createElement('textarea');
        textarea.value = text;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand('copy');
        document.body.removeChild(textarea);
    }

    // Function to log and copy the current media time and video URL
    function logVideoDetails() {
        const ytPlayer = document.querySelector('video');
        if (ytPlayer) {
            const currentTime = ytPlayer.currentTime;
            const videoURL = window.location.href;
            const timestamp = formatTime(currentTime);
            const urlTimestamp = secondsToURLTimestamp(currentTime);
            // Extract video ID from the URL
            const videoIdMatch = videoURL.match(/[?&]v=([a-zA-Z0-9_-]+)/);
            const videoId = videoIdMatch ? videoIdMatch[1] : '';
            const timestampedURL = `https://youtu.be/${videoId}?t=${urlTimestamp}`;
            const output = `Note: \nVideo URL: ${videoURL}\nTimestamp: ${timestamp}\nVideo URL w/ Time: ${timestampedURL}`;
            console.log(output);
            copyToClipboard(output);
            alert('Video URL, Timestamp, and Timestamped URL copied to clipboard!');
        } else {
            console.log('YouTube video element not found.');
        }
    }
    // Function to create or remove the button based on the page state
    function updateButton() {
        // Check if we are on a YouTube video or stream page
        const isYouTubeVideoPage = /\/watch\?v=/.test(window.location.href) || /\/live/.test(window.location.href);
        const isVideoPage = document.querySelector('video') !== null;
        const isFullscreen = document.fullscreenElement !== null;

        if (isYouTubeVideoPage && isVideoPage && !isFullscreen) {
            if (!document.getElementById('copyTimestampButton')) {
                const button = document.createElement('button');
                button.id = 'copyTimestampButton';
                button.innerHTML = 'Timestamp';
                button.style.position = 'fixed';
                button.style.bottom = '10px';
                button.style.left = '10px';
                button.style.zIndex = '9999';
                button.style.padding = '10px';
                button.style.backgroundColor = '#404040';
                button.style.color = '#FFFFFF';
                button.style.border = 'none';
                button.style.cursor = 'pointer';
                button.addEventListener('click', logVideoDetails);
                document.body.appendChild(button);
            }
        } else {
            const button = document.getElementById('copyTimestampButton');
            if (button) {
                button.remove();
            }
        }
    }

    // Set up observers to check for changes
    function setupObservers() {
        // Monitor for changes in the page that might indicate a video or fullscreen state change
        const observer = new MutationObserver(updateButton);
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

        // Also check for fullscreen changes
        document.addEventListener('fullscreenchange', updateButton);
    }

    // Initialize observers when the page loads
    window.addEventListener('load', setupObservers);
    // Also check initially if on a video page
    window.addEventListener('load', updateButton);
})();