├── LICENSE ├── README.md ├── blurryCardBackground.js ├── pwPlayer - Browser.js ├── pwPlayer - Fullscreen v0.5.js ├── pwPlayer - Oculus v0.5.js ├── pwPlayer - PiP v0.5.js └── pwPlayer.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Philip Wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stash Custom Javascripts - Unexpectably Powerful ! 2 |

3 | 4 | #### This repo contains custom javascripts to be used in the amazing [StashApp](https://github.com/stashapp/stash), which empower you to manage all your special video collections. Credits to all the incredible, talented and hardworking programmers who make the StashApp so elegant and useful ! 5 | 6 | File to use: 7 | * pwPlayer.js : This is the latest development. 8 | * pwPlayer - PiP v0.5.js : This This is pre-configured js file for playing videos in Picture-in-Picture mode. Default size is 800x450, you can change it in the script. 9 | * pwPlayer - Fullscreen v0.5.js : This This is pre-configured js file for playing videos in Fullscreen mode. 10 | * pwPlayer - Browser v0.5.js : This This is pre-configured js file for playing videos in Browser mode, which the video will fill up the available browser space, but it will not make the browser fullscreen. 11 | * pwPlayer - Oculus v0.5.js : This is pre-configured js file for Oculus Browser. Every video will be played in full screen mode. Works great for VR videos! In fullscreen you need to choose the VR mode like 180 and 3D side by side. The browser will not remember it. When the playing is done, click on the pause button and you will be back to the scene wall immediately. 12 | * blurryCardBackground.js: Fill scene/movie/image/gallery/studio cards with blurry background. Inspired by CJ in Discord channel. 13 | 14 | ### Reason to create a repo just for this: 15 | 16 | StashApp is an excellent video management system for all your desires. It has many great features, but playing videos is a little short.

17 | I made an AutoIt program just to enhance its video playback capability, yet that's not cross-platform and the program has problems here and there.

18 | Well, in Stash version v0.18 there is a new feature called "Custom Javascript". I saw someone submitted a script to enable IINA player on MacOS. I was curious and started to modify that script. Little did I knew that "Custom Javascript" in StashApp can be so powerful ! I can actually utilize the full pontential of the browsers, Stash and platforms !

19 | 20 | ----- 21 | 22 | ### To install my scripts 23 | Just copy the content of the script you choose and paste them into the "Settings->Interface->Custom Javascript". Reload the browser and done.

24 | Please don't paste 2 scripts into it, or mixing different scripts together. It usually won't work. Or you are also familiar with Javascript, then you can do your own mixing. 25 | 26 | ----- 27 | 28 | ### pwPlayer.js - Scene Card Quick Player 29 |
30 | This Javascript will create a "Play" button in each scene card. You can click on it and the video for that scene will be played right away. Click on the video again, then you are back to the scene list. 31 | #### Features 32 | * You Use different mode to watch the video 33 | - browser mode: video will be played inside the browser. 34 | - browserfull mode: video will be played inside the browser, but in fullscreen mode. 35 | - player mode: script will try to send the video to an external player like VLC. It works well in Android, but others need more work. 36 | * One click to end the play back, and you will see the scene selection again. Very convenient. 37 | * Worked and tested in all 3 major browsers: Chrome, Firefox and Ms Edge. 38 | * Now it can show detailed information for the scene file: 39 | * 40 | #### Versions 41 | - v0.5 Added "browserpip" mode, which the video will be played in a draggable window. 42 | - v0.4 The browser and browserfull mode is better. Oculus browser now can play videos in browserfull mode. Useful for VR videos. 43 | - v0.3 Add "browserfull" mode and test fullscreen feature in all 3 browsers. 44 | - v0.2 Seperate the code with different mode: "browsers" and "player". 45 | - v0.1 Add file details to the on mouse hover event. 46 | 47 | ### blurryCardBackground - Add blurry background to scene/movie/gallery/image/studio. 48 | It fills up the background with blurry images like this:

49 |

