YouTube Stream Timestamp Logger

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

  1. // ==UserScript==
  2. // @name YouTube Stream Timestamp Logger
  3. // @namespace http://tampermonkey.net/
  4. // @version 420.69
  5. // @description Logs the current YouTube stream URL, timestamp, and timestamped URL in shortened format
  6. // @author Kai Amamiya / ModernDisappointment | using the help of ChatGPT 3.0
  7. // @license MIT
  8. // @match *://www.youtube.com/watch*
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Function to convert seconds to HH:MM:SS.sss format
  15. function formatTime(seconds) {
  16. let hours = Math.floor(seconds / 3600);
  17. let minutes = Math.floor((seconds % 3600) / 60);
  18. let secs = (seconds % 60).toFixed(3);
  19. return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(6, '0')}`;
  20. }
  21.  
  22. // Function to convert seconds to URL timestamp format
  23. function secondsToURLTimestamp(seconds) {
  24. return Math.floor(seconds); // Round down to the nearest whole number
  25. }
  26.  
  27. // Function to copy text to clipboard
  28. function copyToClipboard(text) {
  29. const textarea = document.createElement('textarea');
  30. textarea.value = text;
  31. document.body.appendChild(textarea);
  32. textarea.select();
  33. document.execCommand('copy');
  34. document.body.removeChild(textarea);
  35. }
  36.  
  37. // Function to log and copy the current media time and video URL
  38. function logVideoDetails() {
  39. const ytPlayer = document.querySelector('video');
  40. if (ytPlayer) {
  41. const currentTime = ytPlayer.currentTime;
  42. const videoURL = window.location.href;
  43. const timestamp = formatTime(currentTime);
  44. const urlTimestamp = secondsToURLTimestamp(currentTime);
  45. // Extract video ID from the URL
  46. const videoIdMatch = videoURL.match(/[?&]v=([a-zA-Z0-9_-]+)/);
  47. const videoId = videoIdMatch ? videoIdMatch[1] : '';
  48. const timestampedURL = `https://youtu.be/${videoId}?t=${urlTimestamp}`;
  49. const output = `Note: \nVideo URL: ${videoURL}\nTimestamp: ${timestamp}\nVideo URL w/ Time: ${timestampedURL}`;
  50. console.log(output);
  51. copyToClipboard(output);
  52. alert('Video URL, Timestamp, and Timestamped URL copied to clipboard!');
  53. } else {
  54. console.log('YouTube video element not found.');
  55. }
  56. }
  57. // Function to create or remove the button based on the page state
  58. function updateButton() {
  59. // Check if we are on a YouTube video or stream page
  60. const isYouTubeVideoPage = /\/watch\?v=/.test(window.location.href) || /\/live/.test(window.location.href);
  61. const isVideoPage = document.querySelector('video') !== null;
  62. const isFullscreen = document.fullscreenElement !== null;
  63.  
  64. if (isYouTubeVideoPage && isVideoPage && !isFullscreen) {
  65. if (!document.getElementById('copyTimestampButton')) {
  66. const button = document.createElement('button');
  67. button.id = 'copyTimestampButton';
  68. button.innerHTML = 'Timestamp';
  69. button.style.position = 'fixed';
  70. button.style.bottom = '10px';
  71. button.style.left = '10px';
  72. button.style.zIndex = '9999';
  73. button.style.padding = '10px';
  74. button.style.backgroundColor = '#404040';
  75. button.style.color = '#FFFFFF';
  76. button.style.border = 'none';
  77. button.style.cursor = 'pointer';
  78. button.addEventListener('click', logVideoDetails);
  79. document.body.appendChild(button);
  80. }
  81. } else {
  82. const button = document.getElementById('copyTimestampButton');
  83. if (button) {
  84. button.remove();
  85. }
  86. }
  87. }
  88.  
  89. // Set up observers to check for changes
  90. function setupObservers() {
  91. // Monitor for changes in the page that might indicate a video or fullscreen state change
  92. const observer = new MutationObserver(updateButton);
  93. observer.observe(document.body, {
  94. childList: true,
  95. subtree: true
  96. });
  97.  
  98. // Also check for fullscreen changes
  99. document.addEventListener('fullscreenchange', updateButton);
  100. }
  101.  
  102. // Initialize observers when the page loads
  103. window.addEventListener('load', setupObservers);
  104. // Also check initially if on a video page
  105. window.addEventListener('load', updateButton);
  106. })();