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