Erome Video Cloner

clone videos in an erome album, play multiple & side-by-side!

  1. // ==UserScript==
  2. // @name Erome Video Cloner
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.9.900
  5. // @description clone videos in an erome album, play multiple & side-by-side!
  6. // @author throwinglove23
  7. // @license MIT
  8. // @match https://www.erome.com/a/*
  9. // @match http://www.erome.com/a/*
  10. // @match https://www.erome.com/*
  11. // @exclude http://www.erome.com/a/*/edit
  12. // @exclude https://www.erome.com/a/*/edit
  13. // @icon https://www.erome.com/favicon-32x32.png
  14. // @grant none
  15. // @supportURL https://github.com/wflover23/erome-multi-tool
  16. // ==/UserScript==
  17. /* jshint esversion: 8 */
  18.  
  19. function mainFunction() {
  20. 'use strict';
  21. // removing default seek functions
  22. document.onkeydown = null;
  23. window.addEventListener('keydown', function(e) {
  24. // avoiding space which scrolls down to allow pausing
  25. if(e.keyCode == 32 && e.target.tagName != 'INPUT') {
  26. e.preventDefault();
  27. }
  28. });
  29. const userRow = document.querySelector('.username');
  30. const cleanseBtn = document.createElement('button');
  31. // if (userRow == null || document.querySelector('video') == null)
  32. // {
  33. // return;
  34. // }
  35. cleanseBtn.classList.add('btn', 'btn-grey', 'btn-sm', 'url-btn');
  36. cleanseBtn.textContent = 'SHOW URLS';
  37. userRow.appendChild(cleanseBtn);
  38. cleanseBtn.addEventListener('click', urlShow);
  39. if (document.querySelectorAll('.video').length>0)
  40. {
  41. const infoRow = document.querySelector('.user-info.text-right');
  42. const spanItem = document.createElement('span');
  43. //spanItem.classList.add('btn', 'mr-5', 'btn-grey', 'cloner');
  44. const cloneIcon = document.createElement('i');
  45. if (document.querySelectorAll('#legend a').length > 0)
  46. {
  47. const legendBtn = document.createElement('a');
  48. legendBtn.classList.add('btn', 'btn-grey', 'btn-sm', 'mr-5');
  49. legendBtn.href='#legend';
  50. legendBtn.textContent = 'GO TO LEGEND';
  51. spanItem.append(legendBtn);
  52. }
  53. infoRow.insertBefore(spanItem, infoRow.firstElementChild);
  54. //spanItem.addEventListener('click', cloneFunction);
  55. }
  56. // adding transitions to legend links if exists
  57. replaceAdWithButtons();
  58.  
  59. // Your code here...
  60. }
  61.  
  62. function seekChaptersN()
  63. {
  64. const video = document.querySelector('video');
  65. video.addEventListener('keydown', seekChapters);
  66. video.setAttribute('data-chapter', 0);
  67.  
  68. function seekChapters(event)
  69. {
  70. if (event.key == 'n')
  71. {
  72. const chapterArea = document.querySelector('.vjs-control.vjs-chapters-button .vjs-menu-content');
  73. if (chapterArea.childElementCount > 1)
  74. {
  75. const childrenChapterCount = chapterArea.childElementCount;
  76. const chapters = Array.from(chapterArea.querySelectorAll('.vjs-menu-item'));
  77. const currentChapter = video.dataset.chapter;
  78. // skipping title child from chapter
  79. if (currentChapter < childrenChapterCount -1)
  80. {
  81. chapters[+currentChapter].click();
  82. video.dataset.chapter++;
  83. }
  84. else
  85. {
  86. video.currentTime = 0;
  87. video.dataset.chapter=0;
  88. }
  89. }
  90. }
  91. }
  92. }
  93.  
  94.  
  95. function copySourceFromAlbum()
  96. {
  97. const albums = Array.from(document.getElementsByClassName('album'));
  98. albums.forEach(async function(album)
  99. {
  100. /* const hr = album.querySelector('.album-link').href;
  101. const hdr = await fetch(hr);
  102. const data = await hdr.text();
  103. var parser = new DOMParser();
  104. var doc = parser.parseFromString(data, 'text/html');
  105. album.querySelector('.album-thumbnail').style.objectFit = 'cover';
  106. album.style.maxHeight = '200px';
  107. if (doc.querySelector('source') == null)
  108. {
  109. return;
  110. }
  111. const vidSrc = doc.querySelector('source').src;
  112. async function copyFxn()
  113. {
  114. await navigator.clipboard.writeText(vidSrc);
  115. }
  116. 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>');
  117. album.querySelector('.copy-link-btn').onclick = copyFxn;
  118. const btnCopy = album.querySelector('.copy-link-btn');
  119. copyOnHover(btnCopy); */
  120. });
  121. }
  122.  
  123. function copyOnHover(btn)
  124. {
  125. btn.style.opacity=0;
  126. btn.closest('.album').addEventListener('mouseover', function()
  127. {
  128. btn.style.opacity=1;
  129. });
  130. btn.closest('.album').addEventListener('mouseout', function()
  131. {
  132. btn.style.opacity=0;
  133. });
  134. }
  135.  
  136. function checkForChapters()
  137. {
  138. if (document.querySelector('video') == null)
  139. {
  140. return;
  141. }
  142. const legend = document.querySelector('#legend');
  143. // if no text nodes/chapters found in legend, return ;
  144. if (!legend || legend.children.length < 2)
  145. {
  146. return;
  147. }
  148. const nodeTypes = Array.from(legend.childNodes).filter(function(item)
  149. {
  150. return item.nodeType === 3 && item.textContent.trim() != '';
  151. })
  152. .map(item => item.textContent.trim());
  153. const startingIndex = nodeTypes.indexOf('CHAPTERS BELOW');
  154. if (startingIndex == -1)
  155. {
  156. return;
  157. }
  158. else
  159. {
  160. document.querySelector('#bubble').style.width = 'min-content';
  161. document.querySelector('#bubble').insertAdjacentHTML("beforeend", '<button class="btn btn-sm btn-pink chapter-btn mb-5">ADD CHAPTERS</button>');
  162. const chapterBtn = document.querySelector('.chapter-btn');
  163. chapterBtn.addEventListener('click', function()
  164. {
  165. parseChapters(nodeTypes.slice(startingIndex+1));
  166. chapterBtn.textContent == 'REMOVE CHAPTERS' ? chapterBtn.textContent = 'ADD CHAPTERS' : chapterBtn.textContent = 'REMOVE CHAPTERS';
  167. });
  168. }
  169. }
  170.  
  171. function parseChapters(chapterInfo)
  172. {
  173. document.querySelector('.vjs-chapters-button.vjs-control').classList.toggle('vjs-hidden');
  174. let listTimes = [];
  175. let listNames = [];
  176. // https://stackoverflow.com/questions/9640266/convert-hhmmss-string-to-seconds-only-in-javascript
  177. function timeToSeconds(str)
  178. {
  179. var timeElements = str.split(':'),
  180. seconds = 0, minutes = 1;
  181. while (timeElements.length > 0)
  182. {
  183. seconds += minutes * parseInt(timeElements.pop(), 10);
  184. minutes *= 60;
  185. }
  186. return seconds;
  187. }
  188. for (let i = 0; i<chapterInfo.length;i++)
  189. {
  190. listTimes.push(timeToSeconds(chapterInfo[i].split('-')[0]));
  191. listNames.push(chapterInfo[i].split('-')[1]);
  192. }
  193. const chapterBar = document.querySelector('.vjs-chapters-button .vjs-menu-content');
  194. if (chapterBar.children.length > 1)
  195. {
  196. chapterBar.innerHTML = '<li class="vjs-menu-title" tabindex="-1">Chapters</li>';
  197. }
  198. for (let i = 0; i< listTimes.length;i++)
  199. {
  200. chapterBar.insertAdjacentHTML("beforeend", `<li class="vjs-menu-item" onclick='function moveTo(){document.querySelector("video").currentTime=${listTimes[i]}} moveTo();' tabindex="-1">${listNames[i]}</li>`);
  201. }
  202. seekChaptersN();
  203. }
  204.  
  205. function urlShow()
  206. {
  207. if (document.querySelector('video') == null)
  208. {
  209. return;
  210. }
  211. const urlBtn = document.querySelector('.url-btn');
  212. urlBtn.textContent == 'SHOW URLS' ? urlBtn.textContent = 'HIDE URLS': urlBtn.textContent = 'SHOW URLS';
  213. const vids = document.querySelectorAll('.video');
  214. if (document.querySelector('.form-url') == null)
  215. {
  216. const area = document.querySelector('.clearfix').previousElementSibling.parentElement;
  217. 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>");
  218. const form = document.querySelector('.form-url').addEventListener('submit', function(e)
  219. {
  220. e.preventDefault();
  221. });
  222. const btn = document.querySelector('.btn-add-url');
  223. btn.addEventListener('click', addVideo);
  224. }
  225. vids.forEach(vid =>
  226. {
  227. const src = vid.querySelector('video').firstElementChild.src;
  228. if (vid.firstChild.tagName != 'A')
  229. {
  230. const anc = document.createElement('a');
  231. anc.classList.add('video-url', 'hidden');
  232. anc.textContent = 'COPY LINK';
  233. vid.insertAdjacentElement("afterbegin", anc);
  234. anc.onclick = async function()
  235. {
  236. await navigator.clipboard.writeText(src);
  237. };
  238. }
  239. });
  240.  
  241. function addVideo()
  242. {
  243. const input = document.getElementById('video-input');
  244.  
  245. if (input.value == '' || input.value.length < 50 || input.value == null)
  246. {
  247. console.log("no valid input");
  248. return;
  249. }
  250. else
  251. {
  252. let vidURLs = input.value.split(',');
  253. vidURLs.forEach(url => createVid(url));
  254. }
  255. }
  256.  
  257. function createVid(sourceURL)
  258. {
  259. let posterURL1 = sourceURL.replace('v', 's');
  260. let posterURL2 = posterURL1.replace('_720p', '');
  261. let posterURL = posterURL2.replace('mp4', 'jpg');
  262. const mediaDiv = document.createElement('div');
  263. const videoDiv = document.createElement('div');
  264. mediaDiv.classList.add('media-group');
  265. videoDiv.classList.add('video');
  266. const mainMedia = document.querySelector('.media-group');
  267. mainMedia.parentElement.appendChild(mediaDiv);
  268. mediaDiv.appendChild(videoDiv);
  269. const video = document.createElement('video');
  270. video.classList.add('video-js', 'vjs-16-9');
  271. video.controls = true;
  272. video.poster = posterURL;
  273. const src = document.createElement('source');
  274. src.setAttribute('src', sourceURL);
  275. video.appendChild(src);
  276. videoDiv.appendChild(video);
  277. var player = videojs(video);
  278. video.preload="none";
  279. allowPToPause(video);
  280.  
  281.  
  282. document.querySelector('.sidebyside-btn').click();
  283. document.querySelector('.sidebyside-btn').click();
  284. }
  285.  
  286.  
  287. if (urlBtn.textContent == 'SHOW URLS')
  288. {
  289. const links = document.querySelectorAll('.video-url');
  290. links.forEach(anc =>
  291. {
  292. anc.classList.add('hidden');
  293. });
  294. }
  295. else
  296. {
  297. const links = document.querySelectorAll('.video-url');
  298. links.forEach(anc =>
  299. {
  300. anc.classList.remove('hidden');
  301. });
  302. }
  303. document.querySelector('.form-url').classList.toggle('hidden');
  304. }
  305.  
  306.  
  307. function addTransitionToID()
  308. {
  309. const legendLinks = document.querySelectorAll('.comments a');
  310. legendLinks.forEach(link =>
  311. {
  312. const idText = link.textContent.trim();
  313. const parsedInt = parseInt(idText.substring(1), 10);
  314. const textInLink = link.nextSibling;
  315. const idEl = document.getElementById(parsedInt);
  316. if (Number.isNaN(parsedInt))
  317. {
  318. return;
  319. }
  320. if (textInLink.nodeType == 3)
  321. {
  322. if (idEl) {
  323. idEl.title=textInLink?.textContent?.trim();
  324. }
  325. }
  326. });
  327. legendLinks.forEach(link => link.onclick= function()
  328. {
  329. const idText = link.textContent.trim();
  330. const parsedInt = parseInt(idText.substring(1), 10);
  331. const idEl = document.getElementById(parsedInt);
  332. if (!Number.isNaN(parsedInt))
  333. {
  334. link.href=`#${parsedInt}`;
  335. }
  336. idEl.style.transition = 'all 0.3s ease-in-out';
  337. idEl.style.opacity = '0.4';
  338. function backTo(elem)
  339. {
  340. elem.style.opacity='1';
  341. }
  342. setTimeout(backTo, 400, idEl);
  343. });
  344. }
  345.  
  346. function addProperID()
  347. {
  348. let count = 0;
  349. document.querySelectorAll('.media-group img.img-front, .media-group video').forEach
  350. (item =>
  351. {
  352. count++;
  353. item.closest('.media-group').removeAttribute('id');
  354. item.closest('.media-group').id=count;
  355. }
  356. );
  357. }
  358.  
  359. function playerSeekables()
  360. {
  361. var btn = document.createElement('button');
  362. var backwardIcon = document.createElement('i');
  363. backwardIcon.classList.add('fas', 'fa-forward', 'fa-flip-horizontal');
  364. btn.append(backwardIcon);
  365. btn.title = "Back 10 seconds";
  366. btn.addEventListener('click', seekNeg);
  367. function seekNeg()
  368. {
  369. this.closest('.video').querySelector('video').currentTime -= 10;
  370. }
  371. function seekPos()
  372. {
  373. this.closest('.video').querySelector('video').currentTime += 10;
  374. }
  375. var btn2 = document.createElement('button');
  376. var forwardIcon = document.createElement('i');
  377. forwardIcon.classList.add('fas', 'fa-forward');
  378. btn2.append(forwardIcon);
  379. btn2.title = 'Forward 10 seconds';
  380. btn2.onclick = seekPos;
  381. var flipIcon = document.createElement('i');
  382. flipIcon.classList.add('fas','fa-sort', 'fa-rotate-90', 'fa-2x', 'ml-10');
  383. const flipBtn = document.createElement('button');
  384. flipBtn.append(flipIcon);
  385. flipBtn.classList.add('mirror-btn');
  386. flipBtn.onclick = flip;
  387.  
  388. return {btn, btn2, flipBtn};
  389. }
  390.  
  391. function flip()
  392. {
  393. let flipper = this.closest('.mirror-btn');
  394. if (this.closest('.mirror-btn').classList.contains('flipped'))
  395. {
  396. this.closest('.video').querySelector('video').style.transform = '';
  397. flipper.classList.toggle('flipped');
  398. return;
  399. }
  400. this.closest('.video').querySelector('video').style.transform = 'rotateY(170deg)';
  401. flipper.classList.add('flipped');
  402. }
  403.  
  404. function replaceAdWithButtons()
  405. {
  406. const ad = document.getElementById('bubble');
  407. ad.removeAttribute('href');
  408. ad.textContent = '';
  409. ad.style.display='block';
  410. const sbsBtn = document.createElement('button');
  411. sbsBtn.textContent = 'SBS: OFF';
  412. const clonerBtn = document.createElement('button');
  413. clonerBtn.textContent = 'CLONER: OFF';
  414. sbsBtn.classList.add('btn', 'btn-sm', 'btn-pink', 'sidebyside-btn', 'mr-5', 'mb-5');
  415. clonerBtn.classList.add('btn', 'btn-sm', 'btn-pink', 'cloner', 'mb-5');
  416. sbsBtn.addEventListener('click', sideBySide);
  417. clonerBtn.addEventListener('click', cloneFunction);
  418. ad.append(sbsBtn, clonerBtn);
  419. }
  420.  
  421. function allowPToPause(videoToAllow)
  422. {
  423. videoToAllow.parentElement.onkeydown = function(event){
  424. if(event.key == 'p' || event.key == ' ')
  425. {
  426. videoToAllow.parentElement.querySelector('.vjs-play-control').click();
  427. }
  428. else if (event.key == 'ArrowRight')
  429. {
  430. videoToAllow.currentTime+=10;
  431. }
  432. else if (event.key == 'ArrowLeft')
  433. {
  434. videoToAllow.currentTime-=10;
  435. }
  436. else if (event.key == 'r')
  437. {
  438. const rng = Math.random() * (videoToAllow.duration - 1);
  439. videoToAllow.currentTime = rng;
  440. }
  441. else if (event.key == 'x')
  442. {
  443. if (videoToAllow.parentElement.querySelector('.mirror-btn')!= null)
  444. {
  445. videoToAllow.parentElement.querySelector('.mirror-btn').click();
  446. return;
  447. }
  448. if (videoToAllow.classList.contains('flipped'))
  449. {
  450. videoToAllow.style.transform = '';
  451. videoToAllow.classList.remove('flipped');
  452. }
  453. else
  454. {
  455. videoToAllow.style.transform = 'rotateY(173deg)';
  456. videoToAllow.classList.add('flipped');
  457. }
  458. }
  459. else if (event.key == 'f')
  460. {
  461. videoToAllow.parentElement.querySelector('.vjs-fullscreen-control').click();
  462. }
  463. else if (!isNaN(event.key) && event.key != ' ')
  464. {
  465. videoToAllow.currentTime = (videoToAllow.duration/10) * (event.key);
  466. }
  467. else if (event.key == 'z')
  468. {
  469. if (!videoToAllow.classList.contains('zoomed'))
  470. {
  471. videoToAllow.style.scale = 1.6;
  472. }
  473. else
  474. {
  475. videoToAllow.style.scale= 1;
  476. }
  477. videoToAllow.classList.toggle('zoomed');
  478. }
  479. else if (event.key == 't')
  480. {
  481. if (!document.querySelector('.sea-css'))
  482. {
  483. let css = document.createElement('link');
  484. css.href='https://unpkg.com/@videojs/themes@1/dist/sea/index.css';
  485. css.classList.add('sea-css');
  486. css.rel='stylesheet';
  487. document.head.appendChild(css);
  488.  
  489. css = document.createElement('link');
  490. css.href='https://unpkg.com/@videojs/themes@1/dist/forest/index.css';
  491. css.classList.add('sea-css');
  492. css.rel='stylesheet';
  493. document.head.appendChild(css);
  494.  
  495. css = document.createElement('link');
  496. css.href='https://unpkg.com/@videojs/themes@1/dist/fantasy/index.css';
  497. css.classList.add('sea-css');
  498. css.rel='stylesheet';
  499. document.head.appendChild(css);
  500.  
  501. css = document.createElement('link');
  502. css.href='https://unpkg.com/@videojs/themes@1/dist/city/index.css';
  503. css.classList.add('sea-css');
  504. css.rel='stylesheet';
  505. document.head.appendChild(css);
  506. }
  507. const themes = ["vjs-theme-city","vjs-theme-fantasy", "vjs-theme-sea", "vjs-theme-forest"]
  508. const random = Math.floor(Math.random() * themes.length);
  509. videoToAllow.parentElement.classList.remove("vjs-theme-city")
  510. videoToAllow.parentElement.classList.remove("vjs-theme-fantasy")
  511. videoToAllow.parentElement.classList.remove("vjs-theme-sea")
  512. videoToAllow.parentElement.classList.remove("vjs-theme-forest")
  513. videoToAllow.parentElement.classList.toggle(themes[random]);
  514. }
  515. };
  516. }
  517.  
  518. function playerVersion(data)
  519. {
  520. const mediaDiv = document.createElement('div');
  521. const videoDiv = document.createElement('div');
  522. mediaDiv.classList.add('media-group');
  523. videoDiv.classList.add('video');
  524.  
  525. const mainMedia = document.querySelector('.media-group');
  526. mainMedia.parentElement.appendChild(mediaDiv);
  527. mediaDiv.appendChild(videoDiv);
  528. const video = document.createElement('video');
  529. video.classList.add('video-js', 'vjs-16-9');
  530. video.controls = true;
  531. video.poster=data.bi;
  532. const src = document.createElement('source');
  533. src.setAttribute('src', data.urL);
  534. video.appendChild(src);
  535. videoDiv.appendChild(video);
  536. var player = videojs(video);
  537. video.preload="none";
  538. let btn = playerSeekables().btn;
  539. let btn2 = playerSeekables().btn2;
  540. let flipper = playerSeekables().flipBtn;
  541. mediaDiv.querySelector('.vjs-control-bar').insertAdjacentElement("afterbegin", btn);
  542. mediaDiv.querySelector('.vjs-play-control').insertAdjacentElement("afterend", btn2);
  543. mediaDiv.querySelector('.vjs-fullscreen-control').insertAdjacentElement("beforebegin", flipper);
  544. allowPToPause(video);
  545. }
  546.  
  547. function getVidData(vidDiv)
  548. {
  549. const urL = vidDiv.querySelector('.video video source').src;
  550. var img = vidDiv.querySelector('.vjs-poster');
  551. var bi = img.style.backgroundImage.slice(4, -1).replace(/"/g, "");
  552. return {urL, bi};
  553. }
  554. // remove original videos and get their poster+vid url
  555. function removeWithData(vidDiv)
  556. {
  557. let data = getVidData(vidDiv);
  558. vidDiv.remove();
  559. return data;
  560. }
  561.  
  562. function videoCleanseReplace()
  563. {
  564. const vidDivs = document.getElementsByClassName('video');
  565. console.log("started cleansing");
  566. Array.from(vidDivs).forEach(vidDiv =>
  567. {
  568. let data = removeWithData(vidDiv);
  569. playerVersion(data);
  570. });
  571. //showing message on load
  572. const messageDiv = document.querySelector('#user_message');
  573. messageDiv.textContent = 'videos replaced';
  574. setTimeout(() => {
  575. messageDiv.style.display='none';
  576. }, 5000);
  577. // deleting empty first video section
  578. Array.from(document.querySelectorAll('.video-lg')).forEach(lgVid => lgVid.parentElement.remove());
  579. }
  580.  
  581. function sideBySide()
  582. {
  583. if (document.querySelectorAll('.media-group.col-sm-6').length > 0)
  584. {
  585. const sideVideos = Array.from(document.querySelectorAll('.media-group.col-sm-6'));
  586. sideVideos.forEach(group =>
  587. {
  588. group.classList.remove('col-sm-6');
  589. });
  590. document.querySelector('a .sidebyside-btn').textContent = 'SBS: OFF';
  591. }
  592. else
  593. {
  594. const sideVideos = Array.from(document.querySelectorAll('.media-group.col-sm-6'));
  595. sideVideos.forEach(group =>
  596. {
  597. group.classList.remove('col-sm-6');
  598. });
  599. const groups = Array.from(document.querySelectorAll('.media-group'));
  600. groups.forEach(group =>
  601. {
  602. group.classList.add('col-sm-6');
  603. });
  604. document.querySelector('a .sidebyside-btn').textContent = 'SBS: ON';
  605. }
  606. }
  607.  
  608. function showMessage()
  609. {
  610. if (document.querySelector('.video') == null)
  611. {
  612. return;
  613. }
  614. const messageDiv = document.querySelector('#user_message');
  615. messageDiv.textContent = 'videos replaced + multi-play ON';
  616. messageDiv.style.display='block';
  617. messageDiv.style.width="400px";
  618. setTimeout(() => {
  619. messageDiv.style.display='none';
  620. messageDiv.style.width="200px";
  621. }, 1500);
  622. }
  623.  
  624. // adding clone button to each video
  625. function cloneFunction()
  626. {
  627. if (document.querySelector('.video video') == null)
  628. {
  629. console.log("no videos");
  630. return;
  631. }
  632. // pressing button again up top should clear the clone buttons if second time pressing it
  633. if (document.getElementsByClassName('clone-btn').length > 0)
  634. {
  635. const allButtons = document.querySelectorAll('.clone-btn');
  636. allButtons.forEach(button => button.remove());
  637. document.querySelector('a .cloner').textContent = 'CLONER: OFF';
  638. return;
  639. }
  640. const videoDivs = document.querySelectorAll('.video');
  641. videoDivs.forEach(videoDiv =>
  642. {
  643. const cloneBtn = document.createElement('button');
  644. cloneBtn.style.position = 'absolute';
  645. cloneBtn.style.top = '0px';
  646. cloneBtn.style.zIndex = 1;
  647. cloneBtn.style.left="94.75%";
  648. if (videoDiv.parentElement.classList.contains('col-sm-6'))
  649. {
  650. cloneBtn.style.left="89%";
  651. }
  652. cloneBtn.style.transition = 'all 0.6s ease-in-out';
  653. cloneBtn.style.opacity=0;
  654. cloneBtn.classList.add('btn','btn-sm','btn-default','clone-btn');
  655. cloneBtn.textContent = 'CLONE';
  656. videoDiv.addEventListener('mouseover', function()
  657. {
  658. cloneBtn.style.opacity=1;
  659. });
  660. videoDiv.addEventListener('mouseout', function()
  661. {
  662. cloneBtn.style.opacity = 0;
  663. });
  664. videoDiv.insertBefore(cloneBtn, videoDiv.firstElementChild);
  665. cloneBtn.onclick = cloneThis;
  666. });
  667. document.querySelector('a .cloner').textContent = 'CLONER: ON';
  668. }
  669.  
  670. function cloneThis()
  671. {
  672. if (document.querySelector('.video video') == null)
  673. {
  674. console.log("no videos");
  675. return;
  676. }
  677. else
  678. {
  679. const videoDivData = this.parentElement;
  680. let data = getVidData(videoDivData);
  681. const videoOriginal = videoDivData.querySelector('video');
  682. const mediaDiv = document.createElement('div');
  683. const videoDiv = document.createElement('div');
  684. mediaDiv.classList.add('media-group');
  685. if (videoOriginal.closest('.media-group').classList.contains('col-sm-6'))
  686. {
  687. mediaDiv.classList.add('col-sm-6');
  688. }
  689. videoDiv.classList.add('video');
  690.  
  691. const currentMedia = this.parentElement.parentElement;
  692. currentMedia.insertAdjacentElement("afterend", mediaDiv);
  693.  
  694. mediaDiv.appendChild(videoDiv);
  695. const video = document.createElement('video');
  696. video.classList.add('video-js', 'vjs-16-9');
  697. video.controls = true;
  698. video.poster=data.bi;
  699. const src = document.createElement('source');
  700. src.setAttribute('src', data.urL);
  701. video.appendChild(src);
  702. videoDiv.appendChild(video);
  703. var player = videojs(video);
  704. // var player = videojs(duplicateVid);
  705. allowPToPause(video);
  706. console.log("found videos");
  707. }
  708. }
  709.  
  710. function showHideMenuE()
  711. {
  712. document.addEventListener('keypress', function(event)
  713. {
  714. if (event.key == 'e')
  715. {
  716. document.querySelector('#bubble').classList.toggle('hidden');
  717. }
  718. else if (event.key == 's' && event.target != document.querySelector('#q') && event.target != document.querySelector('#content'))
  719. {
  720. sideBySide();
  721. }
  722. else if (event.key == 'v' && event.target != document.querySelector('#q') && event.target != document.querySelector('#content'))
  723. {
  724. if (!!document.querySelector('div.vjs-playing'))
  725. {
  726. document.querySelector('div.vjs-playing').scrollIntoView();
  727. }
  728. }
  729. });
  730. }
  731.  
  732. function cleanOnLoad()
  733. {
  734. mainFunction();
  735. videoCleanseReplace();
  736. showMessage();
  737. addProperID();
  738. addTransitionToID();
  739. copySourceFromAlbum();
  740. checkForChapters();
  741. showHideMenuE();
  742. }
  743. cleanOnLoad();