Click on video thumbnail to play in MPV

Open videos in external player (mpv) by simply clicking on a thumbnail.

当前为 2021-06-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Click on video thumbnail to play in MPV
  3. // @name:en-US Click on video thumbnail to play in MPV
  4. // @name:ru-RU Нажми на митиатюру для проигрывания в MPV
  5. // @namespace nsinister.scripts.videothumb2mpv
  6. // @match https://*.youtube.com/*
  7. // @match https://vimeo.com/*
  8. // @grant none
  9. // @version 0.1
  10. // @author nSinister
  11. // @license MIT
  12. // @description Open videos in external player (mpv) by simply clicking on a thumbnail.
  13. // @description:en-US Open videos in external player (mpv) by simply clicking on a thumbnail.
  14. // @description:ru-RU Проигрывайте ролики во внешнем mpv плеере просто нажав на миниатюру
  15. //
  16. // ==/UserScript==
  17.  
  18. "use strict";
  19.  
  20.  
  21. let observer;
  22. let listeners = [];
  23.  
  24. let sites = {
  25. "youtube.com": { sel: "a.ytd-thumbnail", url: "https://www.youtube.com", needsFullUrl: true },
  26. "vimeo.com": { sel: "a.iris_video-vital__overlay", url: "https://vimeo.com", needsFullUrl: false },
  27. };
  28.  
  29. // Watches for new elements based on selector to appear on page and assigns a function to them
  30. function ready(selector, func) {
  31. listeners.push({ selector: selector, func: func });
  32. if (!observer) {
  33. observer = new MutationObserver(checkDOM);
  34. observer.observe(document.documentElement, { childList: true, subtree: true });
  35. }
  36. checkDOM();
  37. }
  38.  
  39. function checkDOM() {
  40. for (let i = 0, len = listeners.length, listener, elements; i < len; i++) {
  41. listener = listeners[i];
  42. elements = document.querySelectorAll(listener.selector);
  43. for (let j = 0, jlen = elements.length, element; j < jlen; j++) {
  44. element = elements[j];
  45. if (!element.ready) {
  46. element.ready = true;
  47. listener.func.call(element, element);
  48. }
  49. }
  50. }
  51. }
  52.  
  53. // Replaces https:// hyperlinks with mpv:// and overrides click event
  54. function replaceLink(node, site) {
  55. if(node) {
  56. let hrefval = node.getAttribute('href');
  57. if (hrefval == null || hrefval.startsWith("mpv"))
  58. return;
  59. let newval = "mpv://" + btoa( (site.needsFullUrl ? site.url : "") + hrefval);
  60. node.setAttribute('href', newval);
  61. node.addEventListener('click', function(event){
  62. event.preventDefault();
  63. event.stopPropagation();
  64. location.href = newval;
  65. });
  66. }
  67. }
  68.  
  69. // Detects and returns current site from the list of known websites
  70. function detectSite(sites) {
  71. let site;
  72. for (let s in sites) {
  73. site = sites[s];
  74. if (location.href.includes(s)) {
  75. return site;
  76. }
  77. }
  78. return null;
  79. }
  80.  
  81. let site = detectSite(sites)
  82. if (site) {
  83. ready(site.sel, function(element) {
  84. replaceLink(element, site);
  85. });
  86. }