mirror of
https://github.com/movie-web/movie-web.git
synced 2025-01-14 13:49:13 +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 { ReactNode, useEffect, useMemo, useRef } from "react";
|
||||||
|
|
||||||
import { makeVideoElementDisplayInterface } from "@/components/player/display/base";
|
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 { playerStatus } from "@/stores/player/slices/source";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
@ -37,16 +37,39 @@ export function useShouldShowVideoElement() {
|
|||||||
return true;
|
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() {
|
function VideoElement() {
|
||||||
const videoEl = useRef<HTMLVideoElement>(null);
|
const videoEl = useRef<HTMLVideoElement>(null);
|
||||||
|
const trackEl = useRef<HTMLTrackElement>(null);
|
||||||
const display = usePlayerStore((s) => s.display);
|
const display = usePlayerStore((s) => s.display);
|
||||||
const srtData = usePlayerStore((s) => s.caption.selected?.srtData);
|
const srtData = usePlayerStore((s) => s.caption.selected?.srtData);
|
||||||
const captionAsTrack = usePlayerStore((s) => s.caption.asTrack);
|
const captionAsTrack = usePlayerStore((s) => s.caption.asTrack);
|
||||||
const language = usePlayerStore((s) => s.caption.selected?.language);
|
const language = usePlayerStore((s) => s.caption.selected?.language);
|
||||||
|
const trackObjectUrl = useObjectUrl(
|
||||||
const trackData = useMemo(() => {
|
() => (srtData ? convertSubtitlesToObjectUrl(srtData) : null),
|
||||||
return srtData ? convertSubtitlesToDataurl(srtData) : null;
|
[srtData]
|
||||||
}, [srtData]);
|
);
|
||||||
|
|
||||||
// report video element to display interface
|
// report video element to display interface
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -55,14 +78,21 @@ function VideoElement() {
|
|||||||
}
|
}
|
||||||
}, [display, videoEl]);
|
}, [display, videoEl]);
|
||||||
|
|
||||||
|
// select track as showing if it exists
|
||||||
|
useEffect(() => {
|
||||||
|
if (trackEl.current) {
|
||||||
|
trackEl.current.track.mode = "showing";
|
||||||
|
}
|
||||||
|
}, [trackEl]);
|
||||||
|
|
||||||
let subtitleTrack: ReactNode = null;
|
let subtitleTrack: ReactNode = null;
|
||||||
if (captionAsTrack && trackData && language)
|
if (captionAsTrack && trackObjectUrl && language)
|
||||||
subtitleTrack = (
|
subtitleTrack = (
|
||||||
<track
|
<track
|
||||||
label="Subtitles"
|
label="movie-web"
|
||||||
kind="subtitles"
|
kind="subtitles"
|
||||||
srcLang={language}
|
srcLang={language}
|
||||||
src={trackData}
|
src={trackObjectUrl}
|
||||||
default
|
default
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -41,5 +41,13 @@ export function parseSubtitles(text: string): CaptionCueType[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function convertSubtitlesToDataurl(text: string): string {
|
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