- // ==UserScript==
- // @name Erome Video Cloner
- // @namespace http://tampermonkey.net/
- // @version 0.9.900
- // @description clone videos in an erome album, play multiple & side-by-side!
- // @author throwinglove23
- // @license MIT
- // @match https://www.erome.com/a/*
- // @match http://www.erome.com/a/*
- // @match https://www.erome.com/*
- // @exclude http://www.erome.com/a/*/edit
- // @exclude https://www.erome.com/a/*/edit
- // @icon https://www.erome.com/favicon-32x32.png
- // @grant none
- // @supportURL https://github.com/wflover23/erome-multi-tool
- // ==/UserScript==
- /* jshint esversion: 8 */
-
- function mainFunction() {
- 'use strict';
- // removing default seek functions
- document.onkeydown = null;
- window.addEventListener('keydown', function(e) {
- // avoiding space which scrolls down to allow pausing
- if(e.keyCode == 32 && e.target.tagName != 'INPUT') {
-
- e.preventDefault();
- }
- });
- const userRow = document.querySelector('.username');
- const cleanseBtn = document.createElement('button');
- // if (userRow == null || document.querySelector('video') == null)
- // {
- // return;
- // }
- cleanseBtn.classList.add('btn', 'btn-grey', 'btn-sm', 'url-btn');
- cleanseBtn.textContent = 'SHOW URLS';
- userRow.appendChild(cleanseBtn);
- cleanseBtn.addEventListener('click', urlShow);
- if (document.querySelectorAll('.video').length>0)
- {
- const infoRow = document.querySelector('.user-info.text-right');
- const spanItem = document.createElement('span');
- //spanItem.classList.add('btn', 'mr-5', 'btn-grey', 'cloner');
- const cloneIcon = document.createElement('i');
- if (document.querySelectorAll('#legend a').length > 0)
- {
- const legendBtn = document.createElement('a');
- legendBtn.classList.add('btn', 'btn-grey', 'btn-sm', 'mr-5');
- legendBtn.href='#legend';
- legendBtn.textContent = 'GO TO LEGEND';
- spanItem.append(legendBtn);
- }
- infoRow.insertBefore(spanItem, infoRow.firstElementChild);
-
- //spanItem.addEventListener('click', cloneFunction);
- }
- // adding transitions to legend links if exists
- replaceAdWithButtons();
-
- // Your code here...
- }
-
- function seekChaptersN()
- {
- const video = document.querySelector('video');
- video.addEventListener('keydown', seekChapters);
- video.setAttribute('data-chapter', 0);
-
-
- function seekChapters(event)
- {
- if (event.key == 'n')
- {
- const chapterArea = document.querySelector('.vjs-control.vjs-chapters-button .vjs-menu-content');
- if (chapterArea.childElementCount > 1)
- {
- const childrenChapterCount = chapterArea.childElementCount;
- const chapters = Array.from(chapterArea.querySelectorAll('.vjs-menu-item'));
- const currentChapter = video.dataset.chapter;
- // skipping title child from chapter
- if (currentChapter < childrenChapterCount -1)
-
- {
- chapters[+currentChapter].click();
- video.dataset.chapter++;
- }
- else
- {
- video.currentTime = 0;
- video.dataset.chapter=0;
- }
- }
- }
- }
- }
-
-
- function copySourceFromAlbum()
- {
- const albums = Array.from(document.getElementsByClassName('album'));
- albums.forEach(async function(album)
- {
- /* const hr = album.querySelector('.album-link').href;
- const hdr = await fetch(hr);
- const data = await hdr.text();
- var parser = new DOMParser();
- var doc = parser.parseFromString(data, 'text/html');
- album.querySelector('.album-thumbnail').style.objectFit = 'cover';
- album.style.maxHeight = '200px';
- if (doc.querySelector('source') == null)
- {
- return;
- }
- const vidSrc = doc.querySelector('source').src;
- async function copyFxn()
- {
- await navigator.clipboard.writeText(vidSrc);
- }
- album.insertAdjacentHTML("afterbegin", '<button class="copy-link-btn btn btn-sm btn-pink" style="margin-left: 2px;width: fit-content;position: relative;z-index: 30;bottom: 61px;font-size: 1.5rem;padding: 0;">COPY</button>');
- album.querySelector('.copy-link-btn').onclick = copyFxn;
- const btnCopy = album.querySelector('.copy-link-btn');
- copyOnHover(btnCopy); */
- });
- }
-
- function copyOnHover(btn)
- {
- btn.style.opacity=0;
- btn.closest('.album').addEventListener('mouseover', function()
- {
- btn.style.opacity=1;
- });
- btn.closest('.album').addEventListener('mouseout', function()
- {
- btn.style.opacity=0;
- });
- }
-
- function checkForChapters()
- {
- if (document.querySelector('video') == null)
- {
- return;
- }
- const legend = document.querySelector('#legend');
- // if no text nodes/chapters found in legend, return ;
- if (!legend || legend.children.length < 2)
- {
- return;
- }
- const nodeTypes = Array.from(legend.childNodes).filter(function(item)
- {
- return item.nodeType === 3 && item.textContent.trim() != '';
- })
- .map(item => item.textContent.trim());
- const startingIndex = nodeTypes.indexOf('CHAPTERS BELOW');
- if (startingIndex == -1)
- {
- return;
- }
- else
- {
- document.querySelector('#bubble').style.width = 'min-content';
- document.querySelector('#bubble').insertAdjacentHTML("beforeend", '<button class="btn btn-sm btn-pink chapter-btn mb-5">ADD CHAPTERS</button>');
- const chapterBtn = document.querySelector('.chapter-btn');
- chapterBtn.addEventListener('click', function()
- {
- parseChapters(nodeTypes.slice(startingIndex+1));
- chapterBtn.textContent == 'REMOVE CHAPTERS' ? chapterBtn.textContent = 'ADD CHAPTERS' : chapterBtn.textContent = 'REMOVE CHAPTERS';
- });
- }
- }
-
- function parseChapters(chapterInfo)
- {
- document.querySelector('.vjs-chapters-button.vjs-control').classList.toggle('vjs-hidden');
- let listTimes = [];
- let listNames = [];
- // https://stackoverflow.com/questions/9640266/convert-hhmmss-string-to-seconds-only-in-javascript
- function timeToSeconds(str)
- {
- var timeElements = str.split(':'),
- seconds = 0, minutes = 1;
-
- while (timeElements.length > 0)
- {
- seconds += minutes * parseInt(timeElements.pop(), 10);
- minutes *= 60;
- }
-
- return seconds;
- }
- for (let i = 0; i<chapterInfo.length;i++)
- {
- listTimes.push(timeToSeconds(chapterInfo[i].split('-')[0]));
- listNames.push(chapterInfo[i].split('-')[1]);
- }
- const chapterBar = document.querySelector('.vjs-chapters-button .vjs-menu-content');
- if (chapterBar.children.length > 1)
- {
- chapterBar.innerHTML = '<li class="vjs-menu-title" tabindex="-1">Chapters</li>';
- }
- for (let i = 0; i< listTimes.length;i++)
- {
- chapterBar.insertAdjacentHTML("beforeend", `<li class="vjs-menu-item" onclick='function moveTo(){document.querySelector("video").currentTime=${listTimes[i]}} moveTo();' tabindex="-1">${listNames[i]}</li>`);
- }
- seekChaptersN();
-
- }
-
- function urlShow()
- {
- if (document.querySelector('video') == null)
- {
- return;
- }
- const urlBtn = document.querySelector('.url-btn');
- urlBtn.textContent == 'SHOW URLS' ? urlBtn.textContent = 'HIDE URLS': urlBtn.textContent = 'SHOW URLS';
- const vids = document.querySelectorAll('.video');
- if (document.querySelector('.form-url') == null)
- {
- const area = document.querySelector('.clearfix').previousElementSibling.parentElement;
- area.insertAdjacentHTML("afterbegin", "<form class='form-url hidden'><input type='url' required id='video-input' style='width:430px' placeholder='enter video url(s) separated by comma ,'><button class='btn btn-sm btn-pink btn-add-url'>ADD</button></form>");
- const form = document.querySelector('.form-url').addEventListener('submit', function(e)
- {
- e.preventDefault();
- });
- const btn = document.querySelector('.btn-add-url');
- btn.addEventListener('click', addVideo);
- }
- vids.forEach(vid =>
- {
- const src = vid.querySelector('video').firstElementChild.src;
- if (vid.firstChild.tagName != 'A')
- {
- const anc = document.createElement('a');
- anc.classList.add('video-url', 'hidden');
- anc.textContent = 'COPY LINK';
- vid.insertAdjacentElement("afterbegin", anc);
- anc.onclick = async function()
- {
- await navigator.clipboard.writeText(src);
- };
- }
- });
-
- function addVideo()
- {
- const input = document.getElementById('video-input');
-
- if (input.value == '' || input.value.length < 50 || input.value == null)
- {
- console.log("no valid input");
- return;
- }
- else
- {
- let vidURLs = input.value.split(',');
- vidURLs.forEach(url => createVid(url));
- }
- }
-
- function createVid(sourceURL)
- {
- let posterURL1 = sourceURL.replace('v', 's');
- let posterURL2 = posterURL1.replace('_720p', '');
- let posterURL = posterURL2.replace('mp4', 'jpg');
- const mediaDiv = document.createElement('div');
- const videoDiv = document.createElement('div');
- mediaDiv.classList.add('media-group');
- videoDiv.classList.add('video');
-
- const mainMedia = document.querySelector('.media-group');
- mainMedia.parentElement.appendChild(mediaDiv);
- mediaDiv.appendChild(videoDiv);
- const video = document.createElement('video');
- video.classList.add('video-js', 'vjs-16-9');
- video.controls = true;
- video.poster = posterURL;
-
- const src = document.createElement('source');
- src.setAttribute('src', sourceURL);
- video.appendChild(src);
- videoDiv.appendChild(video);
- var player = videojs(video);
- video.preload="none";
- allowPToPause(video);
-
-
- document.querySelector('.sidebyside-btn').click();
- document.querySelector('.sidebyside-btn').click();
- }
-
-
- if (urlBtn.textContent == 'SHOW URLS')
- {
- const links = document.querySelectorAll('.video-url');
- links.forEach(anc =>
- {
- anc.classList.add('hidden');
- });
- }
- else
- {
- const links = document.querySelectorAll('.video-url');
- links.forEach(anc =>
- {
- anc.classList.remove('hidden');
- });
- }
- document.querySelector('.form-url').classList.toggle('hidden');
-
- }
-
-
- function addTransitionToID()
- {
- const legendLinks = document.querySelectorAll('.comments a');
- legendLinks.forEach(link =>
- {
- const idText = link.textContent.trim();
- const parsedInt = parseInt(idText.substring(1), 10);
- const textInLink = link.nextSibling;
- const idEl = document.getElementById(parsedInt);
- if (Number.isNaN(parsedInt))
- {
- return;
- }
- if (textInLink.nodeType == 3)
- {
- if (idEl) {
- idEl.title=textInLink?.textContent?.trim();
- }
- }
- });
- legendLinks.forEach(link => link.onclick= function()
- {
- const idText = link.textContent.trim();
- const parsedInt = parseInt(idText.substring(1), 10);
- const idEl = document.getElementById(parsedInt);
- if (!Number.isNaN(parsedInt))
- {
- link.href=`#${parsedInt}`;
- }
- idEl.style.transition = 'all 0.3s ease-in-out';
- idEl.style.opacity = '0.4';
- function backTo(elem)
- {
- elem.style.opacity='1';
- }
- setTimeout(backTo, 400, idEl);
- });
- }
-
- function addProperID()
- {
- let count = 0;
- document.querySelectorAll('.media-group img.img-front, .media-group video').forEach
- (item =>
- {
- count++;
- item.closest('.media-group').removeAttribute('id');
- item.closest('.media-group').id=count;
- }
- );
- }
-
- function playerSeekables()
- {
- var btn = document.createElement('button');
- var backwardIcon = document.createElement('i');
- backwardIcon.classList.add('fas', 'fa-forward', 'fa-flip-horizontal');
- btn.append(backwardIcon);
- btn.title = "Back 10 seconds";
- btn.addEventListener('click', seekNeg);
- function seekNeg()
- {
- this.closest('.video').querySelector('video').currentTime -= 10;
- }
- function seekPos()
- {
- this.closest('.video').querySelector('video').currentTime += 10;
- }
- var btn2 = document.createElement('button');
- var forwardIcon = document.createElement('i');
- forwardIcon.classList.add('fas', 'fa-forward');
- btn2.append(forwardIcon);
- btn2.title = 'Forward 10 seconds';
- btn2.onclick = seekPos;
- var flipIcon = document.createElement('i');
- flipIcon.classList.add('fas','fa-sort', 'fa-rotate-90', 'fa-2x', 'ml-10');
- const flipBtn = document.createElement('button');
- flipBtn.append(flipIcon);
- flipBtn.classList.add('mirror-btn');
- flipBtn.onclick = flip;
-
- return {btn, btn2, flipBtn};
-
- }
-
- function flip()
- {
- let flipper = this.closest('.mirror-btn');
- if (this.closest('.mirror-btn').classList.contains('flipped'))
- {
- this.closest('.video').querySelector('video').style.transform = '';
- flipper.classList.toggle('flipped');
- return;
- }
- this.closest('.video').querySelector('video').style.transform = 'rotateY(170deg)';
- flipper.classList.add('flipped');
- }
-
- function replaceAdWithButtons()
- {
- const ad = document.getElementById('bubble');
- ad.removeAttribute('href');
- ad.textContent = '';
- ad.style.display='block';
- const sbsBtn = document.createElement('button');
- sbsBtn.textContent = 'SBS: OFF';
- const clonerBtn = document.createElement('button');
- clonerBtn.textContent = 'CLONER: OFF';
- sbsBtn.classList.add('btn', 'btn-sm', 'btn-pink', 'sidebyside-btn', 'mr-5', 'mb-5');
- clonerBtn.classList.add('btn', 'btn-sm', 'btn-pink', 'cloner', 'mb-5');
- sbsBtn.addEventListener('click', sideBySide);
- clonerBtn.addEventListener('click', cloneFunction);
-
- ad.append(sbsBtn, clonerBtn);
- }
-
- function allowPToPause(videoToAllow)
- {
- videoToAllow.parentElement.onkeydown = function(event){
- if(event.key == 'p' || event.key == ' ')
- {
- videoToAllow.parentElement.querySelector('.vjs-play-control').click();
- }
- else if (event.key == 'ArrowRight')
- {
- videoToAllow.currentTime+=10;
- }
- else if (event.key == 'ArrowLeft')
- {
- videoToAllow.currentTime-=10;
- }
- else if (event.key == 'r')
- {
- const rng = Math.random() * (videoToAllow.duration - 1);
- videoToAllow.currentTime = rng;
- }
- else if (event.key == 'x')
- {
- if (videoToAllow.parentElement.querySelector('.mirror-btn')!= null)
- {
- videoToAllow.parentElement.querySelector('.mirror-btn').click();
- return;
- }
- if (videoToAllow.classList.contains('flipped'))
- {
- videoToAllow.style.transform = '';
- videoToAllow.classList.remove('flipped');
- }
- else
- {
- videoToAllow.style.transform = 'rotateY(173deg)';
- videoToAllow.classList.add('flipped');
- }
- }
- else if (event.key == 'f')
- {
- videoToAllow.parentElement.querySelector('.vjs-fullscreen-control').click();
- }
- else if (!isNaN(event.key) && event.key != ' ')
- {
- videoToAllow.currentTime = (videoToAllow.duration/10) * (event.key);
- }
- else if (event.key == 'z')
- {
- if (!videoToAllow.classList.contains('zoomed'))
- {
- videoToAllow.style.scale = 1.6;
- }
- else
- {
- videoToAllow.style.scale= 1;
- }
- videoToAllow.classList.toggle('zoomed');
- }
- else if (event.key == 't')
- {
- if (!document.querySelector('.sea-css'))
- {
- let css = document.createElement('link');
- css.href='https://unpkg.com/@videojs/themes@1/dist/sea/index.css';
- css.classList.add('sea-css');
- css.rel='stylesheet';
- document.head.appendChild(css);
-
- css = document.createElement('link');
- css.href='https://unpkg.com/@videojs/themes@1/dist/forest/index.css';
- css.classList.add('sea-css');
- css.rel='stylesheet';
- document.head.appendChild(css);
-
- css = document.createElement('link');
- css.href='https://unpkg.com/@videojs/themes@1/dist/fantasy/index.css';
- css.classList.add('sea-css');
- css.rel='stylesheet';
- document.head.appendChild(css);
-
- css = document.createElement('link');
- css.href='https://unpkg.com/@videojs/themes@1/dist/city/index.css';
- css.classList.add('sea-css');
- css.rel='stylesheet';
- document.head.appendChild(css);
- }
- const themes = ["vjs-theme-city","vjs-theme-fantasy", "vjs-theme-sea", "vjs-theme-forest"]
- const random = Math.floor(Math.random() * themes.length);
- videoToAllow.parentElement.classList.remove("vjs-theme-city")
- videoToAllow.parentElement.classList.remove("vjs-theme-fantasy")
- videoToAllow.parentElement.classList.remove("vjs-theme-sea")
- videoToAllow.parentElement.classList.remove("vjs-theme-forest")
- videoToAllow.parentElement.classList.toggle(themes[random]);
- }
- };
- }
-
- function playerVersion(data)
- {
- const mediaDiv = document.createElement('div');
- const videoDiv = document.createElement('div');
- mediaDiv.classList.add('media-group');
- videoDiv.classList.add('video');
-
- const mainMedia = document.querySelector('.media-group');
- mainMedia.parentElement.appendChild(mediaDiv);
- mediaDiv.appendChild(videoDiv);
- const video = document.createElement('video');
- video.classList.add('video-js', 'vjs-16-9');
- video.controls = true;
- video.poster=data.bi;
-
- const src = document.createElement('source');
- src.setAttribute('src', data.urL);
- video.appendChild(src);
- videoDiv.appendChild(video);
- var player = videojs(video);
- video.preload="none";
-
- let btn = playerSeekables().btn;
- let btn2 = playerSeekables().btn2;
- let flipper = playerSeekables().flipBtn;
- mediaDiv.querySelector('.vjs-control-bar').insertAdjacentElement("afterbegin", btn);
- mediaDiv.querySelector('.vjs-play-control').insertAdjacentElement("afterend", btn2);
- mediaDiv.querySelector('.vjs-fullscreen-control').insertAdjacentElement("beforebegin", flipper);
-
- allowPToPause(video);
- }
-
- function getVidData(vidDiv)
- {
- const urL = vidDiv.querySelector('.video video source').src;
- var img = vidDiv.querySelector('.vjs-poster');
- var bi = img.style.backgroundImage.slice(4, -1).replace(/"/g, "");
-
- return {urL, bi};
- }
- // remove original videos and get their poster+vid url
- function removeWithData(vidDiv)
- {
- let data = getVidData(vidDiv);
- vidDiv.remove();
- return data;
- }
-
- function videoCleanseReplace()
- {
- const vidDivs = document.getElementsByClassName('video');
- console.log("started cleansing");
- Array.from(vidDivs).forEach(vidDiv =>
- {
- let data = removeWithData(vidDiv);
- playerVersion(data);
- });
- //showing message on load
- const messageDiv = document.querySelector('#user_message');
- messageDiv.textContent = 'videos replaced';
- setTimeout(() => {
- messageDiv.style.display='none';
- }, 5000);
- // deleting empty first video section
- Array.from(document.querySelectorAll('.video-lg')).forEach(lgVid => lgVid.parentElement.remove());
-
-
- }
-
- function sideBySide()
- {
- if (document.querySelectorAll('.media-group.col-sm-6').length > 0)
- {
- const sideVideos = Array.from(document.querySelectorAll('.media-group.col-sm-6'));
- sideVideos.forEach(group =>
- {
- group.classList.remove('col-sm-6');
- });
- document.querySelector('a .sidebyside-btn').textContent = 'SBS: OFF';
- }
- else
- {
- const sideVideos = Array.from(document.querySelectorAll('.media-group.col-sm-6'));
- sideVideos.forEach(group =>
- {
- group.classList.remove('col-sm-6');
- });
- const groups = Array.from(document.querySelectorAll('.media-group'));
- groups.forEach(group =>
- {
- group.classList.add('col-sm-6');
- });
- document.querySelector('a .sidebyside-btn').textContent = 'SBS: ON';
-
- }
- }
-
- function showMessage()
- {
- if (document.querySelector('.video') == null)
- {
- return;
- }
- const messageDiv = document.querySelector('#user_message');
- messageDiv.textContent = 'videos replaced + multi-play ON';
- messageDiv.style.display='block';
- messageDiv.style.width="400px";
- setTimeout(() => {
- messageDiv.style.display='none';
- messageDiv.style.width="200px";
- }, 1500);
- }
-
- // adding clone button to each video
- function cloneFunction()
- {
- if (document.querySelector('.video video') == null)
- {
- console.log("no videos");
- return;
- }
- // pressing button again up top should clear the clone buttons if second time pressing it
- if (document.getElementsByClassName('clone-btn').length > 0)
- {
- const allButtons = document.querySelectorAll('.clone-btn');
- allButtons.forEach(button => button.remove());
- document.querySelector('a .cloner').textContent = 'CLONER: OFF';
- return;
- }
- const videoDivs = document.querySelectorAll('.video');
- videoDivs.forEach(videoDiv =>
- {
- const cloneBtn = document.createElement('button');
- cloneBtn.style.position = 'absolute';
- cloneBtn.style.top = '0px';
- cloneBtn.style.zIndex = 1;
- cloneBtn.style.left="94.75%";
- if (videoDiv.parentElement.classList.contains('col-sm-6'))
- {
- cloneBtn.style.left="89%";
- }
- cloneBtn.style.transition = 'all 0.6s ease-in-out';
- cloneBtn.style.opacity=0;
- cloneBtn.classList.add('btn','btn-sm','btn-default','clone-btn');
- cloneBtn.textContent = 'CLONE';
-
- videoDiv.addEventListener('mouseover', function()
- {
- cloneBtn.style.opacity=1;
- });
- videoDiv.addEventListener('mouseout', function()
- {
- cloneBtn.style.opacity = 0;
- });
-
- videoDiv.insertBefore(cloneBtn, videoDiv.firstElementChild);
- cloneBtn.onclick = cloneThis;
- });
- document.querySelector('a .cloner').textContent = 'CLONER: ON';
- }
-
- function cloneThis()
- {
-
- if (document.querySelector('.video video') == null)
- {
- console.log("no videos");
- return;
- }
- else
- {
- const videoDivData = this.parentElement;
- let data = getVidData(videoDivData);
- const videoOriginal = videoDivData.querySelector('video');
-
-
- const mediaDiv = document.createElement('div');
- const videoDiv = document.createElement('div');
- mediaDiv.classList.add('media-group');
- if (videoOriginal.closest('.media-group').classList.contains('col-sm-6'))
- {
- mediaDiv.classList.add('col-sm-6');
- }
- videoDiv.classList.add('video');
-
- const currentMedia = this.parentElement.parentElement;
- currentMedia.insertAdjacentElement("afterend", mediaDiv);
-
- mediaDiv.appendChild(videoDiv);
- const video = document.createElement('video');
- video.classList.add('video-js', 'vjs-16-9');
- video.controls = true;
- video.poster=data.bi;
-
- const src = document.createElement('source');
- src.setAttribute('src', data.urL);
- video.appendChild(src);
- videoDiv.appendChild(video);
- var player = videojs(video);
- // var player = videojs(duplicateVid);
- allowPToPause(video);
- console.log("found videos");
- }
- }
-
- function showHideMenuE()
- {
- document.addEventListener('keypress', function(event)
- {
- if (event.key == 'e')
- {
- document.querySelector('#bubble').classList.toggle('hidden');
- }
- else if (event.key == 's' && event.target != document.querySelector('#q') && event.target != document.querySelector('#content'))
- {
- sideBySide();
- }
- else if (event.key == 'v' && event.target != document.querySelector('#q') && event.target != document.querySelector('#content'))
- {
- if (!!document.querySelector('div.vjs-playing'))
- {
- document.querySelector('div.vjs-playing').scrollIntoView();
- }
- }
- });
-
- }
-
- function cleanOnLoad()
- {
- mainFunction();
- videoCleanseReplace();
- showMessage();
- addProperID();
- addTransitionToID();
- copySourceFromAlbum();
- checkForChapters();
- showHideMenuE();
- }
- cleanOnLoad();