- // ==UserScript==
- // @name erome.com video length
- // @namespace https://github.com/drdre1/
- // @icon https://www.erome.com/favicon.ico
- // @version 1.0
- // @description Duration of video on erome.com
- // @author drdre1
- // @match https://www.erome.com/*
- // @grant GM.xmlHttpRequest
- // ==/UserScript==
-
- (function () {
-
- const onLength = function (milliseconds, a, video) {
- let s = milliseconds / 1000;
- const h = Math.floor(s / 3600);
- s -= h * 3600;
- const m = Math.floor(s / 60);
- s = Math.floor(s - m * 60);
-
- const span = document.createElement('span');
- span.appendChild(document.createTextNode(` ${h > 0 ? `${h}:` : ''}${h > 0 ? m.toString().padStart(2, '0') : m}:${s.toString().padStart(2, '0')}`));
- a.parentNode.insertBefore(span, a.nextElementSibling || a);
-
- if (video && video.dataset) {
- s = parseInt(milliseconds / 1000);
- video.dataset.length = s;
- const slider = document.getElementById('slider_min_length');
- if (slider) {
- slider.max = Math.max(slider.max, s);
- }
- }
- };
-
- const videoLength = function (url, a, video) {
- const storedTime = window.localStorage.getItem(`$vl#${url}`);
- if (storedTime && !isNaN(parseInt(storedTime))) {
- const t = parseInt(storedTime);
- if (t >= 0) {
- return onLength(t, a, video);
- }
- }
-
- const xmlHttpRequest = GM.xmlHttpRequest({
- url,
- method: 'GET',
- headers: {
- Accept: 'video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5',
- Referer: 'https://www.erome.com/',
- Range: 'bytes=0-140',
- },
- responseType: 'blob',
- onprogress(response) {
- if (Math.max(response.loaded, response.total) > 150) {
- xmlHttpRequest.abort();
- }
- },
- onload(response) {
- const m = response.responseText.match(/\x03.*\xe8/);
- if (m) {
- const i = response.responseText.indexOf(m[0]) + m[0].length;
- const s = response.responseText.substring(i, i + 4);
- const ms = Array.from(s)
- .map((c) => c.charCodeAt(0))
- .map((value, index, values) => value * Math.pow(256, values.length - index - 1))
- .reduce((a, b) => a + b);
- window.localStorage.setItem(`$vl#${url}`, ms);
- return onLength(ms, a, video);
- }
- },
- });
- };
-
- const showSlider = function () {
- const div = document.body.appendChild(document.createElement('div'));
- div.setAttribute('style', 'position:fixed; right:0px; top:50px');
- div.innerHTML = 'Minimal length:<br>';
- const output = div.appendChild(document.createElement('output'));
- output.setAttribute('id', 'slider_min_length_output');
- const slider = div.appendChild(document.createElement('input'));
- slider.setAttribute('id', 'slider_min_length');
- slider.setAttribute('type', 'range');
- slider.setAttribute('step', '1');
- slider.setAttribute('min', '1');
- slider.setAttribute('max', '5');
- slider.setAttribute('value', '1');
- slider.addEventListener('input', () => {
- const minS = parseInt(slider.value);
- if (minS > 1) {
- const m = parseInt(slider.value / 60);
- const s = minS - m * 60;
- output.textContent = `${m}:${s > 9 ? s : (`0${s}`)}`;
- document.querySelectorAll('.video')
- .forEach((vc) => {
- const video = vc.querySelector('.player video');
- if (video && 'length' in video.dataset && video.dataset.length < minS) {
- vc.style.display = 'none';
- } else {
- vc.style.display = '';
- }
- });
- } else {
- output.textContent = 'Off';
- document.querySelectorAll('.video')
- .forEach((vc) => {
- vc.style.display = '';
- });
- }
- });
- };
-
- let minNumberOfVideos = 0;
- const showOnlyVideosThumbs = function () {
- document.querySelectorAll('.album')
- .forEach((album) => {
- const e = album.querySelector('.album-videos');
- if (e && e.textContent && parseInt(e.textContent) && parseInt(e.textContent) >= minNumberOfVideos) {
- return;
- }
- album.style.display = 'none';
- });
- };
-
- const showOnlyVideos = function (ev) {
- if (ev) {
- ev.preventDefault();
- }
- minNumberOfVideos++;
- if (document.location.hash.match(/onlyvideos=(\d+)/)) {
- document.location.hash = document.location.hash.replace(/onlyvideos=\d+/, `onlyvideos=${minNumberOfVideos}`);
- } else {
- document.location.hash = `#onlyvideos=${minNumberOfVideos}`;
- }
- if (document.location.pathname.startsWith('/a/')) {
- showOnlyVideosAlbum();
- } else {
- showOnlyVideosThumbs();
- }
- document.querySelectorAll('a[href]')
- .forEach((a) => {
- a.hash = `#onlyvideos=${minNumberOfVideos}`;
- });
- };
-
- const showOnlyVideosAlbum = function () {
- document.querySelectorAll('.media-group')
- .forEach((mediaGroup) => {
- if (!mediaGroup.querySelector('.video')) {
- mediaGroup.remove();
- }
- });
- };
-
- const disableShowOnlyVideos = function (ev) {
- if (ev) {
- ev.preventDefault();
- }
- document.location.hash = '';
- document.location.reload();
- };
-
- if (document.querySelectorAll('video')
- .length > 1) {
- showSlider();
- }
- window.requestAnimationFrame(() => {
- document.querySelectorAll('.player video source')
- .forEach((source) => {
- const url = source.src;
- const a = document.createElement('a');
- a.href = url;
- a.appendChild(document.createTextNode(url));
- a.target = '_blank';
- source.parentNode.parentNode.parentNode.insertBefore(a, source.parentNode.parentNode);
- videoLength(url, a, source.parentNode);
- });
- });
-
- if (document.querySelector('#app-navbar-collapse ul.navbar-right')) {
- const a = document.querySelector('#app-navbar-collapse ul.navbar-right')
- .appendChild(document.createElement('li'))
- .appendChild(document.createElement('a'));
- a.href = `#onlyvideos=${minNumberOfVideos + 1}`;
- a.title = 'Right click to disable';
- a.addEventListener('click', showOnlyVideos);
- a.addEventListener('contextmenu', disableShowOnlyVideos);
- a.appendChild(document.createTextNode('only videos'));
- }
-
- if (document.location.hash.match(/onlyvideos=(\d+)/)) {
- const n = parseInt(document.location.hash.match(/onlyvideos=(\d+)/)[1]);
- for (let i = 0; i < n; i++) {
- showOnlyVideos();
- }
- }
- }());