Netflix Volume and Time Mouse Controlled

Volume/Time mouse control for Netflix

安装此脚本
作者推荐脚本

您可能也喜欢Netflix seamless play

安装此脚本
  1. // ==UserScript==
  2. // @name Netflix Volume and Time Mouse Controlled
  3. // @namespace PoKeRGT
  4. // @version 2.00
  5. // @description Volume/Time mouse control for Netflix
  6. // @author PoKeRGT
  7. // @match https://www.netflix.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=netflix.com
  9. // @grant none
  10. // @run-at document-ready
  11. // @homepageURL https://github.com/PoKeRGT/userscripts
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17.  
  18. window.netflixVolumeMouseControl = false;
  19.  
  20. const getPlayer = () => {
  21. try {
  22. const nApi = netflix.appContext.state.playerApp.getAPI();
  23. const videoPlayer = nApi.videoPlayer;
  24. if (videoPlayer && videoPlayer.getVideoPlayerBySessionId && videoPlayer.getAllPlayerSessionIds) {
  25. const allSessionIds = videoPlayer.getAllPlayerSessionIds();
  26. const watchSessionIds = allSessionIds.filter(sid => sid.startsWith('watch-'));
  27. if (watchSessionIds.length > 0) {
  28. return videoPlayer.getVideoPlayerBySessionId(watchSessionIds[0]);
  29. } else if (allSessionIds.length > 0) {
  30. return videoPlayer.getVideoPlayerBySessionId(allSessionIds[0]);
  31. }
  32. }
  33. } catch (error) {
  34. return null;
  35. }
  36. return null;
  37. }
  38.  
  39. const moveToPosition = (player, timeMillis) => {
  40. player.seek(timeMillis);
  41. }
  42.  
  43. const limitRange = (minValue, maxValue, n) => {
  44. return Math.max(minValue, Math.min(maxValue, n));
  45. }
  46.  
  47. const handleMouseWheelEvent = (player, event) => {
  48. const videos = document.getElementsByTagName('video');
  49. const videoTag = (videos && videos.length === 1 ? videos[0] : null);
  50. const rect = videoTag.getBoundingClientRect();
  51. const width = videoTag.offsetWidth;
  52. const height = videoTag.offsetHeight;
  53. const x = event.clientX - rect.left; //x position within the element.
  54. const y = event.clientY - rect.top; //y position within the element.
  55. // console.log("Left? : " + x + " ; Top? : " + y + ".");
  56.  
  57. if ((width / 2) > x) {
  58. // console.log('isLeft');
  59. if (event.deltaY < 0) {
  60. const currVolume = player.getVolume();
  61. player.setVolume(limitRange(0, 1, currVolume + 0.1))
  62. } else {
  63. const currVolume = player.getVolume();
  64. player.setVolume(limitRange(0, 1, currVolume - 0.1))
  65. }
  66. } else {
  67. // console.log('isRight');
  68. if (event.deltaY < 0) {
  69. const newPosition = player.getCurrentTime() + 10000.0;
  70. moveToPosition(player, limitRange(0, player.getDuration(), newPosition));
  71. } else {
  72. const newPosition = player.getCurrentTime() - 10000.0;
  73. moveToPosition(player, limitRange(0, player.getDuration(), newPosition));
  74. }
  75. }
  76. }
  77.  
  78. const init = () => {
  79. if (location.href.includes('/watch/')) {
  80. const player = getPlayer();
  81.  
  82. if (player) {
  83. if (!window.netflixVolumeMouseControl) {
  84. console.log('Appending mouse control')
  85. document.body.addEventListener('wheel', handleMouseWheelEvent.bind(null, player), { passive: false });
  86. window.netflixVolumeMouseControl = true;
  87. } else {
  88. console.log('Event handler already added')
  89. }
  90. } else {
  91. console.log('No player found!')
  92. }
  93. } else {
  94. document.body.removeEventListener('wheel', handleMouseWheelEvent, { passive: false });
  95. window.netflixVolumeMouseControl = false;
  96. console.log('Not watching. Event removed')
  97. }
  98. }
  99.  
  100. // Set up a mutation observer to watch for url change to detect navigation
  101. var previousUrl = location.href;
  102. var observer = new MutationObserver(function (mutations) {
  103. // If URL changes...
  104. if (location.href !== previousUrl) {
  105. previousUrl = location.href;
  106.  
  107. console.log(`New URL: ${location.href}`);
  108. setTimeout(() => {
  109. init();
  110. }, 5000);
  111.  
  112. }
  113. });
  114.  
  115. // Mutation observer setup
  116. const config = { subtree: true, childList: true };
  117. setTimeout(() => {
  118. init();
  119. }, 5000);
  120. observer.observe(document, config);
  121. })();

QingJ © 2025

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