From b4746231b5161671e96a37ded34fd24f8eb16c79 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Mon, 9 Jan 2023 03:24:02 -0500 Subject: [PATCH 01/14] Create pwPlayer.js --- scripts/SceneCardVideoPlayer/pwPlayer.js | 307 +++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 scripts/SceneCardVideoPlayer/pwPlayer.js diff --git a/scripts/SceneCardVideoPlayer/pwPlayer.js b/scripts/SceneCardVideoPlayer/pwPlayer.js new file mode 100644 index 00000000..0aa6f301 --- /dev/null +++ b/scripts/SceneCardVideoPlayer/pwPlayer.js @@ -0,0 +1,307 @@ +// Inspired by clangmoyai's IINA player script in github ! +// This script will add a "Play" button in each scene card. +// Allow you to easily play those video files. +// To use it, just copy and paste the code into Stash->Settings->Interface->Custome Javascript. +// Then refresh the browser. +// This is only version 1.0 + +// settings +const debug = false; +function log(str){ + if(debug)console.log(str); +} + +const pwPlayer_settings = { + "Mode": "local", + // Path fixes for different OS + "Windows":{ + // Not used. + "urlScheme": "file:///", + // double backsplashes need 4 backslashes. + "replacePath": ["\\\\", "/"], + }, + "Android":{ + // Not used. + "urlScheme": "file:///", + "replacePath": ["", ""], + }, + "iOS":{ + // Not use + "urlScheme": "file://", + "replacePath": ["", ""], + }, + "Linux":{ + // not use + "urlScheme": "file://", + "replacePath": ["", ""], + }, + "MacOS":{ + // For local iina player. + "urlScheme": "iina://weblink?url=file://", + "replacePath": ["", ""], + } +}; + +// style +const pwPlayer_style = document.createElement("style"); +pwPlayer_style.innerHTML = ` + .pwPlayer_button { + border-radius: 3.5px; + cursor: pointer; + padding: 2px 9px 3px 13px; + } + .pwPlayer_button:hover { + background-color: rgba(138, 155, 168, .15); + } + .pwPlayer_button svg { + fill: currentColor; + width: 1em; + vertical-align: middle; + } + .pwPlayer_button span { + font-size: 13px; + font-weight: 500; + letter-spacing: 0.1em; + color: currentColor; + vertical-align: middle; + margin-left: 3px; + } + #pwPlayer_videoDiv{ + background: black; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 99; + } +} +`; + +// Only need to call once. +const pwPlayer_OS = pwPlayer_getOS(); +log("OS: " + pwPlayer_OS); +document.head.appendChild(pwPlayer_style); + + +// api +const pwPlayer_getSceneInfo = async href => { + const regex = /\/scenes\/(\d+)\?/, + sceneId = regex.exec(href)[1], + graphQl = `{ findScene(id: ${sceneId}) { files { path }, paths{stream} } }`, + response = await fetch("/graphql", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ query: graphQl }) + }); + return response.json(); +}; + +function pwPlayer_getOS() { + var userAgent = window.navigator.userAgent, + platform = window.navigator?.userAgentData?.platform, + macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], + windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'], + iosPlatforms = ['iPhone', 'iPad', 'iPod'], + os = null; + + if (macosPlatforms.indexOf(platform) !== -1) { + os = 'MacOS'; + } else if (iosPlatforms.indexOf(platform) !== -1) { + os = 'iOS'; + } else if (windowsPlatforms.indexOf(platform) !== -1) { + os = 'Windows'; + } else if (/Android/.test(userAgent)) { + os = 'Android'; + } else if (/Linux/.test(platform)) { + os = 'Linux'; + } + + return os; +} + +// promise +const pwPlayer_waitForElm = selector => { + return new Promise(resolve => { + if (document.querySelector(selector)) { + return resolve(document.querySelector(selector)); + } + const observer = new MutationObserver(mutations => { + if (document.querySelector(selector)) { + resolve(document.querySelector(selector)); + observer.disconnect(); + } + }); + observer.observe(document.body, { + childList: true, + subtree: true + }); + }); +}; + +// initial +pwPlayer_waitForElm("video").then(() => { + pwPlayer_addButton(); +}); + +// route +let previousUrl = ""; +const observer = new MutationObserver(function (mutations) { + if (window.location.href !== previousUrl) { + previousUrl = window.location.href; + pwPlayer_waitForElm("video").then(() => { + pwPlayer_addButton(); + }); + } +}); +const config = { subtree: true, childList: true }; +observer.observe(document, config); + +// main +const pwPlayer_addButton = () => { + const scenes = document.querySelectorAll("div.row > div"); + for (const scene of scenes) { + if (scene.querySelector("a.pwPlayer_button") === null) { + const scene_url = scene.querySelector("a.scene-card-link"), + popover = scene.querySelector("div.card-popovers"), + button = document.createElement("a"); + button.innerHTML = ` + + + Play`; + + button.classList.add("pwPlayer_button"); + button.href = "javascript:;"; + button.onclick = () =>{ + pwPlayer_getSceneInfo(scene_url.href) + .then((result) =>{ + const streamLink = result.data.findScene.paths.stream; + const filePath = result.data.findScene.files[0].path + .replace(pwPlayer_settings[pwPlayer_OS].replacePath[0], ""); + switch (pwPlayer_OS){ + case "Mac OS": + // For iina player. + if(debug)alert("you just click play in MacOS"); + if (pwPlayer_settings.Mode == "local"){ + href = pwPlayer_settings.MacOS.urlScheme + + pwPlayer_settings.MacOS.replacePath[1] + + encodeURIComponent(filePath); + }else{ + href = streamLink; + } + playVideoInBrowser(streamLink); + break; + case "iOS": + if(debug)alert("you just click play in iOS"); + playVideoInBrowser(streamLink); + break; + case "Android": + if(debug)alert("you just click play in Android"); + intent = new Intent(android.content.Intent.ACTION_VIEW); + if (pwPlayer_settings.Mode == "local"){ + uriData = Uri.parse( pwPlayer_settings.Android.urlScheme + filePath); + }else{ + uriData = Uri.parse(streamLink); + } + intent.setDataAndType(uriData, "video/*"); + context.startActivity(intent); + break; + case "Windows": + if(debug)alert("you just click play in Windows"); + log("streamLink:" + streamLink); + playVideoInBrowser(streamLink); + break; + default: + if(debug)alert("You just click play in an unknow OS."); + + } + }); + + }; + + if (popover) popover.append(button); + + button.onmouseover = () => { + if (button.title.length == 0) { + pwPlayer_getSceneInfo(scene_url.href) + .then((result) => { + // console.log("result: " + JSON.stringify(result)); + const filePath = result.data.findScene.files[0].path + .replace(pwPlayer_settings[pwPlayer_OS].replacePath[0], ""); + button.title = filePath; + }); + } + }; + } + } +}; + +function playVideoInBrowser(streamLink){ + var pwPlayer_video_div = document.createElement("div"); + // log("video_div instance of node:" + (video_div instanceof Node)); + + pwPlayer_video_div.id = "pwPlayer_videoDiv"; + var pwPlayer_video = document.createElement("video"); + pwPlayer_video.autoplay = true; + pwPlayer_video.controls = true; + pwPlayer_video.src = streamLink; + pwPlayer_video.width = window.innerWidth-20; + pwPlayer_video.height = window.innerHeight; + pwPlayer_video_div.appendChild(pwPlayer_video); + var pwPlayer_divNode = document.body.insertBefore(pwPlayer_video_div, document.body.firstChild); + // log("divNode instance of node:" + (divNode instanceof Node)); + log("win w:" + window.innerWidth); + log("win h: "+ window.innerHeight); + window.addEventListener('resize', () => { + pwPlayer_video.width = window.innerWidth-20; + pwPlayer_video.height = window.innerHeight; + }); + // save the scroll postion. + var pwPlayer_scrollPos; + if (typeof window.pageYOffset != 'undefined') { + pwPlayer_scrollPos = window.pageYOffset; + } + else if (typeof document.compatMode != 'undefined' && document.compatMode != 'BackCompat') { + pwPlayer_scrollPos = document.documentElement.scrollTop; + } + else if (typeof document.body != 'undefined') { + pwPlayer_scrollPos = document.body.scrollTop; + } + log("scroll pos:" + pwPlayer_scrollPos); + + window.scrollTo(0,0); + + // track mouse y position + var pwPlayer_mouseY = 0; + document.onmousemove = (e) => { + pwPlayer_mouseY = e.clientY; + } + + pwPlayer_video.onerror = () => { + alert("Error playing this video."); + document.body.removeChild(pwPlayer_divNode); + log("Error in playing, scroll pos:" + pwPlayer_scrollPos); + window.scrollTo(0, pwPlayer_scrollPos); + } + + pwPlayer_video.onpause = (event) => { + var rect = event.target.getBoundingClientRect(); + var y = rect.top + rect.height - pwPlayer_mouseY; + log("client Y:" + pwPlayer_mouseY + " y:" + y + ' rect h:' + rect.height); + if ( Math.abs(y) < rect.height / 5 ) return; + + + document.body.removeChild(pwPlayer_divNode); + log("play ends, scroll pos:" + pwPlayer_scrollPos); + window.scrollTo(0, pwPlayer_scrollPos); + } + pwPlayer_video.onended = () => { + document.body.removeChild(pwPlayer_divNode); + window.scrollTo(0, pwPlayer_scrollPos); + } +} + + From a23b81ba570de2eb2140b2580549bc35a15500c2 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Mon, 9 Jan 2023 03:24:59 -0500 Subject: [PATCH 02/14] Create README.MD --- scripts/SceneCardVideoPlayer/README.MD | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 scripts/SceneCardVideoPlayer/README.MD diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD new file mode 100644 index 00000000..866843a6 --- /dev/null +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -0,0 +1,10 @@ +# Scene Card Video Player +