50 | CJ made the original CSS and javascript. I completed the script and make it works in most pages. 51 | This script is better to be used alone, don't mix it up. 52 | 53 | 54 | -------------------------------------------------------------------------------- /blurryCardBackground.js: -------------------------------------------------------------------------------- 1 | /* Created by CJ|500+ TB Stash in Discord channel. 2 | This script will make each scene/movie/gallery/performer/studio card's background to be blurry. 3 | To use it, just copy and paste the code into Stash->Settings->Interface->Custome Javascript. 4 | Then refresh the browser. 5 | 6 | This script is intended to be use as the only script in the custom javascript setting. 7 | */ 8 | 9 | // settings 10 | const debug = true; 11 | 12 | function log(str){ 13 | if(debug)console.log(str); 14 | } 15 | log("program starts."); 16 | // style 17 | const blurry_style = document.createElement("style"); 18 | blurry_style.innerHTML = ` 19 | .thumbnail-section::after { 20 | -webkit-backdrop-filter: blur(5px); 21 | backdrop-filter: blur(5px); 22 | 23 | content: ""; 24 | display: block; 25 | position: absolute; 26 | width: 100%; height: 100%; 27 | top: 0; 28 | } 29 | 30 | .thumbnail-section { 31 | position: relative; 32 | background-position: center; 33 | } 34 | `; 35 | 36 | // wait for last elm of page 37 | const blurry_config = { subtree: true, childList: true }; 38 | const blurry_WaitElm = "span[class^='filter-container']"; 39 | 40 | const blurry_waitForElm = (selector) => { 41 | return new Promise(resolve => { 42 | if (document.querySelector(selector)) { 43 | return resolve(document.querySelector(selector)); 44 | } 45 | 46 | const observer = new MutationObserver(mutations => { 47 | if (document.querySelector(selector)) { 48 | resolve(document.querySelector(selector)); 49 | observer.disconnect(); 50 | } 51 | }); 52 | observer.observe(document.body, blurry_config); 53 | }); 54 | }; 55 | 56 | // initial 57 | var blurry_node = null; 58 | if(addStyle()){ 59 | blurry_waitForElm(blurry_WaitElm).then(() => { 60 | addImageSource(); 61 | }); 62 | } 63 | // route 64 | let previousUrl = window.location.href; 65 | const observer = new MutationObserver(function (mutations) { 66 | if (window.location.href !== previousUrl) { 67 | previousUrl = window.location.href; 68 | if (blurry_node != null){ 69 | document.head.removeChild(blurry_node); 70 | blurry_node = null; 71 | } 72 | 73 | if(addStyle()){ 74 | blurry_waitForElm(blurry_WaitElm).then(() => { 75 | addImageSource(); 76 | }); 77 | } 78 | } 79 | }); 80 | 81 | observer.observe(document, blurry_config); 82 | 83 | function addStyle(){ 84 | category = getCat() 85 | switch (category){ 86 | case "scene": 87 | case "movie": 88 | case "image": 89 | case "gallery": 90 | case "performers": 91 | blurry_node = document.head.appendChild(blurry_style); 92 | return true; 93 | default: 94 | return false; 95 | } 96 | } 97 | 98 | 99 | // Main function. 100 | function addImageSource() { 101 | cat = getCat(); 102 | 103 | log( "cat:" + cat ); 104 | if (cat == "others"){ 105 | // just in case 106 | document.head.removeChild(blurry_node); 107 | return; 108 | } 109 | 110 | // Add style here 111 | log("adding images.") 112 | // Galleries? 113 | var cards = document.querySelectorAll("div[class^='" + cat +"-card ']"); 114 | if (cards.length == 0) { 115 | if ( cat == "gallery" ){ 116 | cat = "image"; 117 | cards = document.querySelectorAll("div[class^='image-card ']"); 118 | }else if(cat == "movie"){ 119 | cat = "scene"; 120 | cards = document.querySelectorAll("div[class^='scene-card ']"); 121 | } 122 | } 123 | log("cards:" + cards.length) 124 | cards.forEach(card => { 125 | thumbnail_section = card.querySelector('.thumbnail-section'); 126 | if (thumbnail_section === null ){ 127 | log("no thumb section."); 128 | return; 129 | } 130 | switch (cat){ 131 | case "gallery": 132 | case "movie": 133 | case "performer": 134 | preview_image = card.querySelector("img." + cat + "-card-image"); 135 | break; 136 | default: 137 | preview_image = card.querySelector("img." + cat + "-card-preview-image"); 138 | } 139 | if (preview_image === null){ 140 | log( "preview image is null. " ); 141 | return; 142 | } 143 | // patch code 1 144 | if (cat == "scene"){ 145 | preview_video = card.querySelector("video.scene-card-preview-video"); 146 | if (preview_video !== null){ 147 | preview_video.style.zIndex = "2"; 148 | } 149 | } 150 | 151 | preview_image.style.position = "relative"; 152 | preview_image.style.zIndex = "1"; 153 | 154 | thumbnail_section.style.backgroundImage = "url(" + preview_image.src + ")"; 155 | 156 | }); 157 | }; 158 | 159 | function getCat(){ 160 | url = new URL(window.location.href); 161 | path = String(url.pathname); 162 | log("path:" + path); 163 | const catArray = path.match( /\/[a-z]+/ ) 164 | if (catArray == null ) return "others"; 165 | if(catArray[0] == "/galleries") { 166 | return "gallery"; 167 | }else{ 168 | // get rid of the '/' in the beginning and "s" in the end 169 | cat = catArray[0].slice(1,-1); 170 | if (["scene", "movie", "image", "performer" ].indexOf(cat) !== -1) 171 | return cat; 172 | return "others"; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /pwPlayer - Browser.js: -------------------------------------------------------------------------------- 1 | /* Inspired by clangmoyai's IINA player script in github ! 2 | This script will add a "Play" button in each scene card. 3 | Allow you to easily play those video files. 4 | To use it, just copy and paste the code into Stash->Settings->Interface->Custome Javascript. 5 | Then refresh the browser. 6 | 7 | Player mode should be either "browser", "browserfull", "browserpip" or "player" 8 | * browser: The video is played within a