- // ==UserScript==
- // @name 4chan \ IB Simple Web Media Player
- // @description Simple Web Media Player for 4chan and other imageboards.
- // @namespace LabMember-001
- // @author Hououin Kyōma
- // @license GPLv3
- // @version 1.4.5
-
- // @grant none
- // @run-at document-end
-
- // @match https://*.4chan.org/*
- // @match https://*.4channel.org/*
- // @match https://*.smuglo.li/*
- // @match https://*.smugloli.net/*
- // @match https://*.kissu.moe/*
- // @match https://*.4taba.net/*
- // @match https://*.2kind.moe/*
- // @match https://*.1chan.net/*
- // @match https://*.otterchat.net/*
- // @match https://*.fatchan.org/*
- // @match https://*.7chan.org/*
- // @match https://*.420chan.org/*
- // @match https://*.anon.cafe/*
- // @match https://*.4-ch.net/*
-
- // @match https://*.archived.moe/*
- // @match https://*.desuarchive.org/*
- // @match https://*.4plebs.org/*
- // @match https://*.warosu.org/*
-
- // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAilBMVEX///8zGeTw8PArQKsXuQAiAv+kpKTu6tkAAADd3d0vEP8fHx9hTOF/bPjj3/97enb6+ffx7//v7+/y7+KUkof6+ftsWeDKwttYQP89If+Ec+5WR7ff398dHRv7+viom94+JuPBvrBKMuIODg3+/f1tbGl0cnZlUepjWK+NfPVPO9SIeej6+vtAQEBg9CwMAAAA3ElEQVRIx+3UxxKCMBCA4bUggahIt/de3v/1HEiICe44iwM3/pPM5jtgVsGuHLTku3TfUW03JJI8YlDFIYUMn6A1iSgEjFhdZGB0zw6Kjzkxhor09XrZQScvJ45eS8SXbXQp3Yv5WNftJ9VJejTWkkLscK2JE4nYuxVTHaL2T6kWMppZSO4NmUoymo4Byb+ekakgLioAAo5MBbGwJVcbKacykzD2BykjEjERkeiITD6oAilQs6T512/+KisvzM+17MqK5ffx5V9yZCrIfBGg4uUhU/lD9jhD4h4yfQMAvzcdsmcBygAAAABJRU5ErkJggg==
-
- // ==/UserScript==
-
- // Most of the sites above are to test scripts.
-
- console.log('Loading IB Media Player.');
-
- /* Repository: */
- /* https://github.com/LabMember-001/Simple-Web-Media-Player */
- /* https://labmember-001.github.io/Simple-Web-Media-Player/ */
- /* */
- /* */
- /* */
-
- /* == BOARD SUPPORT ==
- // Script will alter behavior on different imageboard backends
- // When adding custom board scripts, alter board behavior on bottom of the script. You'll need some knowledge on JS.
- // In most cases, simply adding an @match to the top of this script to turn it on for that domain will work
- // as it captures all link presses and checks for webm.
- // If you want more compatability, check the issue tracker for existing requests and if there are none, you may request help.
- */
-
- /* == SCRIPT CONFIGURATION ==
- // To define a board as a precoded backend type (vichan, tinyib, lynxchan, etc) simply
- // add a regex for that domain in the swmpBoards category below these comments.
- */
-
- /* == TO DO ==
- //
- // High priority
- // - Resizing
- //
- // Medium Priority
- // - Loading poster for large files
- // - Make window move stop if you release mouseup outside of the screen.
- // - Automatic backend script detection.
- //
- // Low Priority
- // - Title length
- // - Fix support for archived.moe redirection urls.
- // - Fix titles on some backends. (Mostly just vichan+4chan taking original filename right now).
- */
-
- /* == Current Script Support ==
- // Yotsuba (4chan)
- // Tinyboard/Vichan/Infinity
- // Fuuka
- // TinyIB
- // Wakaba
- // FoolFuuka (Not archived.moe's redirects, but 4plebs is fine).
- // Kusaba
- */
-
- /* == Script Specific Bugs ==
- // - Vichan shows original title when clicked on video thumb, but not link.
- // - Doesnt grab titles on Fuuka, TinyIB, Wakaba, FoolFuuka
- //
- */
-
- /*
- // == Missing Script Support ==
- // Some Kusaba sites have issues loading video when clicked on thumbnail. Links typically work. 7chan is fine.
- // Phutaba has a slight bug with videos which shows file information when hovering over player depending on which link you click.
- // Some of the bigger Lynxchan sites are very modified and have no thumbnail click support.
- // jschan and vichan will not properly work if not added to the board specific types. Should be fixable for me later.
- // InfinityNext does not work. Don't care.
- */
-
- // Get domain
- var currentUrl = window.location.href;
-
- // Board Types - probably temporary.
- var swmpBoards = {
- fourchan: // For title support, otherwise works well without adding here.
- ['https:\/\/*..*(4chan|4channel).org\/*'],
- vichan: // For Title and thumbnail click support. Not great without due to thumbnails.
- ['https:\/\/*..*(smuglo.li|smugloli.net)\/*',
- 'https:\/\/*..*2kind.moe\/*',
- 'https:\/\/*..*kissu.moe\/*'], // Also works on new UI (lolnoty) as long as it's in here.
- tinyib: // Title support not written, otherwise works well without adding here.
- ['https:\/\/*..*1chan.net\/*'],
- wakaba: // Title support not written, otherwise works well without adding here.
- ['https:\/\/*..*otterchat.net\/*'],
- lynxchan: // Title support not written, otherwise works well without adding here.
- ['https:\/\/*..*anon.cafe\/*'],
- jschan: // Title support not written. Jschan installations *must* be added here to work properly.
- ['https:\/\/*..*fatchan.org\/*']
- }
-
- // regex to check the backend script of current domain
- var backendScript = [];
- Object.keys(swmpBoards).forEach(script => {
- swmpBoards[script].forEach(regex => {
- if (currentUrl.match(regex)) {
- backendScript = script;
- }
- });
- });
-
- console.log(backendScript);
-
-
- // This configuration variable can be overwritten wherever you want later
- // on as you wish or add your own site variables for user configuration.
- var swmpConfig = {
- autoplay: 'true', // Autoplay media when launched by SWMP.
- loop: 'true', // Loop media when launched by SWMP.
- windowed: 'true',
- positionTop: '100',
- positionOffset: '100',
- positionSide: 'right',
- volume: 60,
- volumeScroll: 'true',
- muted: 'false', //Not implemented
- skip: 5, //skip forward/backward keyboard shortcut, seconds.
- theme: 'default', //Default theme
- themes: //All themes
- [
- ['default', 'MPC Light'],
- ['dark', 'MPC Dark'],
- ['kurisu', 'Kurisumasu'],
- ['winxp', 'WIN_XP'],
- ['modernity', 'Modernity']
- ],
- files: 'avi|mpeg|mpg|ogv|mp4|webm|flv|wav|mp3|m4a|mp2|ogg|flac',
- allowMultiple: 'false',
- downloadAttribute: 'true', //true = override default action, false = download
- doubleclickMaximize: 'false' //true = doubleclick video to maximize instead of fullscreen
- }
-
- // Initialize site configuration. As of now it's on a per site basis and not using GM values, I like different designs.
- if (localStorage.swmpVolume == undefined) {
- localStorage.swmpVolume = swmpConfig.volume;
- } else {
- swmpConfig.volume = localStorage.swmpVolume;
- }
-
- if (localStorage.swmpTheme == undefined) {
- localStorage.swmpTheme = swmpConfig.theme;
- } else {
- swmpConfig.theme = localStorage.swmpTheme;
- }
-
- if (localStorage.swmpAutoplay == undefined) {
- localStorage.swmpAutoplay = swmpConfig.autoplay;
- } else {
- swmpConfig.autoplay = localStorage.swmpAutoplay;
- }
-
- if (localStorage.swmpLoop == undefined) {
- localStorage.swmpLoop = swmpConfig.loop;
- } else {
- swmpConfig.loop = localStorage.swmpLoop;
- }
-
- if (localStorage.swmpAllowMultiple == undefined) {
- localStorage.swmpAllowMultiple = swmpConfig.allowMultiple;
- } else {
- swmpConfig.allowMultiple = localStorage.swmpAllowMultiple;
- }
-
- if (localStorage.swmpWindowed == undefined) {
- localStorage.swmpWindowed = swmpConfig.windowed;
- } else {
- swmpConfig.windowed = localStorage.swmpWindowed;
- }
-
- if (localStorage.swmpMuted == undefined) {
- localStorage.swmpMuted = swmpConfig.muted;
- } else {
- swmpConfig.muted = localStorage.swmpMuted;
- }
-
- if (localStorage.swmpVolumeScroll == undefined) {
- localStorage.swmpVolumeScroll = swmpConfig.volumeScroll;
- } else {
- swmpConfig.volumeScroll = localStorage.swmpVolumeScroll;
- }
-
- if (localStorage.swmpDownloadAttribute == undefined) {
- localStorage.swmpDownloadAttribute = swmpConfig.downloadAttribute;
- } else {
- swmpConfig.downloadAttribute = localStorage.swmpDownloadAttribute;
- }
-
- if (localStorage.swmpDoubleclickMaximize == undefined) {
- localStorage.swmpDoubleclickMaximize = swmpConfig.doubleclickMaximize;
- } else {
- swmpConfig.doubleclickMaximize = localStorage.swmpDoubleclickMaximize;
- }
-
-
- // Add style to head when DOM is loaded.
-
- if (!document.getElementById('swmp-stylesheet')) { // Don't bother injecting style on demo page.
- var swmpStyle = document.createElement('style');
- swmpStyle.setAttribute('id', 'swmp-stylesheet');
- swmpStyle.innerHTML = `div.swmp,div.swmp.swmp-theme-dark,div.swmp.swmp-theme-dark *{--swmp-container-border:#000;--swmp-controls-background:var(--swmp-background);--swmp-button-background:var(--swmp-background);--swmp-seek-height:30px;--swmp-seek-offset:10px;--swmp-btn-border-right:#000;--swmp-btn-border-bottom:#000;--swmp-btn-border-left-active:#000;--swmp-btn-border-top-active:#000}.swmp *,div.swmp.swmp-container{font-family:-apple-system,BlinkMacSystemFont,URW Gothic,MS PGothic,Helvetica,sans-serif;font-size:11pt;text-indent:4px;letter-spacing:1px;line-height:1;outline:0;color:var(--swmp-text-color)}div.swmp iframe,div.swmp video{max-width:500px;max-height:500px;width:auto;height:auto;margin:auto}.swmp *,div.swmp.swmp-container,select.swmp.swmp-selector{color:var(--swmp-text-color)}div.swmp,div.swmp.swmp-theme-dark,div.swmp.swmp-theme-dark *,div.swmp.swmp-theme-winxp,div.swmp.swmp-theme-winxp *{--swmp-range-thumb-border-right:#000;--swmp-range-thumb-border-bottom:#000}.swmp *{background:0 0;border:0;margin:0;padding:0;height:unset;width:unset}div.swmp{--swmp-background:#e6e6e6;--swmp-container-box-shadow:none;--swmp-player-container-background:#000;--swmp-player-container-border-left:#000;--swmp-player-container-border-top:#000;--swmp-player-container-border-right:#000;--swmp-player-container-border-bottom:#000;--swmp-settings-background:var(--swmp-controls-background);--swmp-text-color:#000;--swmp-button-mask-color:#000;--swmp-seek-background:var(--swmp-controls-background);--swmp-seek-progress-color:lightgrey;--swmp-seek-border-left:darkgray;--swmp-seek-border-top:darkgray;--swmp-seek-border-right:#fff;--swmp-seek-border-bottom:#fff;--swmp-range-thumb-color:var(--swmp-controls-background);--swmp-range-thumb-border-left:#fff;--swmp-range-thumb-border-top:#fff;--swmp-btn-border-radius:0;--swmp-btn-border-left:#fff;--swmp-btn-border-top:#fff;--swmp-btn-border-right-active:#fff;--swmp-btn-border-bottom-active:#fff}div.swmp.swmp-theme-dark,div.swmp.swmp-theme-dark *{--swmp-background:#333;--swmp-text-color:#888;--swmp-button-mask-color:#888;--swmp-seek-progress-color:#555;--swmp-seek-border-left:#1a1a1a;--swmp-seek-border-top:#1a1a1a;--swmp-seek-border-right:#464646;--swmp-seek-border-bottom:#464646;--swmp-range-thumb-color:var(--swmp-background);--swmp-range-thumb-border-left:#777;--swmp-range-thumb-border-top:#777;--swmp-btn-border-left:#777;--swmp-btn-border-top:#777;--swmp-btn-border-right-active:#777;--swmp-btn-border-bottom-active:#777}div.swmp.swmp-theme-kurisu,div.swmp.swmp-theme-kurisu *{--swmp-background:#a44242;--swmp-text-color:#fff;--swmp-button-mask-color:#fff}div.swmp.swmp-container{position:relative;display:inline-flex;flex-direction:column;padding:2px;background:var(--swmp-background);border:1px solid var(--swmp-container-border);z-index:100;overflow:hidden;min-width:320px;width:auto;box-shadow:var(--swmp-container-box-shadow);cursor:none}div.swmp .swmp-player-container,div.swmp audio,div.swmp iframe,div.swmp video{background:var(--swmp-player-container-background)}div.swmp.swmp-window.swmp-window-container{display:flex;justify-content:space-between;padding-bottom:2px}div.swmp.swmp-fullscreen div.swmp-settings.swmp-settings-container,div.swmp.swmp-fullscreen div.swmp-window.swmp-window-container,div.swmp.swmp-minimized div.swmp-player-container{display:none}div.swmp.swmp-fullscreen div.swmp-player-container{display:block;width:100vw;height:100vh}span.swmp.swmp-window.swmp-window-titlebar{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;position:relative;margin:auto;cursor:move;width:100%;text-align:center;display:block}span.swmp.swmp-window.swmp-window-title{display:block;max-width:260px;text-overflow:ellipsis;overflow:hidden;margin:auto auto -2px;line-height:1.5}span.swmp.swmp-window.swmp-window-buttons-contain{display:flex;flex:0 1 auto;margin-right:-2px}div.swmp .swmp-player-container{display:flex;position:relative;height:100%;border:1px solid;border-left-color:var(--swmp-player-container-border-left);border-top-color:var(--swmp-player-container-border-top);border-right-color:var(--swmp-player-container-border-right);border-bottom-color:var(--swmp-player-container-border-bottom)}div.swmp.swmp-audio div.swmp-player-container,div.swmp.swmp-fullscreen div.swmp-player-container{border:none}div.swmp.swmp-container.swmp-fullscreen{background:#000;position:unset!important;width:100%;height:auto;border-radius:0!important}div.swmp.swmp-container.swmp-maximized{position:fixed!important;top:0!important;bottom:0!important;right:0!important;left:0!important;transition:.2s ease-out;border-radius:0!important}div.swmp.swmp-container.swmp-maximized audio,div.swmp.swmp-container.swmp-maximized iframe,div.swmp.swmp-container.swmp-maximized video{position:absolute;max-width:100%;max-height:100%;width:100%;height:100%;top:0;bottom:0;left:0;right:0}div.swmp.swmp-container.swmp-fullscreen audio,div.swmp.swmp-container.swmp-fullscreen iframe,div.swmp.swmp-container.swmp-fullscreen video{position:relative;width:100%;height:100%;max-width:100%;max-height:100%}div.swmp iframe{min-width:420px;min-height:236px;pointer-events:none}div.swmp audio{min-width:320px;min-height:40px}div.swmp.swmp-controls{bottom:0;left:0;background:var(--swmp-controls-background);width:100%;display:flex;flex-direction:column}div.swmp.swmp-settings-container{background:var(--swmp-settings-background);display:flex;flex-direction:column;align-items:flex-start}div.swmp.swmp-fullscreen div.swmp.swmp-controls{position:absolute;opacity:0;transition:opacity .5s ease-out}div.swmp.swmp-fullscreen.swmp-movingmouse div.swmp.swmp-controls{opacity:1;position:absolute;transition:none}div.swmp.swmp-movingmouse{cursor:unset}div.swmp.swmp-controls span.swmp-seek-container{display:flex;width:calc(100% - 6px);height:var(--swmp-seek-height);margin:auto;position:relative}div.swmp.swmp-controls span.swmp-seek-container input.swmp.swmp-seeker{width:calc(100% - var(--swmp-seek-offset));left:calc(var(--swmp-seek-offset)/ 2);-webkit-appearance:none;background:#0000;padding:0;margin:0;height:var(--swmp-seek-height);position:absolute;z-index:1;cursor:pointer;-webkit-margin-top:-14px}input[type=range].swmp{background:0 0!important;border:0!important;outline:0!important}span.swmp input[type=range]::-webkit-slider-runnable-track{width:100%;height:6px;cursor:pointer;background:#0000;border-radius:0;border:1px solid #000;border-left-color:var(--swmp-seek-border-left);border-top-color:var(--swmp-seek-border-top);border-right-color:var(--swmp-seek-border-right);border-bottom-color:var(--swmp-seek-border-bottom)}span.swmp input[type=range]::-moz-range-track{width:100%;height:6px;cursor:pointer;background:#0000;border-radius:0;border:1px solid #000;border-left-color:var(--swmp-seek-border-left);border-top-color:var(--swmp-seek-border-top);border-right-color:var(--swmp-seek-border-right);border-bottom-color:var(--swmp-seek-border-bottom)}span.swmp progress::-webkit-progress-bar{background:#0000}span.swmp progress::-webkit-progress-value{background:var(--swmp-seek-progress-color)}span.swmp progress::-moz-progress-bar{background:var(--swmp-seek-progress-color)}span.swmp input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:4px solid var(--swmp-range-thumb-color);height:8px;width:2px;border-radius:0;padding:4px 3px;background:#0000;background:linear-gradient(180deg,var(--swmp-seek-border-top) 10%,var(--swmp-seek-background) 10%,var(--swmp-seek-background) 90%,var(--swmp-seek-border-bottom) 90%);cursor:pointer;margin-top:-6px;box-shadow:1px 1px 0 0 var(--swmp-range-thumb-border-bottom),-1px -1px 0 0 var(--swmp-range-thumb-border-top)}span.swmp input[type=range]::-moz-range-thumb{appearance:none;border:4px solid var(--swmp-range-thumb-color);height:8px;width:6px;border-radius:0;background:linear-gradient(180deg,var(--swmp-seek-border-top) 10%,var(--swmp-seek-background) 10%,var(--swmp-seek-background) 90%,var(--swmp-seek-border-bottom) 90%);cursor:pointer;box-shadow:1px 1px 0 0 var(--swmp-range-thumb-border-bottom),-1px -1px 0 0 var(--swmp-range-thumb-border-top)}span.swmp input[type=range]::-webkit-range-progress{height:6px;background-color:#0000}span.swmp input[type=range]::-moz-range-progress{height:6px;background-color:#0000}span.swmp progress.swmp-volume{width:50px;position:absolute;height:6px;right:8px;border:none;bottom:7px;z-index:0;background:var(--swmp-seek-background)}span.swmp input.swmp-volume[type=range]{-webkit-appearance:none;background:#0000;padding:0;margin-left:2px;cursor:pointer;position:relative}span.swmp input.swmp-volume[type=range]::-webkit-slider-thumb{padding:4px 2px;width:2px}span.swmp input.swmp-volume[type=range]::-moz-range-thumb{padding:0 1px;width:1px}div.swmp.swmp-controls span.swmp-seek-container progress.swmp-progress{width:calc(100% - var(--swmp-seek-offset));left:calc(var(--swmp-seek-offset)/ 2);height:6px;z-index:0;position:relative;background:var(--swmp-seek-background);bottom:-12px;border:none}span.swmp.swmp-row-bottom{display:flex;flex-direction:row;height:20px;margin-bottom:2px}div.swmp.swmp-fullscreen span.swmp.swmp-row-bottom{padding-bottom:5px}span.swmp.swmp-buttons-container{height:100%}select.swmp.swmp-selector{-webkit-appearance:none;appearance:none;background:var(--swmp-button-background);border:1px solid var(--swmp-text-color);outline:0;border-radius:0;width:85px;overflow:hidden;text-overflow:ellipsis;letter-spacing:0;text-indent:0}label.swmp.swmp-settings{display:inline-flex;flex-direction:row-reverse;line-height:1.2}input.swmp.swmp-settings{margin:-2px 0 0 4px;border:1px solid var(--swmp-text-color);appearance:none;-webkit-appearance:none;outline:0;width:14px;height:14px;background:var(--swmp-controls-background)}input.swmp.swmp-settings:checked{outline:5px inset var(--swmp-text-color);outline-offset:-8px}button.swmp.swmp-button{min-width:26px;height:100%;padding:0 4px;display:inline-block;cursor:pointer;margin:0 2px;color:var(--swmp-button-mask-color);background:var(--swmp-button-background);border:1px solid;border-radius:var(--swmp-btn-border-radius);border-bottom-color:var(--swmp-btn-border-bottom);border-right-color:var(--swmp-btn-border-right);border-top-color:var(--swmp-btn-border-top);border-left-color:var(--swmp-btn-border-left);filter:unset}button.swmp.swmp-button span{display:block;width:16px;height:16px;image-rendering:crisp-edges;image-rendering:pixelated;background-repeat:no-repeat;background-color:var(--swmp-button-mask-color);-webkit-mask-image:var(--image);mask-image:var(--image);-webkit-mask-size:16px;mask-size:16px;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}button.swmp.swmp-button:active span{transform:translateX(1px) translateY(1px)}span.swmp.swmp-window button{height:20px;min-width:22px;width:22px}button.swmp.swmp-button.swmp-playlist span{--image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAADFBMVEUAAAAAAAAAAAAAAAA16TeWAAAABHRSTlMARP/Eyy24XQAAAHxJREFUeJzN0MENgCAMBVBkHKdgHqdhCGLCBxMODsAIxomkLQca4h0OlBcaaGvMWsvRtvFxN5mCLQJ4ApwgMLwAlZA6bgIeQbtqSB0XoSUw4AixIxNQBImRBTh5hwC/UGkvP3PMT4+fqnLGQiO3EObmVNvjQNSoONgqWGt96g97WXTz3RYAAAAASUVORK5CYII=)}button.swmp.swmp-button.swmp-playlist.swmp-playlist-prev span{transform:rotate(180deg)}button.swmp.swmp-button.swmp-window-minimize span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAARElEQVRYR+3V0Q0AMAQFQPYfuv7apAPg4yzguQQZw5XD/UMAAgQIECCwTuA0fcc7+C8gAIFxgaYleG3W3QECBAgQaBcokVQGIRA6KiEAAAAASUVORK5CYII=');margin-top:2px;-webkit-mask-size:12px;mask-size:12px}button.swmp.swmp-button.swmp-window-maximize span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAANUlEQVQ4T2NkoBAwQvX/J9McRqobADOQkINgLsZwwagBDAyjYUCFMCCUAtHlqZcXSLUZrh4AU/cYEVH9Rd0AAAAASUVORK5CYII=');margin-top:2px;-webkit-mask-size:12px;mask-size:12px}button.swmp.swmp-button.swmp-window-close span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA9UlEQVRoge2Y2woCMRBD5699dB79a7ViQfDWaZNMFybQR5NzVndhNatUKpUjxe/nctT+Vn59HsYItf+1nDFC7f9Ujhyh9v8qR4xQ+0fKV0bY/XYKDERHIvDtnGcEWBIyeIaEHB4pkQaPkEiHnwXxyc9QE/0mtrjyCgkZfA9SQg7fg5BIg+9ZkUiH75mR2Aa+xS0uwHyzC8Vt/ieULuG2fhOnSfgA3LYSDoBOk2DAyySi8O1RyXyzo8P3pEuswKdLIODTJJDwcgkGvFQiMhKBV/UPj0yXC/r/jiyXC/q/jsDKBf1vI/ByQf8jbtz/bdj9lUqlAs4N+1iFrUSwCpcAAAAASUVORK5CYII=');margin-top:2px;-webkit-mask-size:12px;mask-size:12px}button.swmp.swmp-button.swmp-playbutton span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA8klEQVRoQ+3aMQ6DMAyF4XDycjCGVmrPBRmapVLkJLafn1GRMiHB/+EpEVtJfm3J+8vtAO86kb2uI8tkfidwfsM/WSA9QBsAPUQC0ENGAbSQWQAdZBVAA9ECwiFWgDCINQAO8QLAIN4AdwgK4AZBA8whUQAzSDRADWEBLEPYANMQVsAwhB0gQrIAupA/AHR60d2bs09APFRgBYjhbfJsgOFwNsB0OAtgOTwaoA6PApiFowHm4SiAW7g3wD3cCwALtwbAw60AYeFaQHj4KoAmfBZAFz4KoA2XAPThPcCz3njU9QJtFdWvud2vBuovgn5A+glcJSF8MQrukbIAAAAASUVORK5CYII=')}button.swmp.swmp-button.swmp-playbutton.swmp-playing span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAtUlEQVRoQ+2Y2w6AIAxD5f8/2kuCRgiJbdjDMMfnxUE5o9WyLf6Uxde//W4D+8SJuGKE9OqbhrxUFCGkFxt4qQ1CInpX2SMWCIGQwc1ILBACIRBqFQixd1HUkF4MMUMs8taVESVGupFGDZpACIROBTCy5tOsMhGiijiMIb2IEkQJkTeihCAUUUIQ6S4hShAliBKVAZwYJzbuTn7ufoiFExs04cRpndg4xRyl7uDlWPWE+aTbwAFy3FQxPpmarQAAAABJRU5ErkJggg==')}button.swmp.swmp-button.swmp-stopbutton span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAUUlEQVRYR+3Xuw0AIAwD0WQC2H9LJuDXICFqm+KywEWvc4b50tyP7x7oIpE6O221bgEeQAABBBBAAAEEEEAAAQTsAkW0jPYqei0jUf9k7ON0AGFsNSFlb3+JAAAAAElFTkSuQmCC')}.swmp.swmp-timer-container,button.swmp.swmp-button.swmp-fullscreen{margin-left:auto}button.swmp.swmp-button.swmp-fullscreen span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAP0lEQVQ4T2NkoBAwQvX/x2EOQXmCCghZgG4AjE/IYzAXMw4jAwj5Gac8sYFG0AB4qBLplOEYCwOfF4gMfExlADQ3GBE+X9RsAAAAAElFTkSuQmCC')}button.swmp.swmp-button.swmp-volume span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAG1BMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABp4cHsAAAACHRSTlMA1WZ/JZz0Rme5O54AAACGSURBVDjL5ZIxCoAwDEWjVXDs6OjUWXDxRl6hqyL2H9uqKKL5oKtmzIOXNvkiP6qc9LOSAAciAoiIAAcdRNEGmrtoBQb1TbSCFt3eK3CUSAr0KliUlQbEA1YFCTCqID47qMAAwztAVXS4x2RfffC8kusSw7O100Px0/Iw0PjwwPGI0lB/s2bRbW7duVgj2wAAAABJRU5ErkJggg==')}button.swmp.swmp-button.swmp-volume.swmp-min span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAQAAAD9CzEMAAAAd0lEQVR42u2Xuw2AMAwFr41YhKmyVyp2YhZ6pwEJqJDgmRTv3PukV/gDxpjBKDRl+5mV0LWvbIRKUGjEXrJoZIIjGongHI1AcI3mc8E9mpeCeFwWWGCBBTqBfNj9MK4TFk7CykxZ+glnS8LhlXI6Akws/gCMGZAO8wpmVouK9vcAAAAASUVORK5CYII=')}button.swmp.swmp-button.swmp-volume.swmp-max span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAD1BMVEVHcEwAAAAAAAAAAAAAAADTrAj/AAAABXRSTlMA/4hD1KmiQHMAAACwSURBVDjL1ZPBDYMwDEV/nQzAIwwAVQdoNoD9l+qhgAyKW/VGfbHkp/wk9rf0//EI6sZ8Kqx5oj/U07IdgKcHlXfOcNAyVpCA4oU2oAqDF9pB9pcYK7hLAkYnBJKMUZqgc0IgaaJIFYp0Yw/JYJAy9CegBUZZA1SYlWA4gwxdExgUCWiA/mfQlgovj56bog/6loRN/Nz2w6CSG1Q82tgMoX1iw8UWDU0dr8HXxblwvAAGdxy1HX87LAAAAABJRU5ErkJggg==')}button.swmp.swmp-button.swmp-volume.swmp-mute span{--image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAHlBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3KG9qAAAACnRSTlMACZko0v9e9AufnFf4OQAAAJdJREFUeJzlkrsNgDAMRCMhL8BO6WluBmZha2LZDvmdRA1uUHi+S/xJ6Uexk/9bJuAEMcIabBmQQNLknFBw2KERFyMFcEEFalROMAlCaUYFWKoLBDU81wUdkCobgGbHDT0Q/06gSOJJA3hqeKmgd7BX0TpY5V2v2ibO3bW2L+YRg5on6KOtRT9AzdIy2PrwheMrmi4GPhk3sCZY/9usUnQAAAAASUVORK5CYII=')}span.swmp.swmp-volume-container{display:flex;width:60px;height:100%;position:relative}span.swmp.swmp-volume-container input.swmp.swmp-volume.swmp-range{width:50px;vertical-align:top;position:relative}button.swmp.swmp-button:active{border-bottom-color:var(--swmp-btn-border-bottom-active);border-right-color:var(--swmp-btn-border-right-active);border-top-color:var(--swmp-btn-border-top-active);border-left-color:var(--swmp-btn-border-left-active)}span.swmp.swmp-timer-container{display:inline-table;margin-right:5px;cursor:default}span.swmp.swmp-timer-container span.swmp.swmp-time{display:table-cell;vertical-align:bottom}#quote-preview{z-index:1}div.swmp.swmp-theme-modernity,div.swmp.swmp-theme-modernity *{--swmp-background:#222;--swmp-container-border:#222;--swmp-text-color:#eee;--swmp-button-mask-color:#eee;--swmp-controls-background:#222;--swmp-btn-border-left:#0000;--swmp-btn-border-top:#0000;--swmp-btn-border-right:#0000;--swmp-btn-border-bottom:#0000;--swmp-btn-border-left-active:#0000;--swmp-btn-border-top-active:#0000;--swmp-btn-border-right-active:#0000;--swmp-btn-border-bottom-active:#0000;--swmp-seek-background:#444;--swmp-seek-progress-color:#bbb;--swmp-seek-border-left:#444;--swmp-seek-border-top:#444;--swmp-seek-border-right:#444;--swmp-seek-border-bottom:#444;--swmp-container-box-shadow:0px 0px 10px #000;font-family:Arial;font-weight:700}div.swmp.swmp-theme-modernity input[type=range]::-moz-range-thumb{border:none;height:8px;width:8px;background:#eee;box-shadow:none;border-radius:100%;padding:4px}div.swmp.swmp-theme-modernity input[type=range]::-webkit-slider-thumb{border:none;height:8px;width:8px;background:#eee;box-shadow:none;border-radius:100%;padding:4px}div.swmp.swmp-theme-winxp,div.swmp.swmp-theme-winxp *{--swmp-background:blue;--swmp-container-border:none;--swmp-controls-background:#eeead9;--swmp-button-background:#fff;--swmp-seek-background:#ddd;--swmp-seek-progress-color:#17b900;--swmp-seek-border-left:#a4a4a4;--swmp-seek-border-top:#a4a4a4;--swmp-seek-border-right:#fff;--swmp-seek-border-bottom:#fff;--swmp-range-thumb-color:#fff;--swmp-range-thumb-border-left:#fff;--swmp-range-thumb-border-top:#3319e4;--swmp-btn-border-radius:3px;--swmp-btn-border-left:#2202ff;--swmp-btn-border-top:#2202ff;--swmp-btn-border-right:#000;--swmp-btn-border-bottom:#000;--swmp-btn-border-left-active:red;--swmp-btn-border-top-active:red;--swmp-btn-border-right-active:#000;--swmp-btn-border-bottom-active:#000}div.swmp.swmp-theme-winxp.swmp-container{border-radius:3px}div.swmp.swmp-theme-winxp .swmp-window-title{color:#fff}div.swmp.swmp-theme-winxp .swmp.swmp-window.swmp-window-container{background-image:linear-gradient(180deg,#3636ff 0,#0003db 74%)}div.swmp.swmp-theme-winxp .swmp-window button.swmp-button{background:#00f;border-color:#fff}div.swmp.swmp-theme-winxp .swmp-window button.swmp-button span{background-color:#fff}div.swmp.swmp-theme-winxp .swmp-window button.swmp-button.swmp-window-close{background:red}div.swmp.swmp-theme-winxp span.swmp input[type=range]::-moz-range-thumb{border-radius:2px}div.swmp.swmp-theme-winxp span.swmp input[type=range]::-webkit-slider-thumb{border-radius:2px}@media screen and (max-width:480px){div.swmp.swmp-container{top:5px!important;right:5px!important;left:5px!important;margin-bottom:10px}div.swmp.swmp-container.swmp-maximized{margin:0}div.swmp audio,div.swmp iframe,div.swmp video{max-width:100%!important;max-height:100%!important;min-width:unset;min-height:unset;width:100%;height:100%}span.swmp.swmp-volume-container{display:none}}`;
- document.head.appendChild(swmpStyle);
- }
-
- var youtubeIsLoaded = false;
- var gmwindow;
- if (typeof GM_info != 'undefined') {
- gmwindow = unsafeWindow;
- } else {
- gmwindow = window;
- }
-
- var fileregex = new RegExp(`\.(${swmpConfig.files})+$`, 'gmi');
- var ytregex = new RegExp("^(?:https?:)?//[^/]*(?:youtube(?:-nocookie)?\.com|youtu\.be|yewtu\.be).*[=/]([-\\w]{11})(?:\\?|=|&|$)", "gmi");
-
- // SWMP Code
-
- class swmp {
-
- constructor(obj) {
- this.name = 'Simple Web Media Player';
-
- if (obj.id == undefined) {
- this.id = this.uuid();
- } else {
- this.id = obj.id;
- }
-
- this.type = obj.type; // "video" or "audio" player. Youtube too.
- this.mime = obj.mime; // MIME type for source, Example: "video/webm". Feed to enable checking for file support (webm not supported by iOS)
- this.url = obj.url; // File Location
- this.poster = obj.poster; // Optional Video Preview for when autoplay is off.
- this.autoplay = obj.autoplay; // Optional Autoplay
- this.loop = obj.loop; // Optional Loop
- this.windowed = obj.windowed; // Optional set false to disable windowed mode and place inline
-
- this.defaultVolume = parseInt(swmpConfig.volume);
-
- this.playlistLocation = 0;
- this.playlist = obj.playlist;
-
- if (obj.url == undefined) {
- console.log('No media given');
- return false;
- }
-
- if (obj.windowed == undefined) {
- this.windowed = swmpConfig.windowed;
- }
-
- if (obj.title == undefined) {
- this.title = this.getFileName(obj.url);
- } else {
- this.title = obj.title; // If Applicable, assign from existing parameters on IB.
- }
-
- // Check URL for Type and Mime, also sets mime+type based on fileextension in url
- if (this.checkURL(this.url) == false) {
- return false;
- }
-
- // Create Container
- this.container = document.createElement('div');
- this.container.setAttribute('class', 'swmp swmp-container');
- this.container.setAttribute('id', this.id);
- this.container.setAttribute('tabindex', '0');
-
- // Create Window Container
- this.prepareWindow();
-
- // Prepare the media that's gonna play.
-
- if (this.type == 'video' || this.type == 'audio') {
- // Check if browser can play formats, create audio or video tag and fill with source.
- this.preparePlayer();
- } else if (this.type == 'youtube') {
- // Load Youtube iframe.
- if (this.prepareYoutube() == false) {
- console.log("Error: YouTube");
- return false;
- }
- }
-
- // Add Theme
- if (swmpConfig.theme != undefined) {
- this.container.classList.add(`swmp-theme-${swmpConfig.theme}`);
- }
-
- if (this.type == 'video' || this.type == 'audio') {
- // Create buttons
- //this.prepareSharedEventsInit();
- this.prepareSharedEvents();
- this.prepareControls();
- this.preparePlayerEvents();
- this.prepareSettings();
- } else if (this.type == 'youtube') {
- //this.prepareSharedEvents();
- //this.prepareYoutubeEvents();
- }
-
- this.prepareSharedEventsInit();
-
- }
-
- nextMedia() {
- if (this.playlistLocation === this.playlist.length -1) {
- return;
- }
-
- this.playlistLocation++;
- this.url = this.playlist[this.playlistLocation];
- this.windowTitle.textContent = `[${this.playlistLocation+1}/${this.playlist.length}] ${this.url}`;
-
- this.refreshPlayer();
- }
-
- previousMedia() {
- if (this.playlistLocation === 0) {
- return;
- }
-
- this.playlistLocation--;
- this.url = this.playlist[this.playlistLocation];
- this.windowTitle.textContent = `[${this.playlistLocation+1}/${this.playlist.length}] ${this.url}`;
-
- this.refreshPlayer();
- }
-
- clearPlayer() {
-
- if (this.player.interval != undefined) {
- clearInterval(this.player.interval);
- }
-
- if (this.closeError != undefined) {
- this.closeError.remove();
- }
-
- /*if (timeInterval != undefined) {
- clearInterval(timeInterval); //the yt timer is completely borken
- }*/
-
- this.container.classList.remove('swmp-video');
- this.container.classList.remove('swmp-audio');
- this.container.classList.remove('swmp-youtube');
-
- if (this.settingsContainer != undefined) {
- this.settingsContainer.innerHTML = null;
- this.settingsContainer.remove();
- }
- this.controls.innerHTML = null;
- this.controls.remove();
- this.playerContainer.innerHTML = null;
- this.playerContainer.remove();
- this.player.innerHTML = null;
- this.player.remove();
-
-
- }
-
- refreshPlayer() {
- this.clearPlayer();
-
- this.checkURL(this.url);
-
- if (this.type == 'youtube') {
- this.prepareYoutube();
- }
-
- if (this.type == 'video' || this.type == 'audio') {
- this.preparePlayer();
- this.prepareSharedEvents();
- this.prepareControls();
- this.preparePlayerEvents();
- this.prepareSettings();
- }
- }
-
- prepareWindow() {
- this.windowContainer = document.createElement('div');
- this.windowContainer.setAttribute('class', 'swmp swmp-window swmp-window-container');
- this.container.appendChild(this.windowContainer);
-
- // Create Title/WindowDragbar and put inside Window Container
- this.windowTitlebar = document.createElement('span');
- this.windowTitlebar.setAttribute('class', 'swmp swmp-window swmp-window-titlebar');
-
- this.windowTitle = document.createElement('span');
- this.windowTitle.setAttribute('class', 'swmp swmp-window swmp-window-title');
-
- if (this.playlist != undefined) {
- if (this.title != undefined) {
- this.windowTitle.textContent = `[${this.playlistLocation+1}/${this.playlist.length}] ${this.title}`;
- } else {
- this.windowTitle.textContent = `[${this.playlistLocation+1}/${this.playlist.length}] ${this.url}`;
- }
- } else {
- if (this.title != undefined) {
- this.windowTitle.textContent = this.title;
- } else {
- this.windowTitle.textContent = this.url;
- }
- }
-
-
-
- this.windowTitlebar.appendChild(this.windowTitle);
- this.windowContainer.appendChild(this.windowTitlebar);
-
- // Create Window Buttons Container
- this.windowButtonsContain = document.createElement('span');
- this.windowButtonsContain.setAttribute('class', 'swmp swmp-window swmp-window-buttons-contain');
- this.windowContainer.appendChild(this.windowButtonsContain);
-
- // Create Minimize Button (Video only)
- if (this.type == 'video' || this.type == 'youtube') {
- this.windowMinimize = document.createElement('button');
- this.windowMinimize.setAttribute('class', 'swmp swmp-button swmp-window-minimize');
- this.windowMinimize.innerHTML = '<span></span>';
- this.windowMinimize.addEventListener('click', (event) => {
- event.preventDefault();
- if (this.container.classList.contains('swmp-minimized') ) {
- this.container.classList.remove('swmp-minimized');
- } else {
- this.container.classList.add('swmp-minimized');
- }
- });
- this.windowButtonsContain.appendChild(this.windowMinimize);
- }
-
- // Create Maximize Button (Video only)
- if (this.type == 'video' || this.type == 'youtube') {
- this.windowMaximize = document.createElement('button');
- this.windowMaximize.setAttribute('class', 'swmp swmp-button swmp-window-maximize');
- this.windowMaximize.innerHTML = '<span></span>';
- this.windowMaximize.addEventListener('click', this.toggleMaximize);
- this.windowButtonsContain.appendChild(this.windowMaximize);
- }
-
- // Create Close Button
- this.windowClose = document.createElement('button');
- this.windowClose.setAttribute('class', 'swmp swmp-button swmp-window-close');
- this.windowClose.innerHTML = '<span></span>';
- this.windowClose.addEventListener('click', (event) => {
- event.preventDefault();
- this.container.remove();
- });
- this.windowButtonsContain.appendChild(this.windowClose);
-
- // Window Event
- if (swmpConfig.windowed != 'false') {
- this.makeDraggable(this.container);
- } else {
- this.windowTitlebar.style.cursor = 'default';
- }
-
-
- // Disable Default Context Menu on Titlebar
- this.windowTitlebar.addEventListener('contextmenu', function(evt) {
- evt.preventDefault();
- }, false);
- // Right Click Event
- this.windowTitlebar.addEventListener('mousedown', (event) => {
- event.preventDefault();
- switch (event.which) {
- case 3: //rightclick
- this.openSettings();
- break;
- }
- });
-
- // Maximize
- this.windowTitlebar.addEventListener('dblclick', this.toggleMaximize);
-
- }
-
- prepareControls() {
- // Create and put Controls inside Container
- this.controls = document.createElement('div');
- this.controls.setAttribute('class', 'swmp swmp-controls');
- this.container.appendChild(this.controls);
-
- // Disable Default Context Menu on Controls
- this.controls.addEventListener('contextmenu', function(evt) {
- evt.preventDefault();
- }, false);
- // Right Click Event
- this.controls.addEventListener('mousedown', (event) => {
- switch (event.which) {
- case 3: //rightclick
- this.openSettings();
- break;
- }
- });
-
- // Create Progress/Seeker Container
- this.seekContain = document.createElement('span');
- this.seekContain.setAttribute('class', 'swmp swmp-seek-container');
- //this.seekContain.textContent = 'seek-cntnr';
- this.controls.appendChild(this.seekContain);
-
- // Create Progress Bar
- this.progress = document.createElement('progress');
- this.progress.setAttribute('value', '0');
- this.progress.setAttribute('min', '0');
- this.progress.setAttribute('max', '1000');
- this.progress.setAttribute('step', '1');
- this.progress.setAttribute('class', 'swmp swmp-progress');
- this.seekContain.appendChild(this.progress);
-
- // Create Seeker Input
- this.seeker = document.createElement('input');
- this.seeker.setAttribute('type', 'range');
- this.seeker.setAttribute('value', '0');
- this.seeker.setAttribute('min', '0');
- this.seeker.setAttribute('max', '1000');
- this.seeker.setAttribute('step', '1');
- this.seeker.setAttribute('class', 'swmp swmp-seeker');
- this.seekContain.appendChild(this.seeker);
-
- // Create a Row Bottom Container
- this.bottomRow = document.createElement('span');
- this.bottomRow.setAttribute('class', 'swmp swmp-row-bottom');
- this.controls.appendChild(this.bottomRow);
-
- // Create Buttons Container
- this.buttonsContain = document.createElement('span');
- this.buttonsContain.setAttribute('class', 'swmp swmp-buttons-container');
- this.bottomRow.appendChild(this.buttonsContain);
-
- // Create Play/Pause Button and put inside Controls
- this.playbutton = document.createElement('button');
- this.playbutton.setAttribute('class', 'swmp swmp-button swmp-playbutton');
- this.playbutton.innerHTML = "<span></span>"; // ◀
- this.playbutton.addEventListener("click", event => {
- event.preventDefault();
-
- if (this.type == 'video' || this.type == 'audio') {
- if (this.player.paused ) {
- this.player.play();
- } else {
- this.player.pause();
- }
- } else if (this.type == 'youtube') {
- this.togglePlay();
- }
- });
- this.buttonsContain.appendChild(this.playbutton);
-
- // Create a Stop/Reload Button and put inside Controls
- this.stopbutton = document.createElement('button');
- this.stopbutton.setAttribute('class', 'swmp swmp-button swmp-stopbutton');
- this.stopbutton.innerHTML = "<span></span>"; // ■
- this.stopbutton.addEventListener("click", event => {
- event.preventDefault();
- if (this.loaded != true) {
- console.log('Userscript: Can\'t send stop yet.');
- return;
- }
-
- if (this.type == 'video' || this.type == 'audio') {
- this.player.pause();
- this.seeker.value = 0;
- this.seeker.setAttribute("value", 0);
- this.progress.value = 0;
- this.progress.setAttribute("value", 0);
- this.player.currentTime = 0;
- this.currentTimer.textContent = '00:00';
- } else if (this.type == 'youtube') {
- this.seeker.value = 0;
- this.seeker.setAttribute("value", 0);
- this.progress.value = 0;
- this.progress.setAttribute("value", 0);
- this.ytplayer.stopVideo();
- this.currentTimer.textContent = '00:00';
- }
- });
- this.buttonsContain.appendChild(this.stopbutton);
-
- if (this.playlist) {
- this.previousButton = document.createElement('button');
- this.previousButton.setAttribute('class', 'swmp swmp-button swmp-playlist swmp-playlist-prev');
- this.previousButton.innerHTML = "<span></span>";
- this.previousButton.addEventListener('click', event => {
- event.preventDefault();
- this.previousMedia();
- });
- this.buttonsContain.appendChild(this.previousButton);
-
- this.nextButton = document.createElement('button');
- this.nextButton.setAttribute('class', 'swmp swmp-button swmp-playlist');
- this.nextButton.innerHTML = "<span></span>";
- this.nextButton.addEventListener('click', event => {
- event.preventDefault();
- this.nextMedia();
- });
- this.buttonsContain.appendChild(this.nextButton);
- }
-
- // Create a Volume Container
- this.volumeContain = document.createElement('span');
- this.volumeContain.setAttribute('class', 'swmp swmp-volume-container');
- this.bottomRow.appendChild(this.volumeContain);
-
- // Create a Volume Button and put inside Buttons Container
- this.volumeButton = document.createElement('button');
- this.volumeButton.setAttribute('class', 'swmp swmp-button swmp-volume');
- this.volumeButton.innerHTML = "<span></span>";
- this.volumeButton.addEventListener("click", event => {
- event.preventDefault();
- this.toggleMute();
- });
- this.buttonsContain.appendChild(this.volumeButton);
-
- // Create a Volume Progress and put inside Volume Container
- this.volumeProgress = document.createElement('progress');
- this.volumeProgress.setAttribute('value', this.defaultVolume);
- this.volumeProgress.setAttribute('min', '0');
- this.volumeProgress.setAttribute('max', '100');
- this.volumeProgress.setAttribute('step', '1');
- this.volumeProgress.setAttribute('class', 'swmp swmp-volume swmp-progress');
- this.volumeContain.appendChild(this.volumeProgress);
-
- // Create a Volume Input and put inside Volume Container
- this.volumeRange = document.createElement('input');
- this.volumeRange.setAttribute('type', 'range');
- this.volumeRange.setAttribute('value', this.defaultVolume);
- this.volumeRange.setAttribute('min', '0');
- this.volumeRange.setAttribute('max', '100');
- this.volumeRange.setAttribute('step', '1');
- this.volumeRange.setAttribute('class', 'swmp swmp-volume swmp-range');
- this.volumeContain.appendChild(this.volumeRange);
-
- // Create a Timer Container and put inside Controls
- this.timerContain = document.createElement('span');
- this.timerContain.setAttribute('class', 'swmp swmp-timer-container');
- this.bottomRow.appendChild(this.timerContain);
-
- // Create a timerCurrent and put inside Timer Container
- this.currentTimer = document.createElement('span');
- this.currentTimer.setAttribute('class', 'swmp swmp-time swmp-current');
- this.currentTimer.textContent = '00:00';
- this.timerContain.appendChild(this.currentTimer);
-
- // Add a separator between timer
- this.timerSeperator = document.createElement('span');
- this.timerSeperator.setAttribute('class', 'swmp swmp-time swmp-separator');
- this.timerSeperator.textContent = '/';
- this.timerContain.appendChild(this.timerSeperator);
-
- // Create a totalTimer and put inside Timer Container
- this.totalTimer = document.createElement('span');
- this.totalTimer.setAttribute('class', 'swmp swmp-time swmp-total');
- this.totalTimer.textContent = '00:00';
- this.timerContain.appendChild(this.totalTimer);
-
- // Create a Fullscreen Button and put inside Bottom Row Container
- if (this.type == 'video' || this.type == 'youtube' || (this.type == 'audio' && this.playlist != null) ) {
- this.fullscreenbutton = document.createElement('button');
- this.fullscreenbutton.setAttribute('class', 'swmp swmp-button swmp-fullscreen');
- this.fullscreenbutton.innerHTML = "<span></span>"; // ▣
- this.fullscreenbutton.addEventListener("click", event => {
- event.preventDefault();
- this.fullscreen(this.container);
- });
- this.bottomRow.appendChild(this.fullscreenbutton);
- }
- }
-
- prepareSettings() {
-
- this.openSettings = () => {
- // Settings Menu
-
- if (this.container.querySelector('.swmp-settings-container') != null) {
- this.settingsContainer.remove();
- return false; //Already open
- }
-
- this.settingsContainer = document.createElement('div');
- this.settingsContainer.setAttribute('class', 'swmp swmp-settings swmp-settings-container');
- this.settingsContainer.innerHTML = 'Settings:';
-
-
- this.br = document.createElement('br');
- this.settingsContainer.appendChild(this.br);
-
- this.themeSelector = document.createElement('select');
- this.themeSelector.setAttribute('class', 'swmp swmp-selector swmp-settings swmp-theme-selector');
-
- this.themes = '';
- swmpConfig.themes.forEach(theme => {
- if (localStorage.swmpTheme == theme[0]) {
- this.themeSelector.value = theme[0];
- this.themes += `<option value="${theme[0]}" selected>${theme[1]}</option>`;
- } else {
- this.themes += `<option value="${theme[0]}">${theme[1]}</option>`;
- }
- });
- this.themeSelector.innerHTML = this.themes;
-
- this.themeSelector.onchange = (event) => {
- if (this.themeSelector.value == '') {
- return false;
- } else {
- this.removeClassByPrefix(this.container, 'swmp-theme-'); //regex remove [theme-*]
- this.container.classList.add(`swmp-theme-${this.themeSelector.value}`);
- swmpConfig.theme = this.themeSelector.value;
- localStorage.swmpTheme = this.themeSelector.value;
- }
- }
-
- this.settingsContainer.appendChild(this.themeSelector);
-
-
- // Autoplay Settings
- this.autoplayLabel = document.createElement('label');
- this.autoplayLabel.setAttribute('class', 'swmp swmp-settings swmp-label swmp-autoplay-label');
- this.autoplayLabel.textContent = 'Autoplay';
- this.autoplayCheck = document.createElement('input');
- this.autoplayCheck.setAttribute('class', 'swmp swmp-settings swmp-input swmp-autoplay-input');
- this.autoplayCheck.setAttribute('type', 'checkbox');
- if (localStorage.swmpAutoplay == 'true') {
- this.autoplayCheck.setAttribute('checked', 'checked');
- }
- this.autoplayCheck.addEventListener('change', (event) => {
- if (this.autoplayCheck.checked == true) {
- this.autoplayCheck.setAttribute('checked', 'checked');
- localStorage.swmpAutoplay = 'true';
- swmpConfig.autoplay = 'true';
- } else {
- this.autoplayCheck.removeAttribute('checked');
- localStorage.swmpAutoplay = 'false';
- swmpConfig.autoplay = 'false';
- }
- });
- this.autoplayLabel.appendChild(this.autoplayCheck);
- this.settingsContainer.appendChild(this.autoplayLabel);
-
- // Loop Settings
- this.loopLabel = document.createElement('label');
- this.loopLabel.setAttribute('class', 'swmp swmp-settings swmp-label swmp-loop-label');
- this.loopLabel.textContent = 'Loop';
- this.loopCheck = document.createElement('input');
- this.loopCheck.setAttribute('class', 'swmp swmp-settings swmp-input swmp-loop-input');
- this.loopCheck.setAttribute('type', 'checkbox');
- if (localStorage.swmpLoop == 'true') {
- this.loopCheck.setAttribute('checked', 'checked');
- }
- this.loopCheck.addEventListener('change', (event) => {
- if (this.loopCheck.checked == true) {
- this.loopCheck.setAttribute('checked', 'checked');
- if (this.type == 'video' || this.type == 'audio') {
- this.player.setAttribute('loop', 'true');
- } else if (this.type == 'youtube') {
- // Youtube Loop
- }
- localStorage.swmpLoop = 'true';
- swmpConfig.loop = 'true';
- } else {
- this.loopCheck.removeAttribute('checked');
- if (this.type == 'video' || this.type == 'audio') {
- this.player.removeAttribute('loop');
- } else if (this.type == 'youtube') {
- // Youtube Loop
- }
- localStorage.swmpLoop = 'false';
- swmpConfig.loop = 'false';
- }
- });
- this.loopLabel.appendChild(this.loopCheck);
- this.settingsContainer.appendChild(this.loopLabel);
-
- // Multiple Players Settings
- this.multiLabel = document.createElement('label');
- this.multiLabel.setAttribute('class', 'swmp swmp-settings swmp-label swmp-multi-label');
- this.multiLabel.textContent = 'Multi';
- this.multiCheck = document.createElement('input');
- this.multiCheck.setAttribute('class', 'swmp swmp-settings swmp-input swmp-multi-input');
- this.multiCheck.setAttribute('type', 'checkbox');
- if (localStorage.swmpAllowMultiple == 'true') {
- this.multiCheck.setAttribute('checked', 'checked');
- }
- this.multiCheck.addEventListener('change', (event) => {
- if (this.multiCheck.checked == true) {
- this.multiCheck.setAttribute('checked', 'checked');
- localStorage.swmpAllowMultiple = 'true';
- swmpConfig.allowMultiple = 'true';
- } else {
- this.multiCheck.removeAttribute('checked');
- localStorage.swmpAllowMultiple = 'false';
- swmpConfig.allowMultiple = 'false';
- }
- });
- this.multiLabel.appendChild(this.multiCheck);
- this.settingsContainer.appendChild(this.multiLabel);
-
- this.br = document.createElement('br');
- this.settingsContainer.appendChild(this.br);
-
- // Volume Scroll Settings
- this.volumeScrollLabel = document.createElement('label');
- this.volumeScrollLabel.setAttribute('class', 'swmp swmp-settings swmp-label swmp-volumescroll-label');
- this.volumeScrollLabel.textContent = 'Volume Scroll';
- this.volumeScrollCheck = document.createElement('input');
- this.volumeScrollCheck.setAttribute('class', 'swmp swmp-settings swmp-input swmp-volumescroll-input');
- this.volumeScrollCheck.setAttribute('type', 'checkbox');
- if (localStorage.swmpVolumeScroll == 'true') {
- this.volumeScrollCheck.setAttribute('checked', 'checked');
- }
- this.volumeScrollCheck.addEventListener('change', (event) => {
- if (this.volumeScrollCheck.checked == true) {
- this.volumeScrollCheck.setAttribute('checked', 'checked');
- localStorage.swmpVolumeScroll = 'true';
- swmpConfig.volumeScroll = 'true';
- } else {
- this.volumeScrollCheck.removeAttribute('checked');
- localStorage.swmpVolumeScroll = 'false';
- swmpConfig.volumeScroll = 'false';
- }
- });
- this.volumeScrollLabel.appendChild(this.volumeScrollCheck);
- this.settingsContainer.appendChild(this.volumeScrollLabel);
-
- // Override Download link Attribute Settings
- this.downloadAttributeLabel = document.createElement('label');
- this.downloadAttributeLabel.setAttribute('class', 'swmp swmp-settings swmp-label swmp-downloadattribute-label');
- this.downloadAttributeLabel.textContent = 'Override Download';
- this.downloadAttributeCheck = document.createElement('input');
- this.downloadAttributeCheck.setAttribute('class', 'swmp swmp-settings swmp-input swmp-downloadattribute-input');
- this.downloadAttributeCheck.setAttribute('type', 'checkbox');
- if (localStorage.swmpDownloadAttribute == 'true') {
- this.downloadAttributeCheck.setAttribute('checked', 'checked');
- }
- this.downloadAttributeCheck.addEventListener('change', (event) => {
- if (this.downloadAttributeCheck.checked == true) {
- this.downloadAttributeCheck.setAttribute('checked', 'checked');
- localStorage.swmpDownloadAttribute = 'true';
- swmpConfig.downloadAttribute = 'true';
- } else {
- this.downloadAttributeCheck.removeAttribute('checked');
- localStorage.swmpDownloadAttribute = 'false';
- swmpConfig.downloadAttribute = 'false';
- }
- });
- this.downloadAttributeLabel.appendChild(this.downloadAttributeCheck);
- this.settingsContainer.appendChild(this.downloadAttributeLabel);
-
-
- // Replace doubleclick fullscreen with doubleclick maximize
- this.doubleclickMaximizeLabel = document.createElement('label');
- this.doubleclickMaximizeLabel.setAttribute('class', 'swmp swmp-settings swmp-label swmp-doubleclickmaximize-label');
- this.doubleclickMaximizeLabel.textContent = 'Doubleclick Maximize';
- this.doubleclickMaximizeCheck = document.createElement('input');
- this.doubleclickMaximizeCheck.setAttribute('class', 'swmp swmp-settings swmp-label swmp-doubleclickmaximize-input');
- this.doubleclickMaximizeCheck.setAttribute('type', 'checkbox');
- if (localStorage.swmpDoubleclickMaximize == 'true') {
- this.doubleclickMaximizeCheck.setAttribute('checked', 'checked');
- }
- this.doubleclickMaximizeCheck.addEventListener('change', (event) => {
- if (this.doubleclickMaximizeCheck.checked == true) {
- this.doubleclickMaximizeCheck.setAttribute('checked', 'checked');
- localStorage.swmpDoubleclickMaximize = 'true';
- swmpConfig.doubleclickMaximize = 'true';
- } else {
- this.doubleclickMaximizeCheck.removeAttribute('checked');
- localStorage.swmpDoubleclickMaximize = 'false';
- swmpConfig.doubleclickMaximize = 'false';
- }
- });
- this.doubleclickMaximizeLabel.appendChild(this.doubleclickMaximizeCheck);
- this.settingsContainer.appendChild(this.doubleclickMaximizeLabel);
-
-
-
- this.container.appendChild(this.settingsContainer);
-
- }
- }
-
- preparePlayer() {
- // Create Player HTML5 Video or Audio format.
- if (this.type == 'video') {
- this.container.classList.add('swmp-video');
- this.player = document.createElement('video');
- this.player.setAttribute('class', 'swmp swmp-video swmp-player');
- if (this.poster != false && this.poster != undefined) {
- this.player.setAttribute('poster', this.poster);
- }
- } else if (this.type == 'audio') {
- this.container.classList.add('swmp-audio');
- this.player = document.createElement('audio');
- this.player.setAttribute('class', 'swmp swmp-audio swmp-player');
- } else {
- console.log(`SWMP Error: invalid type of ${this.type}.`);
- return false;
- }
-
- // Check Format Support
- if (this.mime != undefined) {
- if (this.player.canPlayType(this.mime) == '') {
- this.closeError = document.createElement('span');
- this.closeError.innerHTML = `Your browser can't play this format: ${this.mime}`;
- /*this.container.addEventListener('click', (event) => {
- this.container.remove();
- });*/
- this.container.appendChild(this.closeError);
- //return false;
- }
- }
-
- // Preload metadata
- this.player.setAttribute('preload', 'metadata');
-
- // Create Player Container and Put inside Container
- this.playerContainer = document.createElement('div');
- this.playerContainer.setAttribute('class', 'swmp swmp-player-container');
- this.container.appendChild(this.playerContainer);
-
- // Put Player inside Video Container
- this.playerContainer.appendChild(this.player);
-
- // Create and put Source inside Player
- this.source = document.createElement('source');
- this.source.setAttribute('src', this.url);
- if (this.mime != undefined) {
- this.source.setAttribute('type', this.mime);
- }
- this.player.appendChild(this.source);
-
- // Is Autoplay?
- if ( (swmpConfig.autoplay == true || swmpConfig.autoplay == 'true') && this.autoplay != false) {
- this.player.setAttribute('autoplay', true);
- }
-
- // Is Loop?
- if ( (swmpConfig.loop == true || swmpConfig.loop == 'true') && this.loop != false) {
- this.player.setAttribute('loop', true);
- }
- }
-
- prepareYoutube() {
-
- console.log('SWMP: prepareYoutube() ');
-
- if (youtubeIsLoaded == false) {
- // Include YouTube iframe API if not already added:
- if (!document.getElementById('swmp-youtube-api')) {
- console.log("SWMP: Loading YouTube API");
- var tag = document.createElement('script');
- tag.src = "https://www.youtube.com/iframe_api";
- tag.setAttribute('id', 'swmp-youtube-api');
- var firstScriptTag = document.getElementsByTagName('script')[0];
- firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
- }
-
- gmwindow.onYouTubeIframeAPIReady = (event) => {
- youtubeIsLoaded = true;
- console.log('SWMP: Firing YouTube Ready Event from inside PrepareYouTube()');
- this.makeYoutube();
- }
-
-
- } else {
- // API Already loaded, just make video.
- console.log('SWMP: YT API Already loaded, make vid');
- this.makeYoutube();
- }
- }
-
- makeYoutube() {
- // Make new player
- console.log('SWMP: makeYoutube()');
- this.playerfirstrun = true;
- var self = this;
- this.loaded = false;
- this.container.classList.add('swmp-youtube');
- this.onPlayerReady = (event) => {
- this.loaded = true;
- if (!this.container.classList.contains('swmp-youtube')) { //cancel if already changed playlist
- return;
- }
- console.log('SWMP Youtube: onPlayerReady()');
- if (this.playerfirstrun == true) {
- this.playerfirstrun = false;
- this.playerContainer.appendChild(this.ytplayer.getIframe() );
- if (this.playlist) {
- this.windowTitle.textContent = `[${this.playlistLocation+1}/${this.playlist.length}] ${this.ytplayer.getVideoData().title}`;
- } else {
- this.windowTitle.textContent = this.ytplayer.getVideoData().title;
- }
- this.totalTimer.textContent = this.formatSeconds(this.ytplayer.getDuration() );
- this.ytplayer.getIframe().style.display = 'inherit';
-
- this.ytplayer.setVolume(this.defaultVolume);
- this._volume = this.defaultVolume;
- /*if (swmpConfig.muted == 'true') {
- this.ytplayer.mute();
- this.volumeButton.classList.add('swmp-mute');
- } else {
- this.ytplayer.unMute();
- }*/
- this.ytplayer.unMute();
-
- if (this.autoplay == 'true') {
- this.ytplayer.playVideo();
- this.playbutton.classList.add('swmp-playing');
- }
-
-
- }
-
- window.addEventListener('message', function(event) {
- if (event.source === self.ytplayer.getIframe().contentWindow) {
- var data = JSON.parse(event.data);
- //console.log(data);
-
- // Dispatch Volume and Mute Event -- These are sent together by iframe.
- if (data.event === "infoDelivery" && data.info && data.info.volume) {
- //console.log(data.info.volume);
- //console.log(data.info.muted);
- if (data.info.volume != self._volume) {
- //console.log(data.info.volume);
- self.updateVolume();
- }
- }
-
- // Dispatch on Time Event
- if (data.event === "infoDelivery" && data.info && data.info.currentTime) {
- //console.log(data.info.currentTime);
- self.currentTimer.textContent = self.formatSeconds(data.info.currentTime);
- }
-
- // Dispatch on Player state event
- if (data.event === "infoDelivery" && data.info && data.info.playerState) {
- //console.log(data.info.playerState);
- self.updatePlay();
- self.updateVolume();
- }
- }
- });
-
- }
-
- this.videogenerate = document.createElement('div');
- this.videogenerate.style.display = 'none';
- this.videogenerate.setAttribute('id', `ytplayer-${this.id}`);
- document.body.appendChild(this.videogenerate);
-
- this.youtubeautoplay = (swmpConfig.autoplay=='true')?1:0;
- this.youtubeloop = (swmpConfig.loop=='true')?1:0;
-
- this.ytplayer = new gmwindow.YT.Player(`ytplayer-${this.id}`, {
- height: '1080',
- width: '1920', // Allows quality to increase to 1080p. Can't be forced by API, need fast internet.
- videoId: this.videoid,
- playerVars: {
- 'playsinline': 1,
- 'autoplay': this.youtubeautoplay,
- 'loop': this.youtubeloop,
- //'origin': window.location.href,
- 'rel': 0,
- 'modestbranding': 1,
- 'controls': 0
- },
- events: {
- 'onReady': this.onPlayerReady
- }
- });
-
- //console.log(this.ytplayer);
-
- this.playerContainer = document.createElement('div');
- this.playerContainer.setAttribute('class', 'swmp-player-container');
-
- this.container.appendChild(this.playerContainer);
-
- this.prepareSettings();
- this.prepareControls();
- this.prepareSharedEvents();
- this.prepareYoutubeEvents();
-
- if (!this.container.classList.contains('swmp-youtube')) { //cancel if already changed playlist
- this.videogenerate.remove();
- this.ytplayer.remove();
- return false;
- }
-
- }
-
-
- prepareYoutubeEvents() {
-
- this.togglePlay = function() {
- if (this.loaded != true) {
- console.log('Userscript: YT must load before togglePlay.');
- return;
- }
- if (this.ytplayer.getPlayerState() == 1) { // Playing
- this.ytplayer.pauseVideo();
- } else { // -1 unstarted, 0 ended, 1 playing, 2 Pause, 3 buffering, 5 video cued
- this.ytplayer.playVideo();
- this.updateTime();
- }
- }
-
- this.seekBack = function() {
- var time = this.ytplayer.getCurrentTime();
- var max = this.ytplayer.getDuration();
- if (time < 5) {
- time = 0;
- } else {
- time = time - 5;
- }
- this.ytplayer.seekTo(time);
-
- this.seeker.value = Math.floor(time / max * this.seeker.max);
- this.seeker.setAttribute('value', this.seeker.value);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute('value', this.seeker.value);
- }
-
- this.seekForward = function() {
- var time = this.ytplayer.getCurrentTime();
- var max = this.ytplayer.getDuration();
- if (time+5 >= max ) {
- time = max;
- } else {
- time = time + 5;
- }
- this.ytplayer.seekTo(time);
-
- this.seeker.value = Math.floor(time / max * this.seeker.max);
- this.seeker.setAttribute('value', this.seeker.value);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute('value', this.seeker.value);
-
- }
-
- var timeInterval;
- this.updatePlay = () => {
-
- this._playerState = this.ytplayer.getPlayerState();
-
- if (this._playerState == 1) { // Playing
- this.playbutton.classList.add('swmp-playing');
- this.updateTime();
-
-
- var self = this;
- var timeInterval = window.setInterval((event) => {
- self._playerState = self.ytplayer.getPlayerState();
- if (self._playerState == 1) {
- self.updateTime();
- }
- if (self._playerState == 0) { //Ended
- self.updatePlay();
- }
- //console.log('time'); //still bugged on close unlike the other interval, does close on playlist change
- if (self.type != 'youtube' || self._playerState != 1 || self.container == null || self.container == undefined || self.container == false) {
- clearInterval(timeInterval);
- timeInterval = null;
- }
- }, 40);
-
- } else if (this._playerState == 0 || this._playerState == -1 || this._playerState == 2 ) { // -1 unstarted, 0 ended, 1 playing, 2 Pause, 3 buffering, 5 video cued
- this.playbutton.classList.remove('swmp-playing');
- }
-
- if (this._playerState == 0 || this._playerState == -1 ) {
- this.progress.value = 0;
- this.progress.setAttribute('value', 0);
- this.seeker.value = 0;
- this.seeker.setAttribute('value', 0);
- }
-
- if (this._playerState == 0) {
-
- if (this.playlist != undefined && swmpConfig.loop == 'false' && swmpConfig.autoplay == 'true') {
- this.nextMedia();
- return;
- }
-
- if (swmpConfig.loop == 'true') {
- console.log('SWMP: uwah video loop');
- this.ytplayer.seekTo(0);
- this.ytplayer.playVideo();
- }
- }
-
- }
-
- this.seeker.oninput = (event) => {
- if (this.loaded != true) {
- console.log('Userscript: Video must load before seeking');
- return;
- }
- //on mousedown temporary add a mute to avoid annoying seeking sounds?
- this.ytplayer.seekTo(Math.floor(this.ytplayer.getDuration() * this.seeker.value / this.seeker.max) );
- this.progress.value = this.seeker.value;
- this.progress.setAttribute('value', this.seeker.value);
- this.updatePlay();
- }
-
- this.updateTime = () => {
- this.seeker.value = Math.floor(this.ytplayer.getCurrentTime() / this.ytplayer.getDuration() * this.seeker.max);
- this.seeker.setAttribute('value', this.seeker.value);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute('value', this.seeker.value);
- }
-
-
- this.toggleMute = () => {
-
- try {
- if (this.ytplayer.isMuted() == true ) {
- this.volumeButton.classList.remove('swmp-mute');
- this._volume = this.ytplayer.getVolume() ;
- this.ytplayer.unMute();
- this.ytplayer.setVolume(this._volume);
- this.volumeRange.setAttribute('value', this._volume );
- this.volumeRange.value = this._volume;
- this.volumeProgress.setAttribute('value', this._volume );
- this.volumeProgress.value = this._volume;
- swmpConfig.muted = 'false';
- localStorage.swmpMuted = 'false';
- } else {
- this.volumeButton.classList.add('swmp-mute');
- this.ytplayer.mute();
- this.volumeRange.setAttribute('value', 0 );
- this.volumeRange.value = 0;
- this.volumeProgress.setAttribute('value', 0 );
- this.volumeProgress.value = 0;
- swmpConfig.muted = 'true';
- localStorage.swmpMuted = 'true';
- }
- } catch(e) {
- console.log('Userscript: '+e);
- }
- }
-
- this.updateVolume = (firstrun = false) => {
-
- if (this.loaded != true) {
- return;
- }
-
- this.volumeButton.classList.remove('swmp-mute');
-
- if (firstrun == true) {
- this.volumeRange.setAttribute('value', this.defaultVolume);
- this.volumeProgress.setAttribute('value', this.defaultVolume);
- this._volume = this.defaultVolume;
- this.volumeButton.classList.add('swmp-min');
- }
-
- this._volume = this.ytplayer.getVolume();
-
- this.volumeRange.setAttribute('value', this.volumeRange.value );
- this.volumeProgress.setAttribute('value', this.volumeRange.value );
- this.ytplayer.setVolume(this.volumeRange.value);
-
- if (this._volume > 50) {
- this.volumeButton.classList.add('swmp-max');
- this.volumeButton.classList.remove('swmp-med');
- this.volumeButton.classList.remove('swmp-min');
- } else if (this._volume > 10) {
- this.volumeButton.classList.add('swmp-med');
- this.volumeButton.classList.remove('swmp-max');
- this.volumeButton.classList.remove('swmp-min');
- } else if (this._volume > 5) {
- this.volumeButton.classList.add('swmp-min');
- this.volumeButton.classList.remove('swmp-max');
- this.volumeButton.classList.remove('swmp-med');
- }
-
- localStorage.swmpVolume = this.volumeRange.value;
- swmpConfig.volume = this.volumeRange.value;
- }
-
- this.volumeRange.oninput = (event) => {
- this.updateVolume();
- }
-
-
- }
-
- prepareSharedEventsInit() {
-
- this.container.addEventListener('mousemove', event => {
- this.container.classList.add('swmp-movingmouse');
- clearTimeout(this.mousemovetimeout);
- this.mousemovetimeout = window.setTimeout((event) => {
- this.container.classList.remove('swmp-movingmouse');
- }, 1500);
- });
-
- this.volumeScroll = (event) => {
- if (swmpConfig.volumeScroll != 'true') {
- return false;
- }
- event.preventDefault();
- if (this.type == 'video' || this.type == 'audio') {
- if (event.wheelDelta > 0) {
- var vol = this.player.volume + 0.04;
- if (vol > 1.0) {
- vol = 1.0;
- }
-
- } else {
- var vol = this.player.volume - 0.04;
- if (vol < 0.0) {
- vol = 0.0;
- }
- }
- var newvolume = Math.floor(vol * 100);
-
- } else if (this.type == 'youtube') {
- if (event.wheelDelta > 0) {
- var vol = this.ytplayer.getVolume() + 4;
- if (vol > 100) {
- vol = 100;
- }
-
- } else {
- var vol = this.ytplayer.getVolume() - 4;
- if (vol < 0) {
- vol = 0;
- }
- }
- var newvolume = vol;
- }
-
- this.volumeProgress.setAttribute('value', newvolume);
- this.volumeProgress.value = newvolume;
- this.volumeRange.setAttribute('value', newvolume);
- this.volumeRange.value = newvolume;
- this.updateVolume(); // Change icon blah blah
- }
-
- this.container.addEventListener('wheel', event => {
- this.volumeScroll(event);
- });
-
- this.container.addEventListener('keydown', event => {
- if (event.repeat) { return; } // Don't spam
-
- switch(event.key) {
- case ' ': //Space
- this.togglePlay();
- break;
- case 'f':
- this.fullscreen(this.container);
- break;
- case 'm':
- this.toggleMute();
- break;
- case 'x':
- this.container.remove();
- break;
- /*case 'q': // still need do youtube fix for fast skipping, otherwise would work well
- if (this.playlist != undefined) { this.previousMedia(); } else { return; }
- break;
- case 'e':
- if (this.playlist != undefined) { this.nextMedia(); } else { return; }
- break;*/
- case 'ArrowLeft': //left
- this.seekBack();
- break;
- case 'ArrowRight': //right
- this.seekForward();
- break;
- case 'Escape':
- this.container.classList.remove('swmp-fullscreen');
- this.container.classList.remove('swmp-maximized');
- break;
- default:
- return;
- }
-
- event.preventDefault();
-
- }, true);
-
- this.container.addEventListener('fullscreenchange', event => {
- const fullscreenElement =
- document.fullscreenElement ||
- document.mozFullScreenElement ||
- document.webkitFullscreenElement ||
- document.msFullscreenElement;
-
- if (!fullscreenElement) {
- this.container.classList.remove('swmp-fullscreen');
- this.container.classList.remove('swmp-maximized');
- } else {
- this.container.classList.add('swmp-fullscreen');
- }
- });
-
- this.fullscreen = (element) => {
-
- const fullscreenElement =
- document.fullscreenElement ||
- document.mozFullScreenElement ||
- document.webkitFullscreenElement ||
- document.msFullscreenElement;
-
- if (fullscreenElement) {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- window.scrollTo({
- top: this._scroll['y'],
- left: this._scroll['x'],
- behavior: 'auto'
- });
- document.webkitExitFullscreen(); //Safari sucks
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- }
- this.container.classList.remove('swmp-fullscreen');
- this.container.classList.remove('swmp-maximized');
- } else {
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.mozRequestFullScreen) {
- element.mozRequestFullScreen();
- } else if (element.webkitRequestFullscreen) {
- this._scroll = {'x' : window.scrollX, 'y' : window.scrollY}
- element.webkitRequestFullscreen();
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- } else {
- // If no fullscreen on div is supported:
- this.toggleMaximize();
- return;
- }
- this.container.classList.add('swmp-fullscreen');
- }
- }
-
- }
-
- toggleMaximize = (event) => {
- if (event) {
- event.preventDefault();
- }
-
- // Remove fullscreen if toggle off maximize in fullscreen
- const fullscreenElement =
- document.fullscreenElement ||
- document.mozFullScreenElement ||
- document.webkitFullscreenElement ||
- document.msFullscreenElement;
- if (fullscreenElement) {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- window.scrollTo({
- top: this._scroll['y'],
- left: this._scroll['x'],
- behavior: 'auto'
- });
- document.webkitExitFullscreen(); //Safari sucks
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- }
- this.container.classList.remove('swmp-fullscreen');
- this.container.classList.remove('swmp-maximized');
- return;
- }
-
- if (this.type == 'audio' && this.playlist == null) { //allow on playlist, disallow on audio only
- this.container.classList.remove('swmp-maximized');
- return;
- }
- this.container.classList.toggle('swmp-maximized');
- }
-
- prepareSharedEvents() { // Redo on player change
-
- this.playerContainer.addEventListener('click', (event) => {
- this.togglePlay();
- });
-
- this.playerContainer.addEventListener('dblclick', (event) => {
-
- if (swmpConfig.doubleclickMaximize == 'true') {
- this.toggleMaximize();
- return;
- }
-
- this.fullscreen(this.container);
- });
-
- }
-
- preparePlayerEvents() {
-
-
- this.player.onended = (event) => {
- this.player.classList.remove('swmp-playing');
- this.playbutton.classList.remove('swmp-playing');
- this.seeker.value = 0;
- this.progress.value = 0;
- clearInterval(this.player.interval);
- this.currentTimer.textContent = '00:00';
- this.loaded = false;
- if (this.playlist != undefined && swmpConfig.loop == 'false' && swmpConfig.autoplay == 'true') { //doesnt activate on loop
- this.nextMedia();
- return;
- }
- }
-
- this.player.addEventListener('loadedmetadata', (event) => {
- this.totalTimer.textContent = this.formatSeconds(this.player.duration);
- });
-
- this.player.addEventListener('loadeddata', (event) => {
- // Video is loaded and can be played
- this.loaded = true;
- });
-
-
- this.player.onplay = (event) => {
- this.loaded = true;
- this.player.classList.add('swmp-playing');
- this.playbutton.classList.add('swmp-playing');
- this.player.interval = window.setInterval((event) => {
- //console.log('time');
- this.player.timeupdate();
- }, 40);
- }
-
- this.player.onpause = (event) => {
- this.player.classList.remove('swmp-playing');
- this.playbutton.classList.remove('swmp-playing');
- clearInterval(this.player.interval);
- }
-
- this.player.onerror = (event) => {
- clearInterval(this.player.interval);
- var _error = this.player.error.message;
- console.log(_error);
- this.playerContainer.innerHTMl = _error;
- }
-
- this.player.timeupdate = (event) => {
- this.seeker.value = Math.floor(this.player.currentTime / this.player.duration * this.seeker.max);
- this.seeker.setAttribute("value", this.seeker.value);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute("value", this.seeker.value);
- this.updateTimer();
- }
-
- this.seeker.oninput = (event) => {
- if (this.loaded != true) {
- console.log('Userscript: Video status must be loaded first');
- return;
- }
- try {
- //on mousedown temporary add a mute to avoid annoying seeking sounds?
- this.player.currentTime = Math.floor(this.player.duration * this.seeker.value / this.seeker.max);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute("value", this.seeker.value);
- this.updateTimer();
- } catch (e) {
- console.log('Userscript: ' + e);
- }
- }
-
- this.updateTimer = () => {
- this.currentTimer.textContent = this.formatSeconds(this.player.currentTime);
- //this.totalTimer.textContent = this.formatSeconds(this.player.duration);
- }
-
- this.seekBack = function() {
- var time = this.player.currentTime;
- var max = this.player.duration;
- if (time < 5) {
- time = 0;
- } else {
- time = time - 5;
- }
- this.player.currentTime = time;
- this.updateTimer();
-
- this.seeker.value = Math.floor(time / max * this.seeker.max);
- this.seeker.setAttribute('value', this.seeker.value);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute('value', this.seeker.value);
- }
-
- this.seekForward = function() {
- var time = this.player.currentTime;
- var max = this.player.duration;
- if (time+5 >= max ) {
- time = max;
- } else {
- time = time + 5;
- }
- this.player.currentTime = time;
- this.updateTimer();
-
- this.seeker.value = Math.floor(time / max * this.seeker.max);
- this.seeker.setAttribute('value', this.seeker.value);
- this.progress.value = this.seeker.value;
- this.progress.setAttribute('value', this.seeker.value);
-
- }
-
- this.togglePlay = () => {
- try {
- if (this.player.paused ) {
- this.player.play();
- } else {
- this.player.pause();
- }
- } catch (e) {
- console.log('Userscript: ' + e)
- }
- }
-
- this.toggleMute = () => {
- if (this.player.muted) {
- this.volumeButton.classList.remove('swmp-mute');
- this.player.muted = false;
- this._volume = this.player.volume;
- this.volumeRange.setAttribute('value', this._volume * 100 );
- this.volumeRange.value = this._volume * 100;
- this.volumeProgress.setAttribute('value', this._volume * 100 );
- this.volumeProgress.value = this._volume * 100;
- swmpConfig.muted = 'false';
- localStorage.swmpMuted = 'false';
- } else {
- this.volumeButton.classList.add('swmp-mute');
- this.player.muted = true;
- this.volumeRange.setAttribute('value', 0 );
- this.volumeRange.value = 0;
- this.volumeProgress.setAttribute('value', 0 );
- this.volumeProgress.value = 0;
- swmpConfig.muted = 'true';
- localStorage.swmpMuted = 'true';
- }
- //console.log(this._volume);
- }
-
- this.updateVolume = (firstrun = false) => {
-
- this.volumeButton.classList.remove('swmp-mute');
-
- if (firstrun == true) {
- this.volumeRange.setAttribute('value', this.defaultVolume);
- this.volumeProgress.setAttribute('value', this.defaultVolume);
- this.volumeButton.classList.add('swmp-min');
- this._volume = this.defaultVolume;
-
- }
-
- if (this.player.muted) {
- this.player.muted = false;
- }
-
- this.volumeRange.setAttribute('value', this.volumeRange.value );
- this.volumeProgress.setAttribute('value', this.volumeRange.value );
- this.player.volume = parseFloat(this.volumeRange.value / 100);
- this._volume = this.player.volume;
-
- if (this._volume > 0.50) {
- this.volumeButton.classList.add('swmp-max');
- this.volumeButton.classList.remove('swmp-med');
- this.volumeButton.classList.remove('swmp-min');
- } else if (this._volume > 0.10) {
- this.volumeButton.classList.add('swmp-med');
- this.volumeButton.classList.remove('swmp-max');
- this.volumeButton.classList.remove('swmp-min');
- } else if (this._volume > 0.05) {
- this.volumeButton.classList.add('swmp-min');
- this.volumeButton.classList.remove('swmp-max');
- this.volumeButton.classList.remove('swmp-med');
- }
-
- //console.log(this._volume);
-
- localStorage.swmpVolume = this.volumeRange.value;
- swmpConfig.volume = this.volumeRange.value;
- }
-
- this.volumeRange.oninput = (event) => {
- this.updateVolume();
- }
-
- this.player.addEventListener('volumechange', this.updateVolume() );
- this.updateVolume(true); // First time Run
- }
-
- formatSeconds = (seconds) => {
- this._sec_num = parseInt(seconds, 10);
- this._hours = Math.floor(this._sec_num / 3600);
- this._minutes = Math.floor(this._sec_num / 60) % 60;
- this._seconds = this._sec_num % 60;
-
- return [this._hours,this._minutes,this._seconds]
- .map(v => v < 10 ? "0" + v : v)
- .filter((v,i) => v !== "00" || i > 0)
- .join(":");
- }
-
- removeClassByPrefix(el, prefix) {
- let pattern = '(' + prefix + '(\\s|(-)?(\\w*)(\\s)?)).*?';
- var regEx = new RegExp(pattern, 'g');
- el.className = el.className.replace(regEx, '');
- }
-
- uuid() {
- // Source: https://www.w3resource.com/javascript-exercises/javascript-math-exercise-23.php
- var dt = new Date().getTime();
- var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = (dt + Math.random()*16)%16 | 0;
- dt = Math.floor(dt/16);
- return (c=='x' ? r :(r&0x3|0x8)).toString(16);
- });
- return uuid;
- }
-
- getFileName(url) {
- return url.split('/').pop().split('#')[0].split('?')[0];
- }
-
- checkURL(url) {
-
- // if match youtube regex then do this and return
- var result = ytregex.exec(url);
- //console.log(ytregex);
- //console.log(url);
- //console.log(result);
- if (url.match(ytregex) ) {
- console.log('SWMP: YouTube');
- this.type = 'youtube';
- this.videoid = result[1];
- console.log('SWMP: Youtube ID: '+ this.videoid);
- return true;
- }
-
- console.log("SWMP: Video or Audio");
- // Check filename in URL for Type / MIME.
- this.fileExt = url.split(/[#?&]/)[0].split('.').pop().trim();
- this.fileExt = url.split(/[#?&]/).slice(-2)[0].split('.').pop().trim();
-
-
- console.log(this.fileExt);
- this.fileExt = this.fileExt.toLowerCase();
-
- switch (this.fileExt) {
- //VIDEO
- case 'avi':
- this.type = 'video';
- this.mime = 'video/x-msvideo';
- break;
- case 'mpeg':
- this.type = 'video';
- this.mime = 'video/mpeg';
- break;
- case 'mpg':
- this.type = 'video';
- this.mime = 'video/mpeg';
- break;
- case 'ogv':
- this.type = 'video';
- this.mime = 'video/ogg';
- break;
- case 'mp4':
- this.type = 'video';
- this.mime = 'video/mp4';
- break;
- case 'webm':
- this.type = 'video';
- this.mime = 'video/webm';
- break;
- case 'flv':
- this.type = 'video';
- this.mime = 'video/x-flv';
- break;
- //AUDIO
- case 'wav':
- this.type = 'audio';
- this.mime = 'audio/x-wav';
- break;
- case 'mp3':
- this.type = 'audio';
- this.mime = 'audio/mpeg';
- break;
- case 'm4a':
- this.type = 'audio';
- this.mime = 'audio/mp4';
- break;
- case 'mp2':
- this.type = 'audio';
- this.mime = 'audio/mpeg';
- break;
- case 'ogg':
- this.type = 'audio';
- this.mime = 'audio/ogg';
- break;
- case 'flac':
- this.type = 'audio';
- this.mime = 'audio/flac';
- break;
- default:
- console.log('No matching ext/mime');
- console.log(this.fileExt);
- return false;
- }
- return true; //If valid
- }
-
- makeDraggable (element){
- var elm = this.windowTitlebar;
-
- element.style.position = 'fixed';
- element.style.top = swmpConfig.positionTop + 'px';
-
- if (swmpConfig.positionSide == 'right') {
- element.style.right = swmpConfig.positionOffset + 'px';
- } else {
- element.style.left = swmpConfig.positionOffset + 'px';
- }
-
- var isMouseDown = false,
- mouseX,
- mouseY,
- elmTop,
- elmLeft,
- diffX,
- newElmTop,
- newElmLeft,
- diffY,
- rightBarrier,
- bottomBarrier;
-
- function mouseDown(e) {
-
- if (e.which == '3') {
- return false; // Right click
- }
-
- element.focus();
-
- isMouseDown = true;
-
- mouseX = e.clientX;
- mouseY = e.clientY;
-
- elmTop = element.offsetTop;
- elmLeft = element.offsetLeft;
- diffX = mouseX - elmLeft;
- diffY = mouseY - elmTop;
-
- }
-
- function mouseUp() {
- isMouseDown = false;
-
-
- if (swmpConfig.positionSide == 'right') {
- var currentleft = parseInt(element.style.left, 10);
- element.style.left = "unset";
- element.style.right = document.documentElement.clientWidth - currentleft - element.offsetWidth + "px";
- }
-
- }
-
- function mouseMove(e) {
-
-
- if (!isMouseDown) return;
-
- if (e.which != '1') {
- isMouseDown = false;
- }
-
- if (element.classList.contains('swmp-maximized') ) return;
- //element.classList.remove('swmp-maximized');
-
- var newMouseX = e.clientX;
- var newMouseY = e.clientY;
-
- newElmTop = newMouseY - diffY;
- newElmLeft = newMouseX - diffX;
-
- rightBarrier = document.documentElement.clientWidth - element.offsetWidth;
- bottomBarrier = window.innerHeight - element.offsetHeight;
-
- if( ( newElmLeft < 0 ) || ( newElmTop < 0) || ( newElmLeft > rightBarrier ) || (newElmTop > bottomBarrier) ) {
- if ( newElmLeft < 0 ) {
- newElmLeft = 0;
-
- }
-
- if ( newElmTop < 0) {
- newElmTop = 0;
-
- }
- if ( newElmLeft > rightBarrier ) {
- newElmLeft = rightBarrier;
-
- }
- if (newElmTop > bottomBarrier) {
- newElmTop = bottomBarrier;
- }
- }
-
- element.style.top = newElmTop + "px";
- element.style.bottom = "unset";
-
- if (element.offsetTop < 0) {
- element.style.top = "0px";
- }
-
- if (swmpConfig.positionSide == 'right') {
- element.style.left = newElmLeft + "px";
- element.style.right = "unset";
- } else {
- element.style.left = newElmLeft + "px";
- }
-
- }
-
- document.addEventListener('mousemove', mouseMove);
- document.addEventListener('mouseup', mouseUp);
- elm.addEventListener('mousedown', mouseDown);
- }
-
- }
-
- // Above this is SWMP class.
-
-
- // Below this is the event listener that checks if what you are clicking on is a video or audio that should be put into SWMP.
- // If you want to make site specific changes, either expand on it or just make a completely separate event listener below it.
-
- document.addEventListener('click', (event) => {
- //console.log("Userscript - "+event.target.tagName);
-
- // If there are no links in sight, do nothing.
- if (event.target.tagName != 'A' && event.target.parentNode.tagName != 'A') {
- return;
- }
- // Lets figure out which one is the link. Wont normally chain As inside As so... Sometimes image may be inside span inside A so lets do 3x.
- var clicked = false;
- if (event.target.tagName == 'A') {
- clicked = event.target;
- } else if (event.target.parentNode.tagName == 'A') {
- clicked = event.target.parentNode;
- } else if (event.target.parentNode.parentNode.tagName == 'A') {
- clicked = event.target.parentNode.parentNode;
- }
-
- // Download attribute override
- if (swmpConfig.downloadAttribute == 'false' && clicked.hasAttribute('download')) {
- return;
- }
-
- function getVideo() {
- if (backendScript == '' || backendScript == null || backendScript == undefined || backendScript == 'fourchan') {
- return clicked.getAttribute('href');
- } else if (backendScript == 'vichan') {
- //console.log("Userscript - "+clicked.parentNode.querySelectorAll('p.fileinfo a') );
-
- var allthelinks = clicked.parentNode.querySelectorAll('p.fileinfo a'); // Prevent capturing the (Hide) link on some installs
- var matchinglink = '';
- for (var i = 0; i < allthelinks.length ; i++) {
- if (allthelinks[i].getAttribute('href').match(fileregex) ) {
- matchinglink = allthelinks[i];
- }
- }
-
- if (matchinglink == '') { // Kissu New UI (no thanks, but here it is anyways) <- This should also return normal href if not video?
- matchinglink = clicked;
- }
-
- //console.log("Userscript - "+matchinglink);
- return matchinglink.getAttribute('href');
-
- } else {
- return clicked.getAttribute('href');
- }
-
- }
-
- function getFileNameFromUrl(link) {
- if (backendScript == '' || backendScript == null || backendScript == undefined || backendScript == 'fourchan') {
- return link;
- } else if (backendScript == 'vichan') {
- return link;
- } else {
- return link;
- }
-
- }
-
- function getTitle(link) {
- if (backendScript == 'fourchan') {
- if (link.parentNode.querySelector('div.fileText a') != null) {
- if (link.parentNode.querySelector('div.fileText a').getAttribute('title') ) {
- return link.parentNode.querySelector('div.fileText a').getAttribute('title');
- } else {
- return link.parentNode.querySelector('div.fileText a').innerText;
- }
- } else {
- return link.getAttribute('href');
- }
- }
-
- if (backendScript == 'vichan') { // https://regex101.com/r/HivDYB/3
- let regex = new RegExp(`((?:[^\.|^\/|^\=|^\n|^\&])+(?:\.)(?:${swmpConfig.files}))(?:[^(\w)]|$)`, 'gmi'); // Tests for www.webmaster.com/test.webm domain too.
- var newlink = [...link.matchAll(regex)]; // Remove query behind *final filename* &title for old filename on vichan will stay.
- return newlink.slice(-1)[0][1]; // return last in array, grabs t= title for vichan player.php links.
- }
- }
-
- var clickedHref;
- var clickedFileName;
- var clickedTitle;
- var anythingmatch;
-
- function isYoutube(link) {
- var result = ytregex.exec(link);
-
- if (link.match(ytregex) != null ) {
- anythingmatch = true;
- console.log('Userscript - YouTube: '+result[1]); // Video ID
- clickedTitle = 'YouTube: ' + result[1];
- return true;
- } else {
- console.log('Userscript - Not YouTube');
- return false;
- }
- }
-
- // If youtube
-
- if (isYoutube(clicked.getAttribute('href') ) ) {
- console.log('Userscript - YouTube link clicked');
- clickedHref = clicked.getAttribute('href');
- //clickedTitle = 'Loading YouTube';
- }
-
- function isVideo(link) {
- var result = fileregex.exec(link);
-
- if (link.match(fileregex) != null) {
- anythingmatch = true;
- console.log('Userscript - Video/Audio match:' + result);
- return true;
- } else {
- console.log('Userscript - Not Video/Audio');
- return false;
- }
- }
-
- //get video links
- clickedHref = getVideo();
-
- if (isVideo(clickedHref) ) {
- //clickedHref = getVideo();
- clickedFileName = getFileNameFromUrl(clicked.getAttribute('href') );
- clickedTitle = false;
- if (backendScript == '' || backendScript == null || backendScript == undefined) {
- clickedTitle = decodeURI(clickedFileName); //Change with other scripts later if it doesn't already contain the title.
- } else if (backendScript == 'fourchan') {
- clickedTitle = decodeURI(getTitle(clicked) );
- } else if (backendScript == 'vichan') {
- clickedTitle = getTitle(decodeURI(clicked.getAttribute('href') ) );
- } else {
- clickedTitle = decodeURI(clickedFileName); //Change with other scripts later if it doesn't already contain the title.
- }
-
- console.log("Userscript - URL: " + clicked.getAttribute('href') );
- console.log("Userscript - Filename: " + clickedFileName );
- console.log("Userscript - Title: " + clickedTitle);
- }
-
- if (anythingmatch != true) {
- return false;
- } else {
- // If video audio or youtube matched, prevent other events.
- event.preventDefault();
- event.stopPropagation();
- }
-
- // todo:
- // toggleable check if has download attribute?
- // add Q/E shortcut for prev/next <- yt bugs on fast move
-
- // Check if ctrl-shift-click and scan all links for yt/media, get titles,
- // remove player.php + & tag from vichan to not get different url from link and thumb
- // strip duplicates, feed to playlist WITH title
- // Guess I'll need the ability to push urls+title to the player,
- // lets send ["url", "title"] also adapt title get on playlist to grab from playlist
-
-
- // Okay, time to load the player.
- var playerid = false;
-
- if (swmpConfig.allowMultiple != 'false') {
- playerid = `play-swmp-${clicked.getAttribute('href')}`;
- } else {
- playerid = 'play-swmp';
- }
-
- if (typeof(document.getElementById(playerid)) != 'undefined' && document.getElementById(playerid) != null) {
- if (swmpConfig.allowMultiple != 'false') {
- return false; //already exists, lets do nothing.
- } else {
- document.getElementById(playerid).remove();
- //already exists, lets get rid of it.
- }
- }
-
- //console.log(playerid+clickedHref+clickedTitle);
- let newembed = new swmp({
- id: playerid,
- url: clickedHref,
- title: clickedTitle
- });
-
- //console.log(backendScript);
- if (backendScript == 'jschan') { // Might be useful for inline.
- clicked.parentNode.parentNode.appendChild(newembed.container);
- } else {
- clicked.parentNode.appendChild(newembed.container);
- }
-
- // Give focus to player for keybinds.
- newembed.container.focus();
-
-
- }, true); // Fuck other scripts.