Chromcast support (#3907)

This commit is contained in:
CJ 2023-07-13 22:04:57 -05:00 committed by GitHub
parent 5580525c2d
commit 29636d500a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 4 deletions

View file

@ -2,7 +2,7 @@
# Build Frontend
FROM node:alpine as frontend
RUN apk add --no-cache make
RUN apk add --no-cache make git
## cache node_modules separately
COPY ./ui/v2.5/package.json ./ui/v2.5/yarn.lock /stash/ui/v2.5/
WORKDIR /stash

View file

@ -2,7 +2,7 @@
# Build Frontend
FROM node:alpine as frontend
RUN apk add --no-cache make
RUN apk add --no-cache make git
## cache node_modules separately
COPY ./ui/v2.5/package.json ./ui/v2.5/yarn.lock /stash/ui/v2.5/
WORKDIR /stash

View file

@ -432,7 +432,7 @@ func setPageSecurityHeaders(w http.ResponseWriter, r *http.Request) {
defaultSrc := "data: 'self' 'unsafe-inline'"
connectSrc := "data: 'self'"
imageSrc := "data: *"
scriptSrc := "'self' 'unsafe-inline' 'unsafe-eval'"
scriptSrc := "'self' http://www.gstatic.com https://www.gstatic.com 'unsafe-inline' 'unsafe-eval'"
styleSrc := "'self' 'unsafe-inline'"
mediaSrc := "blob: 'self'"

View file

@ -29,6 +29,8 @@
"@fortawesome/free-regular-svg-icons": "^6.3.0",
"@fortawesome/free-solid-svg-icons": "^6.3.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@silvermine/videojs-airplay": "^1.2.0",
"@silvermine/videojs-chromecast": "^1.4.1",
"apollo-upload-client": "^17.0.0",
"axios": "^1.3.3",
"base64-blob": "^1.4.1",

View file

@ -8,6 +8,7 @@ import React, {
useState,
} from "react";
import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from "video.js";
import useScript from "src/hooks/useScript";
import "videojs-contrib-dash";
import "videojs-mobile-ui";
import "videojs-seek-buttons";
@ -22,6 +23,12 @@ import "./big-buttons";
import "./track-activity";
import "./vrmode";
import cx from "classnames";
// @ts-ignore
import airplay from "@silvermine/videojs-airplay";
// @ts-ignore
import chromecast from "@silvermine/videojs-chromecast";
airplay(videojs);
chromecast(videojs);
import {
useSceneSaveActivity,
useSceneIncrementPlayCount,
@ -217,11 +224,15 @@ export const ScenePlayer: React.FC<IScenePlayerProps> = ({
const started = useRef(false);
const auto = useRef(false);
const interactiveReady = useRef(false);
const minimumPlayPercent = uiConfig?.minimumPlayPercent ?? 0;
const trackActivity = uiConfig?.trackActivity ?? false;
const vrTag = uiConfig?.vrTag ?? undefined;
useScript(
"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1",
uiConfig?.enableChromecast
);
const file = useMemo(
() => (scene.files.length > 0 ? scene.files[0] : undefined),
[scene]
@ -306,12 +317,15 @@ export const ScenePlayer: React.FC<IScenePlayerProps> = ({
inactivityTimeout: 2000,
preload: "none",
playsinline: true,
techOrder: ["chromecast", "html5"],
userActions: {
hotkeys: function (this: VideoJsPlayer, event) {
handleHotkeys(this, event);
},
},
plugins: {
airPlay: {},
chromecast: {},
vttThumbnails: {
showTimestamp: true,
},

View file

@ -1,6 +1,8 @@
@import "video.js/dist/video-js.css";
@import "videojs-mobile-ui/dist/videojs-mobile-ui.css";
@import "videojs-seek-buttons/dist/videojs-seek-buttons.css";
@import "@silvermine/videojs-chromecast/dist/silvermine-videojs-chromecast.css";
@import "@silvermine/videojs-airplay/dist/silvermine-videojs-airplay.css";
$scrubberHeight: 120px;
$menuHeight: 4rem;
@ -62,6 +64,12 @@ $sceneTabWidth: 450px;
}
}
.vjs-airplay-button .vjs-icon-placeholder,
.vjs-chromecast-button .vjs-icon-placeholder {
height: 1.6em;
width: 1.6em;
}
.vjs-touch-overlay .vjs-play-control {
z-index: 1;
}
@ -308,6 +316,12 @@ $sceneTabWidth: 450px;
font-size: 1.5em;
line-height: 2;
}
.vjs-airplay-button .vjs-icon-placeholder,
.vjs-chromecast-button .vjs-icon-placeholder {
height: 1.4em;
width: 1.4em;
}
}
.vjs-menu-button-popup .vjs-menu {

View file

@ -272,6 +272,12 @@ export const SettingsInterfacePanel: React.FC = () => {
</SettingSection>
<SettingSection headingID="config.ui.scene_player.heading">
<BooleanSetting
id="enable-chromecast"
headingID="config.ui.scene_player.options.enable_chromecast"
checked={ui.enableChromecast ?? undefined}
onChange={(v) => saveUI({ enableChromecast: v })}
/>
<BooleanSetting
id="show-scrubber"
headingID="config.ui.scene_player.options.show_scrubber"

View file

@ -43,6 +43,8 @@ export interface IUIConfig {
ratingSystemOptions?: RatingSystemOptions;
// if true the chromecast option will enabled
enableChromecast?: boolean;
// if true continue scene will always play from the beginning
alwaysStartFromBeginning?: boolean;
// if true enable activity tracking

View file

@ -0,0 +1,22 @@
import { useEffect } from "react";
const useScript = (url: string, condition?: boolean) => {
useEffect(() => {
const script = document.createElement("script");
script.src = url;
script.async = true;
if (condition) {
document.head.appendChild(script);
}
return () => {
if (condition) {
document.head.removeChild(script);
}
};
}, [url, condition]);
};
export default useScript;

View file

@ -666,6 +666,7 @@
"description": "Play next scene in queue when video finishes",
"heading": "Continue playlist by default"
},
"enable_chromecast": "Enable Chromecast",
"show_scrubber": "Show Scrubber",
"track_activity": "Track Activity",
"vr_tag": {

View file

@ -2161,6 +2161,18 @@
dependencies:
dequal "^2.0.2"
"@silvermine/videojs-airplay@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@silvermine/videojs-airplay/-/videojs-airplay-1.2.0.tgz#3ca6464c8e94c97bb9f35c2926f59a5aa662cebd"
integrity sha512-4KzHoM/wJaq3au8IBLxnz8+btAB/M/2AdMoAoOdZRpp9DGG8SGU/UPw2w+CRMknvfbGtvlhlNrNiiXVWA6Cn0A==
"@silvermine/videojs-chromecast@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@silvermine/videojs-chromecast/-/videojs-chromecast-1.4.1.tgz#a5763eb85dfd4bc8f47a1b8b150d5dadbb8ea658"
integrity sha512-tXeikkWoNC3WIl2WSkIag1CLMbGsgn+26LM4LoB4qx0TQ8mkg7pgpldCTkvXxLVaDluQ/uEm2uxrgrMmjOc6sw==
dependencies:
webcomponents.js "git+https://git@github.com/webcomponents/webcomponentsjs.git#v0.7.24"
"@tootallnate/once@2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
@ -8143,6 +8155,10 @@ web-streams-polyfill@^3.2.1:
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
"webcomponents.js@git+https://git@github.com/webcomponents/webcomponentsjs.git#v0.7.24":
version "0.7.24"
resolved "git+https://git@github.com/webcomponents/webcomponentsjs.git#8a2e40557b177e2cca0def2553f84c8269c8f93e"
webcrypto-core@^1.7.4:
version "1.7.6"
resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.6.tgz#e32c4a12a13de4251f8f9ef336a6cba7cdec9b55"