Youtube loop state keeper

To Loop or not To Loop is Yes

  1. // ==UserScript==
  2. // @name Youtube loop state keeper
  3. // @namespace https//mmis1000.me/
  4. // @version 0.1
  5. // @description To Loop or not To Loop is Yes
  6. // @author mmis1000
  7. // @match https://www.youtube.com/watch?*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13. const NS = "mmis1000";
  14.  
  15. let loopState = sessionStorage.getItem(NS + '_loopState');
  16. let videoElement = document.querySelectorAll('video')[0];
  17.  
  18. if (loopState) {
  19. setTimeout(function () {
  20. try {
  21. let oldState = JSON.parse(loopState);
  22.  
  23. if (oldState.loop) {
  24. try {
  25. // force the menu to populate
  26. // as youtube only populate the menu after you do a right click
  27. var e = videoElement.ownerDocument.createEvent('MouseEvents');
  28.  
  29. e.initMouseEvent('contextmenu', true, true,
  30. videoElement.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
  31. false, false, false,2, null);
  32.  
  33. videoElement.dispatchEvent(e);
  34. videoElement.click()
  35.  
  36. let loopButton = Array.prototype.slice.call(document.querySelectorAll('.ytp-menuitem'), 0).filter((el)=>el.textContent.indexOf('循環播放') >= 0)[0];
  37. loopButton.click()
  38. console.log('restoring loop state...')
  39. } catch (e) {
  40. videoElement.loop = oldState.loop;
  41. console.log('restoring loop state... (fallback to set video element loop attr)')
  42. }
  43. }
  44. } catch(e) {}
  45.  
  46. let prevState = videoElement.loop;
  47.  
  48. videoElement.addEventListener("timeupdate", function () {
  49. if (prevState !== videoElement.loop) {
  50. console.log('updating loop state...')
  51. prevState = videoElement.loop;
  52. sessionStorage.setItem(NS + '_loopState', JSON.stringify({loop: videoElement.loop}));
  53. }
  54. })
  55. }, 0);
  56. }
  57. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址