mirror of
https://github.com/movie-web/movie-web.git
synced 2024-11-11 00:35:07 +01:00
Merge pull request #419 from FelixBoehme/chromecast
Improved Chromecast integration
This commit is contained in:
commit
c49ea0170e
@ -2,6 +2,7 @@ import { useCallback, useEffect, useRef } from "react";
|
|||||||
import { useAsync } from "react-use";
|
import { useAsync } from "react-use";
|
||||||
import { ContentCaption } from "subsrt-ts/dist/types/handler";
|
import { ContentCaption } from "subsrt-ts/dist/types/handler";
|
||||||
|
|
||||||
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
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";
|
||||||
@ -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 isCasting = 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 (isCasting) 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)
|
||||||
|
@ -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 isCasting = getPlayerState(descriptor).casting.isCasting;
|
||||||
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 && !isCasting ? (
|
||||||
<ThumbnailAction
|
<ThumbnailAction
|
||||||
parentRef={ref}
|
parentRef={ref}
|
||||||
videoTime={videoTime}
|
videoTime={videoTime}
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
} from "@/utils/detectFeatures";
|
} from "@/utils/detectFeatures";
|
||||||
|
|
||||||
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,68 @@ 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?.id) {
|
||||||
|
let captionIndex: number | undefined;
|
||||||
|
const linkedCaptions = state.meta?.captions;
|
||||||
|
const captionLangIso = state.source?.caption?.id.slice(7);
|
||||||
|
let trackContentId = "";
|
||||||
|
|
||||||
|
if (linkedCaptions) {
|
||||||
|
for (let index = 0; index < linkedCaptions.length; index += 1) {
|
||||||
|
if (captionLangIso === linkedCaptions[index].langIso) {
|
||||||
|
captionIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (captionIndex) {
|
||||||
|
trackContentId = linkedCaptions[captionIndex].url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const subtitles = new chrome.cast.media.Track(
|
||||||
|
1,
|
||||||
|
chrome.cast.media.TrackType.TEXT
|
||||||
|
);
|
||||||
|
subtitles.trackContentId = trackContentId;
|
||||||
|
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 +217,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 +234,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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user