get subtitle track from stream

This commit is contained in:
Samuel Newman
2024-08-02 19:04:20 +02:00
parent 09a3d61e23
commit a83b563903
3 changed files with 24 additions and 4 deletions
@@ -86,6 +86,7 @@ export function VideoPlayer({
const containerRef = useRef<HTMLDivElement>(null) const containerRef = useRef<HTMLDivElement>(null)
const ref = useRef<HTMLVideoElement>(null) const ref = useRef<HTMLVideoElement>(null)
const [focused, setFocused] = useState(false) const [focused, setFocused] = useState(false)
const [hasSubtitleTrack, setHasSubtitleTrack] = useState(false)
useEffect(() => { useEffect(() => {
if ( if (
@@ -97,6 +98,12 @@ export function VideoPlayer({
// initial value, later on it's managed by Controls // initial value, later on it's managed by Controls
hls.autoLevelCapping = 0 hls.autoLevelCapping = 0
hls.on(Hls.Events.SUBTITLE_TRACKS_UPDATED, (event, data) => {
if (data.subtitleTracks.length > 0) {
setHasSubtitleTrack(true)
}
})
return () => { return () => {
hls.detachMedia() hls.detachMedia()
} }
@@ -151,6 +158,7 @@ export function VideoPlayer({
setFocused={setFocused} setFocused={setFocused}
onScreen={onScreen} onScreen={onScreen}
enterFullscreen={enterFullscreen} enterFullscreen={enterFullscreen}
hasSubtitleTrack={hasSubtitleTrack}
/> />
</div> </div>
</View> </View>
@@ -10,6 +10,7 @@ export function Controls({}: {
setFocused: (focused: boolean) => void setFocused: (focused: boolean) => void
onScreen: boolean onScreen: boolean
enterFullscreen: () => void enterFullscreen: () => void
hasSubtitleTrack: boolean
}): React.ReactElement { }): React.ReactElement {
throw new Error('Web-only component') throw new Error('Web-only component')
} }
@@ -37,6 +37,7 @@ export function Controls({
setFocused, setFocused,
onScreen, onScreen,
enterFullscreen, enterFullscreen,
hasSubtitleTrack,
}: { }: {
videoRef: React.RefObject<HTMLVideoElement> videoRef: React.RefObject<HTMLVideoElement>
hls: Hls hls: Hls
@@ -46,6 +47,7 @@ export function Controls({
setFocused: (focused: boolean) => void setFocused: (focused: boolean) => void
onScreen: boolean onScreen: boolean
enterFullscreen: () => void enterFullscreen: () => void
hasSubtitleTrack: boolean
}) { }) {
const { const {
play, play,
@@ -58,6 +60,7 @@ export function Controls({
duration, duration,
buffering, buffering,
error, error,
canPlay,
} = useVideoUtils(videoRef) } = useVideoUtils(videoRef)
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
@@ -117,6 +120,14 @@ export function Controls({
} }
}, [hls, focused]) }, [hls, focused])
useEffect(() => {
if (hasSubtitleTrack && subtitlesEnabled && canPlay) {
hls.subtitleTrack = 0
} else {
hls.subtitleTrack = -1
}
}, [hasSubtitleTrack, subtitlesEnabled, hls, canPlay])
// clicking on any button should focus the player, if it's not already focused // clicking on any button should focus the player, if it's not already focused
const drawFocus = useCallback(() => { const drawFocus = useCallback(() => {
if (!active) { if (!active) {
@@ -160,9 +171,6 @@ export function Controls({
const showControls = const showControls =
(focused && !playing) || (interactingViaKeypress ? hasFocus : hovered) (focused && !playing) || (interactingViaKeypress ? hasFocus : hovered)
// TODO: get from embed
const videoHasSubtitles = true
return ( return (
<div <div
style={{ style={{
@@ -223,7 +231,7 @@ export function Controls({
<Text style={{color: t.palette.white}}> <Text style={{color: t.palette.white}}>
{formatTime(currentTime)} / {formatTime(duration)} {formatTime(currentTime)} / {formatTime(duration)}
</Text> </Text>
{videoHasSubtitles && ( {hasSubtitleTrack && (
<Button <Button
label={_( label={_(
subtitlesEnabled ? msg`Disable subtitles` : msg`Enable subtitles`, subtitlesEnabled ? msg`Disable subtitles` : msg`Enable subtitles`,
@@ -334,6 +342,7 @@ function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
const [duration, setDuration] = useState(0) const [duration, setDuration] = useState(0)
const [buffering, setBuffering] = useState(false) const [buffering, setBuffering] = useState(false)
const [error, setError] = useState(false) const [error, setError] = useState(false)
const [canPlay, setCanPlay] = useState(false)
const playWhenReadyRef = useRef(false) const playWhenReadyRef = useRef(false)
useEffect(() => { useEffect(() => {
@@ -379,6 +388,7 @@ function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
const handleCanPlay = () => { const handleCanPlay = () => {
setBuffering(false) setBuffering(false)
setCanPlay(true)
if (!current) return if (!current) return
if (playWhenReadyRef.current) { if (playWhenReadyRef.current) {
@@ -520,6 +530,7 @@ function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
toggleMute, toggleMute,
buffering, buffering,
error, error,
canPlay,
} }
} }