mirror of
https://github.com/movie-web/movie-web.git
synced 2025-01-13 22:09:08 +01:00
Fix subtitles not showing up in safari, using a blob
This commit is contained in:
parent
adf5689c48
commit
2b240c8155
@ -1,7 +1,7 @@
|
||||
import { ReactNode, useEffect, useMemo, useRef } from "react";
|
||||
|
||||
import { makeVideoElementDisplayInterface } from "@/components/player/display/base";
|
||||
import { convertSubtitlesToDataurl } from "@/components/player/utils/captions";
|
||||
import { convertSubtitlesToObjectUrl } from "@/components/player/utils/captions";
|
||||
import { playerStatus } from "@/stores/player/slices/source";
|
||||
import { usePlayerStore } from "@/stores/player/store";
|
||||
|
||||
@ -37,16 +37,39 @@ export function useShouldShowVideoElement() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function useObjectUrl(cb: () => string | null, deps: any[]) {
|
||||
const lastObjectUrl = useRef<string | null>(null);
|
||||
const output = useMemo(() => {
|
||||
if (lastObjectUrl.current) URL.revokeObjectURL(lastObjectUrl.current);
|
||||
const data = cb();
|
||||
lastObjectUrl.current = data;
|
||||
return data;
|
||||
// deps are passed in, cb is known not to be changed
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, deps);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
// this is intentionally done only in cleanup
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
if (lastObjectUrl.current) URL.revokeObjectURL(lastObjectUrl.current);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function VideoElement() {
|
||||
const videoEl = useRef<HTMLVideoElement>(null);
|
||||
const trackEl = useRef<HTMLTrackElement>(null);
|
||||
const display = usePlayerStore((s) => s.display);
|
||||
const srtData = usePlayerStore((s) => s.caption.selected?.srtData);
|
||||
const captionAsTrack = usePlayerStore((s) => s.caption.asTrack);
|
||||
const language = usePlayerStore((s) => s.caption.selected?.language);
|
||||
|
||||
const trackData = useMemo(() => {
|
||||
return srtData ? convertSubtitlesToDataurl(srtData) : null;
|
||||
}, [srtData]);
|
||||
const trackObjectUrl = useObjectUrl(
|
||||
() => (srtData ? convertSubtitlesToObjectUrl(srtData) : null),
|
||||
[srtData]
|
||||
);
|
||||
|
||||
// report video element to display interface
|
||||
useEffect(() => {
|
||||
@ -55,14 +78,21 @@ function VideoElement() {
|
||||
}
|
||||
}, [display, videoEl]);
|
||||
|
||||
// select track as showing if it exists
|
||||
useEffect(() => {
|
||||
if (trackEl.current) {
|
||||
trackEl.current.track.mode = "showing";
|
||||
}
|
||||
}, [trackEl]);
|
||||
|
||||
let subtitleTrack: ReactNode = null;
|
||||
if (captionAsTrack && trackData && language)
|
||||
if (captionAsTrack && trackObjectUrl && language)
|
||||
subtitleTrack = (
|
||||
<track
|
||||
label="Subtitles"
|
||||
label="movie-web"
|
||||
kind="subtitles"
|
||||
srcLang={language}
|
||||
src={trackData}
|
||||
src={trackObjectUrl}
|
||||
default
|
||||
/>
|
||||
);
|
||||
|
@ -41,5 +41,13 @@ export function parseSubtitles(text: string): CaptionCueType[] {
|
||||
}
|
||||
|
||||
export function convertSubtitlesToDataurl(text: string): string {
|
||||
return `data:text/vtt;${convertSubtitlesToVtt(text)}`;
|
||||
return `data:text/vtt,${convertSubtitlesToVtt(text)}`;
|
||||
}
|
||||
|
||||
export function convertSubtitlesToObjectUrl(text: string): string {
|
||||
return URL.createObjectURL(
|
||||
new Blob([convertSubtitlesToVtt(text)], {
|
||||
type: "text/vtt",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user