mirror of
https://github.com/movie-web/movie-web.git
synced 2025-01-04 07:15:59 +00:00
track element support
This commit is contained in:
parent
454fa1279b
commit
596e97e1ba
|
@ -1,6 +1,10 @@
|
||||||
import { useEffect, 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 {
|
||||||
|
convertSubtitlesToVtt,
|
||||||
|
vttToDataurl,
|
||||||
|
} 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";
|
||||||
|
|
||||||
|
@ -39,6 +43,14 @@ export function useShouldShowVideoElement() {
|
||||||
function VideoElement() {
|
function VideoElement() {
|
||||||
const videoEl = useRef<HTMLVideoElement>(null);
|
const videoEl = useRef<HTMLVideoElement>(null);
|
||||||
const display = usePlayerStore((s) => s.display);
|
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(
|
||||||
|
() => (srtData ? vttToDataurl(convertSubtitlesToVtt(srtData)) : null),
|
||||||
|
[srtData]
|
||||||
|
);
|
||||||
|
|
||||||
// report video element to display interface
|
// report video element to display interface
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -47,13 +59,27 @@ function VideoElement() {
|
||||||
}
|
}
|
||||||
}, [display, videoEl]);
|
}, [display, videoEl]);
|
||||||
|
|
||||||
|
let subtitleTrack: ReactNode = null;
|
||||||
|
if (captionAsTrack && trackData && language)
|
||||||
|
subtitleTrack = (
|
||||||
|
<track
|
||||||
|
label="Subtitles"
|
||||||
|
kind="subtitles"
|
||||||
|
srcLang={language}
|
||||||
|
src={trackData}
|
||||||
|
default
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<video
|
<video
|
||||||
className="absolute inset-0 w-full h-screen bg-black"
|
className="absolute inset-0 w-full h-screen bg-black"
|
||||||
autoPlay
|
autoPlay
|
||||||
playsInline
|
playsInline
|
||||||
ref={videoEl}
|
ref={videoEl}
|
||||||
/>
|
>
|
||||||
|
{subtitleTrack}
|
||||||
|
</video>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ export function makeQueId(index: number, start: number, end: number): string {
|
||||||
return `${index}-${start}-${end}`;
|
return `${index}-${start}-${end}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseSubtitles(text: string): CaptionCueType[] {
|
export function convertSubtitlesToVtt(text: string): string {
|
||||||
const textTrimmed = text.trim();
|
const textTrimmed = text.trim();
|
||||||
if (textTrimmed === "") {
|
if (textTrimmed === "") {
|
||||||
throw new Error("Given text is empty");
|
throw new Error("Given text is empty");
|
||||||
|
@ -32,5 +32,16 @@ export function parseSubtitles(text: string): CaptionCueType[] {
|
||||||
if (detect(vtt) === "") {
|
if (detect(vtt) === "") {
|
||||||
throw new Error("Invalid subtitle format");
|
throw new Error("Invalid subtitle format");
|
||||||
}
|
}
|
||||||
|
return vtt;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseSubtitles(text: string): CaptionCueType[] {
|
||||||
|
const vtt = convertSubtitlesToVtt(text);
|
||||||
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
|
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function vttToDataurl(vtt: string): string {
|
||||||
|
const bytes = new TextEncoder().encode(vtt);
|
||||||
|
const encoded = btoa(String.fromCodePoint(...bytes));
|
||||||
|
return `data:text/vtt;base64,${encoded}`;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue