YouTube Embed Button Under Video

Adds a button under YouTube videos to open the embed page for the current video.

当前为 2025-05-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube Embed Button Under Video
  3. // @namespace https://github.com/almahmudbd
  4. // @version 2.1
  5. // @description Adds a button under YouTube videos to open the embed page for the current video.
  6. // @license GPL-3
  7. // @author unknown
  8. // @match https://www.youtube.com/watch*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. // Helper to get video ID from current URL
  16. function getVideoId() {
  17. const urlObj = new URL(window.location.href);
  18. return urlObj.searchParams.get('v');
  19. }
  20.  
  21. // Create and insert the embed button under the video
  22. function insertEmbedButton() {
  23. // Avoid duplicate buttons
  24. if (document.getElementById('yt-embed-link-btn')) return;
  25.  
  26. const videoId = getVideoId();
  27. if (!videoId) return;
  28.  
  29. // Find the container below the video (where buttons like Share/Like appear)
  30. // This selector is relatively stable, but may need updating if YouTube changes its layout
  31. const actionsRow = document.querySelector('#top-level-buttons-computed, ytd-menu-renderer #top-level-buttons');
  32.  
  33. if (actionsRow) {
  34. // Create the button
  35. const btn = document.createElement('button');
  36. btn.id = 'yt-embed-link-btn';
  37. btn.textContent = '▶ Open Embed Page';
  38. btn.style.marginLeft = "8px";
  39. btn.style.padding = "6px 12px";
  40. btn.style.background = "#222";
  41. btn.style.color = "#fff";
  42. btn.style.border = "none";
  43. btn.style.borderRadius = "3px";
  44. btn.style.cursor = "pointer";
  45. btn.title = "Open this video in YouTube embed view";
  46.  
  47. btn.onclick = () => {
  48. const embedUrl = `https://www.youtube.com/embed/${videoId}`;
  49. window.open(embedUrl, '_blank');
  50. };
  51.  
  52. // Insert the button at the end of the action row
  53. actionsRow.appendChild(btn);
  54. }
  55. }
  56.  
  57. // Observe for SPA navigation and DOM updates
  58. let lastUrl = location.href;
  59. const observer = new MutationObserver(() => {
  60. if (location.href !== lastUrl) {
  61. lastUrl = location.href;
  62. // Remove button if navigating away (prevents stale button)
  63. const oldBtn = document.getElementById('yt-embed-link-btn');
  64. if (oldBtn) oldBtn.remove();
  65. setTimeout(insertEmbedButton, 700); // Wait a bit for the new page to render
  66. }
  67. // Try to insert the button if not present (handles dynamic loading)
  68. if (!document.getElementById('yt-embed-link-btn')) {
  69. setTimeout(insertEmbedButton, 700);
  70. }
  71. });
  72.  
  73. observer.observe(document.body, { childList: true, subtree: true });
  74.  
  75. // Initial insert
  76. setTimeout(insertEmbedButton, 1000);
  77. })();