1
0
Fork 0
mirror of https://github.com/sussy-code/smov.git synced 2024-12-29 16:07:40 +01:00

Improved Chromecast integration

This commit is contained in:
Felix Boehme 2023-08-31 18:32:46 +02:00
parent 4ffbe45ab1
commit 05671db391
No known key found for this signature in database
GPG key ID: 7EB0603E4E9642EA
3 changed files with 66 additions and 5 deletions

View file

@ -5,6 +5,7 @@ import { ContentCaption } from "subsrt-ts/dist/types/handler";
import { parseSubtitles, sanitize } from "@/backend/helpers/captions"; import { parseSubtitles, sanitize } from "@/backend/helpers/captions";
import { Transition } from "@/components/Transition"; import { Transition } from "@/components/Transition";
import { useSettings } from "@/state/settings"; import { useSettings } from "@/state/settings";
import { getPlayerState } from "@/video/state/cache";
import { useVideoPlayerDescriptor } from "../../state/hooks"; import { useVideoPlayerDescriptor } from "../../state/hooks";
import { useProgress } from "../../state/logic/progress"; import { useProgress } from "../../state/logic/progress";
@ -52,6 +53,7 @@ export function CaptionRendererAction({
const videoTime = useProgress(descriptor).time; const videoTime = useProgress(descriptor).time;
const { captionSettings, setCaptionDelay } = useSettings(); const { captionSettings, setCaptionDelay } = useSettings();
const captions = useRef<ContentCaption[]>([]); const captions = useRef<ContentCaption[]>([]);
const casting = getPlayerState(descriptor).casting.isCasting;
const captionSetRef = useRef<(delay: number) => void>(setCaptionDelay); const captionSetRef = useRef<(delay: number) => void>(setCaptionDelay);
useEffect(() => { useEffect(() => {
@ -96,6 +98,7 @@ export function CaptionRendererAction({
}, },
[] []
); );
if (casting) return null;
if (!captions.current.length) return null; if (!captions.current.length) return null;
const visibileCaptions = captions.current.filter(({ start, end }) => const visibileCaptions = captions.current.filter(({ start, end }) =>
isVisible(start, end, captionSettings.delay, videoTime) isVisible(start, end, captionSettings.delay, videoTime)

View file

@ -22,6 +22,7 @@ export function ProgressAction() {
const controlRef = useRef<typeof controls>(controls); const controlRef = useRef<typeof controls>(controls);
const [hoverPosition, setHoverPosition] = useState<number>(0); const [hoverPosition, setHoverPosition] = useState<number>(0);
const [isThumbnailVisible, setIsThumbnailVisible] = useState<boolean>(false); const [isThumbnailVisible, setIsThumbnailVisible] = useState<boolean>(false);
const casting = getPlayerState(descriptor).casting;
const onMouseOver = useCallback((e: MouseActivity) => { const onMouseOver = useCallback((e: MouseActivity) => {
setHoverPosition(e.clientX); setHoverPosition(e.clientX);
setIsThumbnailVisible(true); setIsThumbnailVisible(true);
@ -106,7 +107,7 @@ export function ProgressAction() {
</div> </div>
</div> </div>
</div> </div>
{isThumbnailVisible ? ( {isThumbnailVisible && !casting ? (
<ThumbnailAction <ThumbnailAction
parentRef={ref} parentRef={ref}
videoTime={videoTime} videoTime={videoTime}

View file

@ -16,6 +16,7 @@ import { updateSource } from "@/video/state/logic/source";
import { resetStateForSource } from "@/video/state/providers/helpers"; import { resetStateForSource } from "@/video/state/providers/helpers";
import { VideoPlayerStateProvider } from "./providerTypes"; import { VideoPlayerStateProvider } from "./providerTypes";
import { SettingsStore } from "../../../state/settings/store";
import { getPlayerState } from "../cache"; import { getPlayerState } from "../cache";
import { updateMediaPlaying } from "../logic/mediaplaying"; import { updateMediaPlaying } from "../logic/mediaplaying";
import { updateProgress } from "../logic/progress"; import { updateProgress } from "../logic/progress";
@ -140,18 +141,53 @@ export function createCastingStateProvider(
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.metadata = movieMeta; mediaInfo.metadata = movieMeta;
const request = new chrome.cast.media.LoadRequest(mediaInfo); const loadRequest = new chrome.cast.media.LoadRequest(mediaInfo);
request.autoplay = true; loadRequest.autoplay = true;
// start where video left off before cast
loadRequest.currentTime = state.progress.time;
let captions = null;
if (state.source?.caption?.url) {
const subtitles = new chrome.cast.media.Track(
1,
chrome.cast.media.TrackType.TEXT
);
subtitles.trackContentId =
"https://cc.2cdns.com/a8/d8/a8d8c98288d4db1d6404e54c644091f5/eng-9.vtt";
subtitles.trackContentType = "text/vtt";
subtitles.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
subtitles.name = "Subtitles";
subtitles.language = "en";
const tracks = [subtitles];
mediaInfo.tracks = tracks;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.textTrackStyle.backgroundColor =
SettingsStore.get().captionSettings.style.backgroundColor;
mediaInfo.textTrackStyle.foregroundColor =
SettingsStore.get().captionSettings.style.color.concat("ff"); // needs to be in RGBA format
mediaInfo.textTrackStyle.fontScale =
SettingsStore.get().captionSettings.style.fontSize / 40; // scale factor way smaller than fortSize
loadRequest.activeTrackIds = [1];
captions = {
url: state.source.caption.url,
id: state.source.caption.id,
};
}
const session = ins?.getCurrentSession(); const session = ins?.getCurrentSession();
session?.loadMedia(request); session?.loadMedia(loadRequest);
// update state // update state
state.source = { state.source = {
quality: source.quality, quality: source.quality,
type: source.type, type: source.type,
url: source.source, url: source.source,
caption: null, caption: captions,
embedId: source.embedId, embedId: source.embedId,
providerId: source.providerId, providerId: source.providerId,
thumbnails: [], thumbnails: [],
@ -166,6 +202,16 @@ export function createCastingStateProvider(
id, id,
url, url,
}; };
// media has to be loaded again to use the new captions
this.setSource({
quality: state.source.quality,
source: state.source.url,
type: state.source.type,
embedId: state.source.embedId,
providerId: state.source.providerId,
});
updateSource(descriptor, state); updateSource(descriptor, state);
} }
}, },
@ -173,6 +219,17 @@ export function createCastingStateProvider(
if (state.source) { if (state.source) {
revokeCaptionBlob(state.source.caption?.url); revokeCaptionBlob(state.source.caption?.url);
state.source.caption = null; state.source.caption = null;
const tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(
[]
);
const session = ins?.getCurrentSession();
session?.getMediaSession()?.editTracksInfo(
tracksInfoRequest,
() => console.log("Captions cleared"),
(error) => console.log(error)
);
updateSource(descriptor, state); updateSource(descriptor, state);
} }
}, },