Redirect to Invidious

Redirects YouTube videos to an Invidious instance.

当前为 2023-10-22 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Redirect to Invidious
  3. // @author André Kugland
  4. // @description Redirects YouTube videos to an Invidious instance.
  5. // @namespace https://github.com/kugland
  6. // @license MIT
  7. // @version 0.2.10
  8. // @match *://*.youtube.com/
  9. // @match *://*.youtube.com/*
  10. // @run-at document-start
  11. // @noframes
  12. // @homepageURL https://greasyfork.org/scripts/477967-redirect-to-invidious
  13. // ==/UserScript==
  14. "use strict";
  15. const instanceKey = 'invidious-redirect-instance';
  16. const defaultInstance = 'https://yewtu.be';
  17. // Get the Invidious instance URL from the user.
  18. localStorage.getItem(instanceKey) || localStorage.setItem(instanceKey, defaultInstance);
  19. function makeUrl(videoId) {
  20. const instance = localStorage.getItem(instanceKey);
  21. // Let's construct a URL object to make sure it's valid.
  22. return new URL(`${instance}/watch?v=${videoId}`).href;
  23. }
  24. function getVideoId(href) {
  25. var _a;
  26. const url = new URL(href, window.location.href);
  27. if (url.pathname === '/watch') {
  28. return url.searchParams.get('v');
  29. }
  30. else {
  31. const videoId = (_a = url.pathname.match(/^\/shorts\/([a-zA-Z0-9_-]+)$/)) === null || _a === void 0 ? void 0 : _a[1];
  32. if (videoId)
  33. return videoId;
  34. }
  35. throw new Error(`Unable to parse URL: ${href}`);
  36. }
  37. // Redirect on click.
  38. document.addEventListener('click', (event) => {
  39. var _a;
  40. if (event.target instanceof HTMLElement) {
  41. try {
  42. const href = (_a = event.target.closest('a')) === null || _a === void 0 ? void 0 : _a.getAttribute('href');
  43. if (href) {
  44. event.preventDefault();
  45. event.stopPropagation();
  46. window.location.assign(makeUrl(getVideoId(href)));
  47. }
  48. }
  49. catch (e) { }
  50. }
  51. }, true);
  52. // Redirect on url change.
  53. let currentUrl = window.location.href;
  54. setInterval(() => {
  55. if (window.location.href !== currentUrl) {
  56. currentUrl = window.location.href;
  57. try {
  58. window.location.replace(makeUrl(getVideoId(currentUrl)));
  59. }
  60. catch (e) { }
  61. }
  62. }, 150);
  63. // Redirect on page load.
  64. try {
  65. window.location.replace(makeUrl(getVideoId(currentUrl)));
  66. }
  67. catch (e) { }
  68. // Add a settings button.
  69. ((fn) => {
  70. if (document.readyState !== 'loading')
  71. fn();
  72. else
  73. document.addEventListener('DOMContentLoaded', fn);
  74. })(() => {
  75. const css = document.createElement('style');
  76. css.textContent = `
  77. #set-invidious-url {
  78. position: fixed;
  79. bottom: 0;
  80. right: 0;
  81. height: 48px;
  82. width: 48px;
  83. z-index: 99999;
  84. margin: 1rem;
  85. cursor: pointer;
  86. border-radius: 50%;
  87. box-shadow: 0px 0px 3px black;
  88. opacity: 0.5;
  89. }
  90. #set-invidious-url:hover {
  91. opacity: 1;
  92. bottom: 1px;
  93. right: 1px;
  94. }
  95. `;
  96. document.head.appendChild(css);
  97. const button = document.createElement('img');
  98. button.id = 'set-invidious-url';
  99. button.tabIndex = -1;
  100. button.src = `
  101. data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAJFBMVEXv8e7
  102. Z4ePn6+kWt/CZzvChpKFrbWrT1dJVV1WJjIm2uLXCxMH33HXYAAAAp0lEQVR4AeXNIQ7CMABG4ceSsXSY
  103. IXFVFaCAC5BwgblNV4HDkMwiIA0YDMnkDMHWoHY5PPwGSfjsE4+fNbZIyXIBOszR1iu+lICWFmiuRGsOa
  104. PURbXOyKINb6FDyR/AoZlefURyNnuwxelKR6YmHVk2yK3qSd+iJKdATB9Be+PAEPakATIi8STzISVaiJ2
  105. lET4YFejIBPbmDnEy3ETmZ9REARr3lP7wAXHImU2sAU14AAAAASUVORK5CYII=
  106. `.replace(/\s/g, '');
  107. button.addEventListener('click', () => {
  108. let instance = prompt('Enter the URL of the Invidious instance to use:', localStorage.getItem(instanceKey) || defaultInstance);
  109. instance = instance.replace(/^\s*(.*)\/*\s*$/, '$1');
  110. try {
  111. new URL(instance); // Make sure it's a valid URL.
  112. localStorage.setItem(instanceKey, instance);
  113. }
  114. catch (e) {
  115. alert(`The URL you entered is invalid: ${instance}`);
  116. }
  117. });
  118. document.body.appendChild(button);
  119. });