Sleazy Fork is available in English.

Download / Play - [ X ]

1) Auto play 2) Auto widescreen 3) High quality playback 4) Click to push the next video 5) Download thumbnail

  1. // ==UserScript==
  2. // @name Download / Play - [ X ]
  3. // @namespace http://tampermonkey.net/
  4. // @version 3.0
  5. // @copyright 2022, terifash (https://greasyfork.org/en/users/964055-teri-fash)
  6. // @author feri.fash <teri.fash@gmail.com>
  7. // @license MIT
  8. // @description 1) Auto play 2) Auto widescreen 3) High quality playback 4) Click to push the next video 5) Download thumbnail
  9. // @match *://*.xvideos.com/video*
  10. // @icon https://www.xvideos.com/favicon-32x32.png
  11. // @supportURL https://github.com/TeriFash/x.scripts.user/issues
  12. // @homepageURL https://github.com/TeriFash/x.scripts.user
  13. // @grant GM_download
  14. // @grant GM_xmlhttpRequest
  15. // @run-at document-end
  16. // @connect 127.0.0.1
  17. // ==/UserScript==
  18.  
  19. (function () {
  20.  
  21. const textMessages = {
  22. responseSucssesGood: 'Загрузка прошла успешно',
  23. responseSucssesBad: 'Не удалось выполнить загрузку',
  24. responseError: 'Ошибка отправки, откройте пакетный загрузчик M3U8 или проверьте занятость порта :8787',
  25. thumbbigWait: 'Идет загрузка миниатюры',
  26. thumbbigError: 'Миниатюра не найдена',
  27. downloadNotFound: 'Разбор, пожалуйста, скачайте позже'
  28. }
  29.  
  30. function init() {
  31. const download = (url) => {
  32. GM_xmlhttpRequest({
  33. method: "POST",
  34. url: "http://127.0.0.1:8787/",
  35. headers: {"Content-Type": "application/json"},
  36. data: JSON.stringify({
  37. data: url,
  38. type: "2",
  39. }),
  40. responseType: "json",
  41. onload: res => {
  42. res.response.stat && (showToast(textMessages.responseSucssesGood));
  43. res.response.stat || (showToast(textMessages.responseSucssesBad));
  44. },
  45. onerror: () => { showToast(textMessages.responseError) },
  46. });
  47. }
  48.  
  49. const showToast = (msg) => {
  50. let m = document.createElement("div");
  51. m.innerHTML = msg;
  52. m.style.cssText =
  53. "max-width:60%;min-width: 180px;padding:0 14px;height: 40px;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 18px;";
  54. document.body.appendChild(m);
  55. setTimeout(() => {
  56. let d = 0.5;
  57. m.style.transition = `-webkit-transform ${d}s ease-in, opacity ${d}s ease-in`;
  58. m.style.opacity = "0";
  59. setTimeout(() => {
  60. document.body.removeChild(m);
  61. }, d * 1000);
  62. }, 2000);
  63. }
  64.  
  65. html5player.player_init && (html5player.toggleExpand());
  66.  
  67. const downloadBtn = document.querySelector("button.dl.tab-button");
  68. downloadBtn.insertAdjacentHTML('afterend', '<button class="dl" id="thumbbig"><span class="icon-f icf-image"></span><span>Миниатюра</span></button>');
  69.  
  70. document.getElementById('thumbbig').onclick = () => {
  71. if (!!html5player.thumb_slide_big) {
  72. let thumbUrl = html5player.thumb_slide_big;
  73. let videoTittle = document.querySelector("p.video-title").innerText;
  74. GM_download(thumbUrl, videoTittle + '.jpg');
  75. showToast(textMessages.thumbbigWait);
  76. } else {
  77. showToast(textMessages.thumbbigError);
  78. }
  79. }
  80.  
  81. downloadBtn.addEventListener('click', e => {
  82. e.stopImmediatePropagation();
  83. if (!!html5player.hlsobj.levels) {
  84. let m3u8 = html5player.hlsobj.levels.slice(-1)[0].url[0];
  85. let videoTittle = document.querySelector("p.video-title").innerText;
  86. download(videoTittle + "," + m3u8);
  87. } else {
  88. showToast(textMessages.downloadNotFound);
  89. }
  90. }, true);
  91.  
  92. Object.defineProperties(html5player.hlsobj, {
  93. autoLevelEnabled: { value: false, writable: false },
  94. firstLevel: { value: 4, writable: false },
  95. })
  96.  
  97. let playValue = false;
  98.  
  99. Object.defineProperty(html5player, 'canPlay', {
  100. get: () => playValue,
  101. set: (val) => {
  102. val && (html5player.playClicked = true);
  103. val && (html5player.play());
  104. playValue = val;
  105. }
  106. });
  107. }
  108.  
  109. window.addEventListener('DOMContentLoaded', init);
  110. })();