+ +

+Inspired by clangmoyai's IINA plugin. I added more cross platform support.
+It is tested fully in windows 11 environment. Hopefully it will work in others.
+The script will add a simple "Play" button for each scene card. You click on it, and the video get played.
+You click on the video, then it will disappear. You are back to the scene list.
+Well, it's supposed to be this simple. Don't know why Stash guys make it so complicated.
+So, enjoy play with it. In the future I will try to make it work with DeoVr. From f6f99936bcb8cd39f89458d7c3814fa39d571d39 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Mon, 9 Jan 2023 03:27:50 -0500 Subject: [PATCH 03/14] Update README.MD --- scripts/SceneCardVideoPlayer/README.MD | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index 866843a6..ce4d0f76 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -1,10 +1,13 @@ # Scene Card Video Player

- +

Inspired by clangmoyai's IINA plugin. I added more cross platform support.
It is tested fully in windows 11 environment. Hopefully it will work in others.
-The script will add a simple "Play" button for each scene card. You click on it, and the video get played.
+ +* The script will add a simple "Play" button for each scene card. You click on it, and the video get played.
You click on the video, then it will disappear. You are back to the scene list.
-Well, it's supposed to be this simple. Don't know why Stash guys make it so complicated.
+* To install it, copy and paste the code from the pwPlayer.js into Stash->Settings->Interface->Custom Javascript.
+Then refresh the browser. +* Well, it's supposed to be this simple. Don't know why Stash guys make it so complicated.
So, enjoy play with it. In the future I will try to make it work with DeoVr. From 3b3f05c28eb2925365a43611b5edc39ac369b4d9 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Mon, 9 Jan 2023 03:35:44 -0500 Subject: [PATCH 04/14] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 4c902a77..3f5decd2 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,8 @@ Category|Plugin Name|Description|Minimum Stash version --------|-----------|-----------|--------------------- Kodi|[Kodi Helper](scripts/kodi-helper)|Generates `nfo` and `strm` for use with Kodi.|v0.7 Maintenance|[Stash Sqlite Renamer](scripts/Sqlite_Renamer)|Renames your files using stash's metadata.|v0.7 + +## Custom Javascripts +Category|Plugin Name|Description|Minimum Stash version +--------|-----------|-----------|--------------------- +Scene Player|[SceneCardVideoPlayer](/scripts/SceneCardVideoPlayer)|Create a "Play" button for each scene in the list.|v0.18 From 3f4e1252f6d1190c8c0b457682d1911e18625e40 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Mon, 9 Jan 2023 10:26:20 -0500 Subject: [PATCH 05/14] Update pwPlayer.js --- scripts/SceneCardVideoPlayer/pwPlayer.js | 38 ++++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/scripts/SceneCardVideoPlayer/pwPlayer.js b/scripts/SceneCardVideoPlayer/pwPlayer.js index 0aa6f301..a44d9f4d 100644 --- a/scripts/SceneCardVideoPlayer/pwPlayer.js +++ b/scripts/SceneCardVideoPlayer/pwPlayer.js @@ -12,11 +12,12 @@ function log(str){ } const pwPlayer_settings = { - "Mode": "local", - // Path fixes for different OS + // most should be using remote playing mode, which plays the stream. + "Mode": "remote", + // Path fixes for different OS. For local only. "Windows":{ - // Not used. - "urlScheme": "file:///", + // Use vlc to handle local files. + "urlScheme": "vlc://", // double backsplashes need 4 backslashes. "replacePath": ["\\\\", "/"], }, @@ -183,27 +184,30 @@ const pwPlayer_addButton = () => { .replace(pwPlayer_settings[pwPlayer_OS].replacePath[0], ""); switch (pwPlayer_OS){ case "Mac OS": - // For iina player. + // Sample local handling for iina player. + // if you don't have iina player, use "remote" mode instead. if(debug)alert("you just click play in MacOS"); if (pwPlayer_settings.Mode == "local"){ href = pwPlayer_settings.MacOS.urlScheme + - pwPlayer_settings.MacOS.replacePath[1] + + pwPlayer_settings.MacOS.replacePath[1] + encodeURIComponent(filePath); - }else{ - href = streamLink; + window.open(href); + }else{ // "remote" + playVideoInBrowser(streamLink); } - playVideoInBrowser(streamLink); break; case "iOS": + // I don't know how to do this, so play in browser. if(debug)alert("you just click play in iOS"); playVideoInBrowser(streamLink); break; case "Android": + // Use android's intent to open the stream. if(debug)alert("you just click play in Android"); intent = new Intent(android.content.Intent.ACTION_VIEW); if (pwPlayer_settings.Mode == "local"){ uriData = Uri.parse( pwPlayer_settings.Android.urlScheme + filePath); - }else{ + }else{ // remote uriData = Uri.parse(streamLink); } intent.setDataAndType(uriData, "video/*"); @@ -211,12 +215,20 @@ const pwPlayer_addButton = () => { break; case "Windows": if(debug)alert("you just click play in Windows"); - log("streamLink:" + streamLink); - playVideoInBrowser(streamLink); + if (pwPlayer_settings.Mode == "local"){ + settings = pwPlayer_settings.Windows; + href = settings.urlScheme + + encodeURIComponent(filePath) + .replace(settings.replacePath[0],settings.replacePath[1]); + window.open(href); + }else{ // remote mode + log("streamLink:" + streamLink); + playVideoInBrowser(streamLink); + } break; default: if(debug)alert("You just click play in an unknow OS."); - + playVideoInBrowser(streamLink); } }); From 8347c19f8a8a582ff2605174161e943b0637ea44 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Tue, 10 Jan 2023 00:15:17 -0500 Subject: [PATCH 06/14] Update pwPlayer.js --- scripts/SceneCardVideoPlayer/pwPlayer.js | 72 ++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/scripts/SceneCardVideoPlayer/pwPlayer.js b/scripts/SceneCardVideoPlayer/pwPlayer.js index a44d9f4d..4323f7a9 100644 --- a/scripts/SceneCardVideoPlayer/pwPlayer.js +++ b/scripts/SceneCardVideoPlayer/pwPlayer.js @@ -86,6 +86,38 @@ document.head.appendChild(pwPlayer_style); // api +const pwPlayer_getSceneDetails = async href => { + const regex = /\/scenes\/(\d+)\?/, + sceneId = regex.exec(href)[1], + graphQl = ` + { + findScene(id:${sceneId}){ + files{ + path, + size, + format, + width, + height, + duration, + video_codec, + audio_codec, + frame_rate, + + }, + date + } + } + `, + response = await fetch("/graphql", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ query: graphQl }) + }); + return response.json(); +}; + const pwPlayer_getSceneInfo = async href => { const regex = /\/scenes\/(\d+)\?/, sceneId = regex.exec(href)[1], @@ -100,6 +132,7 @@ const pwPlayer_getSceneInfo = async href => { return response.json(); }; + function pwPlayer_getOS() { var userAgent = window.navigator.userAgent, platform = window.navigator?.userAgentData?.platform, @@ -238,12 +271,21 @@ const pwPlayer_addButton = () => { button.onmouseover = () => { if (button.title.length == 0) { - pwPlayer_getSceneInfo(scene_url.href) + pwPlayer_getSceneDetails(scene_url.href) .then((result) => { // console.log("result: " + JSON.stringify(result)); - const filePath = result.data.findScene.files[0].path - .replace(pwPlayer_settings[pwPlayer_OS].replacePath[0], ""); - button.title = filePath; + data = result.data.findScene; + sceneFile = data.files[0]; + log("before title phase.") + title =`Path: ${ TrunStr(sceneFile.path,30)} +Size: ${niceBytes(sceneFile.size)} +Dimensions: ${sceneFile.width}x${sceneFile.height} +Duration: ${toHMS(sceneFile.duration)} +Codecs: ${sceneFile.video_codec}, ${sceneFile.audio_codec} +Frame Rate: ${sceneFile.frame_rate} +${data.date?"Date: "+data.date : ""}`; + log("result:" + title); + button.title = title; }); } }; @@ -251,6 +293,28 @@ const pwPlayer_addButton = () => { } }; +function TrunStr(s,n){ + if (s.length <= n) return s; + str = s.substr(0,n) + for (i=n;i('00'+n).slice(-2); + return f(s/3600)+':'+g(f(s/60)%60)+':'+g(s%60); +} + +function niceBytes(x){ + let units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + let l = 0, n = parseInt(x, 10) || 0; + while(n >= 1024 && ++l){ n = n/1024; } + return(n.toFixed(n < 10 && l > 0 ? 1 : 0) + ' ' + units[l]); +} + function playVideoInBrowser(streamLink){ var pwPlayer_video_div = document.createElement("div"); // log("video_div instance of node:" + (video_div instanceof Node)); From ec4f51d2079e648f2dde1c03491457b32e9bb80f Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Tue, 10 Jan 2023 00:18:08 -0500 Subject: [PATCH 07/14] Update README.MD --- scripts/SceneCardVideoPlayer/README.MD | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index ce4d0f76..4dd3ee0f 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -11,3 +11,6 @@ You click on the video, then it will disappear. You are back to the scene list. Then refresh the browser. * Well, it's supposed to be this simple. Don't know why Stash guys make it so complicated.
So, enjoy play with it. In the future I will try to make it work with DeoVr. + +### Update Log: + * 1/10/2023 Show a lot more information about the file when the mouse hovers over Play button. From 34ebe3ca7db0cafb731642f3273a1a9b5cf5f644 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Tue, 10 Jan 2023 12:20:05 -0500 Subject: [PATCH 08/14] minor update --- scripts/SceneCardVideoPlayer/README.MD | 5 +++++ scripts/SceneCardVideoPlayer/pwPlayer.js | 27 ++++++++++++------------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index ce4d0f76..95a1f2aa 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -11,3 +11,8 @@ You click on the video, then it will disappear. You are back to the scene list. Then refresh the browser. * Well, it's supposed to be this simple. Don't know why Stash guys make it so complicated.
So, enjoy play with it. In the future I will try to make it work with DeoVr. + +### Updates +#### 1/10/2023 +* Improve the "wait for element" to preview video only. +* Now when play, the top nav bar will be hidden as well. \ No newline at end of file diff --git a/scripts/SceneCardVideoPlayer/pwPlayer.js b/scripts/SceneCardVideoPlayer/pwPlayer.js index 4323f7a9..e15bf19e 100644 --- a/scripts/SceneCardVideoPlayer/pwPlayer.js +++ b/scripts/SceneCardVideoPlayer/pwPlayer.js @@ -3,7 +3,7 @@ // Allow you to easily play those video files. // To use it, just copy and paste the code into Stash->Settings->Interface->Custome Javascript. // Then refresh the browser. -// This is only version 1.0 +// This is only version 1.1 // settings const debug = false; @@ -39,6 +39,7 @@ const pwPlayer_settings = { "MacOS":{ // For local iina player. "urlScheme": "iina://weblink?url=file://", + // Or VLC: "urlScheme": "vlc-x-callback://x-callback-url/stream?url=file://" "replacePath": ["", ""], } }; @@ -74,7 +75,7 @@ pwPlayer_style.innerHTML = ` left: 0px; width: 100%; height: 100%; - z-index: 99; + z-index: 1040; } } `; @@ -156,6 +157,8 @@ function pwPlayer_getOS() { return os; } +const pwPlayer_config = { subtree: true, childList: true }; +const pwPlayer_previewElm = "video.scene-card-preview-video"; // promise const pwPlayer_waitForElm = selector => { return new Promise(resolve => { @@ -168,15 +171,12 @@ const pwPlayer_waitForElm = selector => { observer.disconnect(); } }); - observer.observe(document.body, { - childList: true, - subtree: true - }); + observer.observe(document.body, pwPlayer_config); }); }; // initial -pwPlayer_waitForElm("video").then(() => { +pwPlayer_waitForElm(pwPlayer_previewElm).then(() => { pwPlayer_addButton(); }); @@ -185,13 +185,13 @@ let previousUrl = ""; const observer = new MutationObserver(function (mutations) { if (window.location.href !== previousUrl) { previousUrl = window.location.href; - pwPlayer_waitForElm("video").then(() => { + pwPlayer_waitForElm(pwPlayer_previewElm).then(() => { pwPlayer_addButton(); }); } }); -const config = { subtree: true, childList: true }; -observer.observe(document, config); + +observer.observe(document, pwPlayer_config); // main const pwPlayer_addButton = () => { @@ -277,7 +277,7 @@ const pwPlayer_addButton = () => { data = result.data.findScene; sceneFile = data.files[0]; log("before title phase.") - title =`Path: ${ TrunStr(sceneFile.path,30)} + title =`Path: ${ WrapStr(sceneFile.path,30)} Size: ${niceBytes(sceneFile.size)} Dimensions: ${sceneFile.width}x${sceneFile.height} Duration: ${toHMS(sceneFile.duration)} @@ -293,7 +293,8 @@ ${data.date?"Date: "+data.date : ""}`; } }; -function TrunStr(s,n){ +function WrapStr(s,n){ + // if (s.length <= n) return s; str = s.substr(0,n) for (i=n;i Date: Wed, 11 Jan 2023 01:56:21 -0500 Subject: [PATCH 09/14] v1.2 Add "browser" mode or "player" mode --- scripts/SceneCardVideoPlayer/pwPlayer.js | 220 ++++++++++++++--------- 1 file changed, 132 insertions(+), 88 deletions(-) diff --git a/scripts/SceneCardVideoPlayer/pwPlayer.js b/scripts/SceneCardVideoPlayer/pwPlayer.js index e15bf19e..5ce82342 100644 --- a/scripts/SceneCardVideoPlayer/pwPlayer.js +++ b/scripts/SceneCardVideoPlayer/pwPlayer.js @@ -1,19 +1,32 @@ -// Inspired by clangmoyai's IINA player script in github ! -// This script will add a "Play" button in each scene card. -// Allow you to easily play those video files. -// To use it, just copy and paste the code into Stash->Settings->Interface->Custome Javascript. -// Then refresh the browser. -// This is only version 1.1 +/* Inspired by clangmoyai's IINA player script in github ! + This script will add a "Play" button in each scene card. + Allow you to easily play those video files. + To use it, just copy and paste the code into Stash->Settings->Interface->Custome Javascript. + Then refresh the browser. + This is only version 1.2 + + Player mode should be either "browser" or "player" + In browser mode, the video is played within a

+Finally, if you use "player" mode, you will be happy to use Quest 2 browser to watch Stash, as I am very happy now. From b84f77c6127aed26f393688c0920c21a4d976d80 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Wed, 11 Jan 2023 02:01:13 -0500 Subject: [PATCH 11/14] Update README.MD --- scripts/SceneCardVideoPlayer/README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index 9e64a389..5cdc17ba 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -20,6 +20,6 @@ So, enjoy play with it. In the future I will try to make it work with DeoVr. * Now when play, the top nav bar will be hidden as well. #### 1/11/2023 * Add "browser" mode and "player" mode. Player mode is useful for using device's internal players, while browser mode works most of the time. -* Add Oculus browser detection. +* Add Oculus browser detection and special handling of it.

Finally, if you use "player" mode, you will be happy to use Quest 2 browser to watch Stash, as I am very happy now. From 82fb1d3513effa915ba1044097fe16fb8e589aab Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Wed, 11 Jan 2023 16:20:49 -0500 Subject: [PATCH 12/14] Update README.MD --- scripts/SceneCardVideoPlayer/README.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index 5cdc17ba..30ef4ec2 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -1,5 +1,9 @@ # Scene Card Video Player +Sorry but this is not the best place for the script. New and updated script will go to: +https://github.com/philpw99/StashCustomJavascripts +I think a separate repo is the best for this script and other scripts I might make in the future.

+

Inspired by clangmoyai's IINA plugin. I added more cross platform support.
From 6cdd67be7dda2c34630ab8213ca543e6d3e7f00a Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Wed, 11 Jan 2023 16:21:10 -0500 Subject: [PATCH 13/14] Update README.MD --- scripts/SceneCardVideoPlayer/README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index 30ef4ec2..357956d9 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -1,6 +1,6 @@ # Scene Card Video Player Sorry but this is not the best place for the script. New and updated script will go to: -https://github.com/philpw99/StashCustomJavascripts +https://github.com/philpw99/StashCustomJavascripts
I think a separate repo is the best for this script and other scripts I might make in the future.

From ad2ab62f6dbd5ba3d35fdff134f4d3edfa575a54 Mon Sep 17 00:00:00 2001 From: Philip Wang Date: Wed, 11 Jan 2023 16:21:22 -0500 Subject: [PATCH 14/14] Update README.MD --- scripts/SceneCardVideoPlayer/README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/SceneCardVideoPlayer/README.MD b/scripts/SceneCardVideoPlayer/README.MD index 357956d9..acde1941 100644 --- a/scripts/SceneCardVideoPlayer/README.MD +++ b/scripts/SceneCardVideoPlayer/README.MD @@ -1,5 +1,5 @@ # Scene Card Video Player -Sorry but this is not the best place for the script. New and updated script will go to: +Sorry but this is not the best place for the script. New and updated script will go to:
https://github.com/philpw99/StashCustomJavascripts
I think a separate repo is the best for this script and other scripts I might make in the future.