百度网盘视频倍速播放-滑动条版

视频内外部添加可拖动的调节视频倍速的滑动条(初始化倍速:max:2.0,min:0.5,step:0.05,val:1.0)。视频音量条设置为竖直方向(初始化音量:vol:20%)。 //\\//\\ 脚本412-416行,用户可进行对倍速(max,min,step,val)、音量(vol)的初始化设置。 //\\//\\ 支持各种快捷键调节视频,脚本299-349行可进行快捷键键位修改 //\\//\\ 在当前网页切换视频时,保持用户设置的音量和倍速

目前為 2019-10-20 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name 百度网盘视频倍速播放-滑动条版
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.2
  5. // @description 视频内外部添加可拖动的调节视频倍速的滑动条(初始化倍速:max:2.0,min:0.5,step:0.05,val:1.0)。视频音量条设置为竖直方向(初始化音量:vol:20%)。 //\\//\\ 脚本412-416行,用户可进行对倍速(max,min,step,val)、音量(vol)的初始化设置。 //\\//\\ 支持各种快捷键调节视频,脚本299-349行可进行快捷键键位修改 //\\//\\ 在当前网页切换视频时,保持用户设置的音量和倍速
  6. // @author fajiao
  7. // @match *://pan.baidu.com/play/video*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. 'use strict';
  13.  
  14. var DocUtil = {
  15. insertAfter: function (targetElm, newElm) {
  16. if (targetElm && newElm) {
  17. let parent = targetElm.parentNode;
  18. if (parent.lastChild == targetElm) {
  19. parent.appendChild(newElm);
  20. } else {
  21. parent.insertBefore(newElm, targetElm.nextSibling)
  22. }
  23. }
  24. },
  25. addEventListener: function (obj, event, func) {
  26. if (obj && (typeof obj == "object") && (typeof event == "string") && (typeof func == "function")) {
  27. obj.addEventListener(event, func);
  28. }
  29. },
  30. removeEventListener: function (obj, event, func) {
  31. if (obj && (typeof obj == "object") && (typeof event == "string") && (typeof func == "function")) {
  32. obj.removeEventListener(event, func);
  33. }
  34. },
  35. addStyleRule(style, rule, index) {
  36. if (style) {
  37. let sheet = style.sheet || style.styleSheet || {};
  38. index = index || sheet.cssRules.length || 0;
  39. if (sheet.insertRule) {
  40. sheet.insertRule(rule, index);
  41. } else if (sheet.addRule) {
  42. // sheet.addRule(selectorText, cssText, index);
  43. }
  44. }
  45. },
  46. addStyleRules(style, rules) {
  47. if (style && typeof style == "object" && "innerText" in style) {
  48. style.innerText += rules;
  49. }
  50. },
  51. log() {
  52. console.log(arguments);
  53. }
  54. };
  55.  
  56. function SpeedComponentUtil(config) {
  57. var _config = {};
  58. var _component = {};
  59. var _style = {};
  60.  
  61. init(config);
  62.  
  63. function init(config) {
  64. initConfig(config);
  65. initOuterComponent();
  66. initInnerComponent();
  67. }
  68.  
  69. function initConfig(config) {
  70. config = config || {};
  71. _config.max = config.max || 2.0;
  72. _config.min = config.min || 0.5;
  73. _config.step = config.step || 0.05;
  74. _config.val = config.val || 1.0;
  75. _config.vol = config.vol || 0.2;
  76. }
  77.  
  78. function initOuterComponent() {
  79. let outerSpeedDiv = document.createElement("div");
  80. let outerLayerDiv = document.createElement("div");
  81. let outerSpeedSlider = document.createElement("input");
  82. let outerSpeedTip = document.createElement("span");
  83.  
  84. outerSpeedDiv.id = "outerSpeedDiv";
  85. outerLayerDiv.id = "outerLayerDiv";
  86.  
  87. outerSpeedSlider.type = "range";
  88. outerSpeedSlider.max = _config.max;
  89. outerSpeedSlider.min = _config.min;
  90. outerSpeedSlider.step = _config.step;
  91. outerSpeedSlider.value = _config.val;
  92. outerSpeedTip.innerText = ${_config.val.toFixed(2)}`;
  93.  
  94. outerSpeedDiv.appendChild(outerLayerDiv);
  95. outerLayerDiv.appendChild(outerSpeedSlider);
  96. outerLayerDiv.appendChild(outerSpeedTip);
  97.  
  98. _component.outerSpeedDiv = outerSpeedDiv;
  99. _component.outerLayerDiv = outerLayerDiv;
  100. _component.outerSpeedSlider = outerSpeedSlider;
  101. _component.outerSpeedTip = outerSpeedTip;
  102. initOuterComponentStyle();
  103. }
  104.  
  105. function initInnerComponent() {
  106. let innerSpeedDiv = document.createElement("div");
  107. let innerLayerSliderDiv = document.createElement("div");
  108. let innerSpeedSlider = document.createElement("input");
  109. let innerLayerTipDiv = document.createElement("div");
  110. let innerSpeedTip = document.createElement("span");
  111.  
  112. innerSpeedDiv.id = "innerSpeedDiv";
  113. innerLayerTipDiv.id = "innerLayerTipDiv";
  114. innerLayerSliderDiv.id = "innerLayerSliderDiv";
  115.  
  116. innerSpeedSlider.type = "range";
  117. innerSpeedSlider.max = _config.max;
  118. innerSpeedSlider.min = _config.min;
  119. innerSpeedSlider.step = _config.step;
  120. innerSpeedSlider.value = _config.val;
  121. innerSpeedTip.innerText = ${_config.val.toFixed(2)}`;
  122.  
  123. innerSpeedDiv.appendChild(innerLayerTipDiv);
  124. innerLayerTipDiv.appendChild(innerSpeedTip);
  125. innerSpeedDiv.appendChild(innerLayerSliderDiv);
  126. innerLayerSliderDiv.appendChild(innerSpeedSlider);
  127.  
  128. _component.innerSpeedDiv = innerSpeedDiv;
  129. _component.innerLayerSliderDiv = innerLayerSliderDiv;
  130. _component.innerSpeedSlider = innerSpeedSlider;
  131. _component.innerLayerTipDiv = innerLayerTipDiv;
  132. _component.innerSpeedTip = innerSpeedTip;
  133. initInnerComponentStyle();
  134. }
  135.  
  136. function initOuterComponentStyle() {
  137. let style = _style.outerSpeedComponentStyle || document.getElementById("outerSpeedComponentStyle") || (function () {
  138. let style = document.createElement('style');
  139. style.type = 'text/css';
  140. style.id = "outerSpeedComponentStyle";
  141. _component.outerSpeedDiv.appendChild(style);
  142. _style.outerSpeedComponentStyle = style;
  143. return style;
  144. })();
  145.  
  146. DocUtil.addStyleRules(style, `
  147. #outerSpeedDiv{width:155px;height:auto;margin:0 0 0 30px;display:inline-block}
  148. #outerLayerDiv{width:140px;height:35px;text-align:left;display:table-cell;vertical-align:middle;padding-left:10px;padding-right:10px}
  149. #outerLayerDiv span{font-size:16px;font-weight:bold;color:black}
  150. #outerLayerDiv input[type=range]{-webkit-appearance:none;width:100px;height:10px;background:transparent;transform:translateY(-2px);outline:0}
  151. #outerLayerDiv input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:#fafbf2;border:2.5px solid black;margin-top:-6px;cursor:pointer}
  152. #outerLayerDiv input[type=range]::-webkit-slider-runnable-track{width:100%;height:5px;border-radius:5px;background:#48abee;cursor:pointer}
  153. #outerLayerDiv input[type=range]::-moz-range-thumb{width:15px;height:15px;border-radius:50%;background:#fafbf2;border:2.5px solid black;cursor:pointer}
  154. #outerLayerDiv input[type=range]::-moz-range-track{width:100%;height:5px;border-radius:5px;background:#2497e3;cursor:pointer}
  155. #outerSpeedDiv .noWork{background:#c5c4c9;pointer-events:none}
  156. `);
  157. }
  158.  
  159. function initInnerComponentStyle() {
  160. let style = _style.innerSpeedComponentStyle || document.getElementById("innerSpeedComponentStyle") || (function () {
  161. let style = document.createElement('style');
  162. style.type = 'text/css';
  163. style.id = "innerSpeedComponentStyle";
  164. _component.innerSpeedDiv.appendChild(style);
  165. _style.innerSpeedComponentStyle = style;
  166. return style;
  167. })();
  168.  
  169. DocUtil.addStyleRules(style, `
  170. #innerSpeedDiv{width:50px;height:auto}
  171. #innerLayerTipDiv{width:100%;height:36px;background:transparent}
  172. #innerLayerTipDiv span{width:100%;height:100%;font-size:16px;font-weight:bold;color:white;text-align:center;display:inline-block;line-height:36px}
  173. #innerLayerSliderDiv{width:auto;height:50px;background:rgba(43,51,63,.7);display:table-cell;vertical-align:middle;transform-origin:left top;transform:translateY(-36px) rotate(-90deg)}
  174. #innerLayerSliderDiv input[type=range]{-webkit-appearance:none;width:100px;height:10px;background:transparent;outline:0}
  175. #innerLayerSliderDiv input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:#fafbf2;transform:translateY(-6px);border:2.5px solid black;cursor:pointer}
  176. #innerLayerSliderDiv input[type=range]::-webkit-slider-runnable-track{width:100%;height:5px;border-radius:5px;background:#48abee;cursor:pointer}
  177. #innerLayerSliderDiv input[type=range]::-moz-range-thumb{width:15px;height:15px;border-radius:50%;background:#fafbf2;border:2.5px solid black;cursor:pointer}
  178. #innerLayerSliderDiv input[type=range]::-moz-range-track{width:100%;height:5px;border-radius:5px;background:#2497e3;cursor:pointer}
  179. #innerSpeedDiv .noWork{display:none}
  180. `);
  181. }
  182.  
  183. this.getComponent = function (componentStr) {
  184. return componentStr ? _component[componentStr] : _component;
  185. }
  186. }
  187.  
  188. function SpeedUtil(config) {
  189. var _config = {};
  190. var _scUtil = null;
  191. var _cmpnt = null;
  192. var _state = null;
  193. var _priorId = null;
  194. var _h5player = null;
  195.  
  196. init(config);
  197.  
  198. function init(config) {
  199. initConfig(config);
  200. initParameter();
  201. initOuterComponentPosition();
  202. startLoadState();
  203. findH5player((_priorId = new Date().getTime()), 1);
  204. initListener();
  205. }
  206.  
  207. function initConfig(config) {
  208. config = config || {};
  209. _config.max = config.max || 2.0;
  210. _config.min = config.min || 0.5;
  211. _config.step = config.step || 0.05;
  212. _config.val = config.val || 1.0;
  213. _config.vol = config.vol || 0.2;
  214. }
  215.  
  216. function initParameter() {
  217. _scUtil = new SpeedComponentUtil(_config);
  218. _cmpnt = _scUtil.getComponent();
  219. }
  220.  
  221. function initOuterComponentPosition() {
  222. let toolbar = document.querySelector(".video-toolbar-buttonbox");
  223. DocUtil.insertAfter(toolbar.lastChild, _cmpnt.outerSpeedDiv);
  224. }
  225.  
  226. function initInnerComponentPosition(volbtn) {
  227. DocUtil.insertAfter(volbtn, _cmpnt.innerSpeedDiv);
  228. }
  229.  
  230. function findH5player(curId, num) {
  231. if (curId != _priorId) {
  232. // console.log("abort", curId, num, new Date().getTime());
  233. return;
  234. }
  235. if (num >= 45) {
  236. // console.log("timeout", curId, num, new Date().getTime());
  237. return;
  238. }
  239. let player = getH5player();
  240. if (player) {
  241. // console.log("success", curId, num, new Date().getTime());
  242. stopLoadState(player);
  243. } else {
  244. // console.log("failure", curId, num, new Date().getTime());
  245. setTimeout(function () {
  246. findH5player(curId, ++num);
  247. }, 1000);
  248. }
  249. }
  250.  
  251. function initListener() {
  252. DocUtil.addEventListener(_cmpnt.outerSpeedSlider, "input", function () {
  253. // console.log("outer", "input", _cmpnt.outerSpeedSlider.value);
  254. let player = _h5player || getH5player();
  255. if (player) {
  256. player.tech_.setPlaybackRate(_cmpnt.outerSpeedSlider.value);
  257. }
  258. });
  259.  
  260. DocUtil.addEventListener(_cmpnt.innerSpeedSlider, "input", function () {
  261. // console.log("inner", "input", _cmpnt.innerSpeedSlider.value);
  262. let player = _h5player || getH5player();
  263. if (player) {
  264. player.tech_.setPlaybackRate(_cmpnt.innerSpeedSlider.value);
  265. }
  266. });
  267.  
  268. DocUtil.addEventListener(_cmpnt.innerLayerTipDiv, "mouseover", function () {
  269. _cmpnt.innerLayerSliderDiv.classList.remove("noWork");
  270. });
  271. DocUtil.addEventListener(_cmpnt.innerLayerTipDiv, "mouseout", function () {
  272. _cmpnt.innerLayerSliderDiv.classList.add("noWork");
  273. });
  274. DocUtil.addEventListener(_cmpnt.innerLayerSliderDiv, "mouseover", function () {
  275. _cmpnt.innerLayerSliderDiv.classList.remove("noWork");
  276. });
  277. DocUtil.addEventListener(_cmpnt.innerLayerSliderDiv, "mouseout", function () {
  278. _cmpnt.innerLayerSliderDiv.classList.add("noWork");
  279. });
  280.  
  281. DocUtil.addEventListener(window, "popstate", function () {
  282. let curId = new Date().getTime();
  283. _priorId = curId;
  284. startLoadState();
  285. setTimeout(function () {
  286. findH5player(curId, 1)
  287. }, 3000);
  288. });
  289.  
  290. DocUtil.addEventListener(document, "keypress", function (e) {
  291. let player = _h5player || getH5player();
  292. let curPlayElm = document.querySelector(".currentplay") || {};
  293. if (_state == "stopLoad") {
  294. if (player) {
  295. let speed = _config.val;
  296. let step = _config.step;
  297. let max = _config.max;
  298. let min = _config.min;
  299. switch (e.key) {
  300. case "c":
  301. //加速
  302. player.tech_.setPlaybackRate((((speed + step)) < max ? (speed + step) : max));
  303. break;
  304. case "x":
  305. //还原
  306. player.tech_.setPlaybackRate(1);
  307. break;
  308. case "z":
  309. //减速
  310. player.tech_.setPlaybackRate((((speed - step) > min) ? (speed - step) : min));
  311. break;
  312. case "f":
  313. //全屏
  314. player.controlBar.fullscreenToggle.el_.click();
  315. break;
  316. case "m":
  317. //画中画
  318. if (document.pictureInPictureEnabled) {
  319. if (!document.pictureInPictureElement) {
  320. player.tech_.el_.requestPictureInPicture();
  321. } else {
  322. document.exitPictureInPicture();
  323. }
  324. }
  325. break;
  326. }
  327. }
  328. }
  329. switch (e.key) {
  330. case "d":
  331. //开关灯
  332. document.querySelector(".video-functions-last").click();
  333. break;
  334. case "b":
  335. //前一个视频
  336. if (curPlayElm.previousSibling) {
  337. curPlayElm.previousSibling.firstChild.click();
  338. }
  339. break;
  340. case "n":
  341. //后一个视频
  342. if (curPlayElm.nextSibling) {
  343. curPlayElm.nextSibling.firstChild.click();
  344. }
  345. break;
  346. case "h":
  347. window.alert("快捷键提醒:\nz:减速,x:还原,c:加速\nd:开关灯,f:全屏\nb:前一个视频,n:后一个视频,m:画中画\nh:帮助\n脚本299-349行可进行快捷键键位修改");
  348. break;
  349. }
  350. });
  351. }
  352.  
  353. function startLoadState() {
  354. _state = "startLoad";
  355. // console.log("load start",new Date().getTime());
  356. _cmpnt.outerLayerDiv.classList.add("noWork");
  357. _cmpnt.innerLayerSliderDiv.classList.add("noWork");
  358. _h5player = null;
  359. }
  360.  
  361. function stopLoadState(player) {
  362. _state = "stopLoad";
  363. // console.log("load stop",new Date().getTime());
  364.  
  365. let bar = player.controlBar;
  366. bar.removeChild("volumeMenuButton");
  367. let volbtn = (bar.addChild("volumeMenuButton", {
  368. inline: false
  369. }, 1)).el_;
  370. initInnerComponentPosition(volbtn);
  371.  
  372. _cmpnt.outerLayerDiv.classList.remove("noWork");
  373. _h5player = player;
  374.  
  375. DocUtil.addEventListener(player.tech_.el_, "ratechange", function () {
  376. let player = _h5player || getH5player();
  377. if (player) {
  378. let speedStr = player.tech_.playbackRate().toFixed(2);
  379. let speedNum = parseFloat(speedStr);
  380. // console.log("ratechange", speed, new Date().getTime());
  381. _config.val = speedNum;
  382. _cmpnt.outerSpeedSlider.value = speedNum;
  383. _cmpnt.outerSpeedTip.innerText = ${speedStr}`;
  384. _cmpnt.innerSpeedSlider.value = speedNum;
  385. _cmpnt.innerSpeedTip.innerText = ${speedStr}`;
  386. }
  387. });
  388. DocUtil.addEventListener(player.tech_.el_, "volumechange", function () {
  389. let player = _h5player || getH5player();
  390. if (player) {
  391. let vol = parseFloat(player.tech_.volume().toFixed(2));
  392. // console.log("volumechange", vol, new Date().getTime());
  393. _config.vol = vol;
  394. }
  395. });
  396. player.tech_.el_.oncanplay = function () {
  397. let speed = parseFloat(_config.val.toFixed(2));
  398. let vol = _config.vol;
  399. player.tech_.setPlaybackRate(speed);
  400. player.tech_.setVolume(vol);
  401. player.tech_.el_.oncanplay = null;
  402. }
  403. }
  404.  
  405. function getH5player() {
  406. return window.videojs ? window.videojs.getPlayers().html5player : null;
  407. }
  408. }
  409.  
  410. DocUtil.addEventListener(window, "load", function () {
  411. new SpeedUtil({
  412. max: 2.0, //最大倍速值
  413. min: 0.5, //最小倍速值
  414. step: 0.05, //步进值
  415. val: 1.0, //初始倍速值
  416. vol: 0.23, //初始音量值
  417. });
  418. });
  419. })();

QingJ © 2025

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