Skip to content
Snippets Groups Projects
Verified Commit 48170b48 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Provide feedback for audio/sub selection

parent 8e662c85
Branches
No related tags found
No related merge requests found
......@@ -40,7 +40,7 @@ export function Player(
const position = usePosition(videoElement);
const duration = useDuration(videoElement);
const audioTracks = useAudioTracks(videoElement);
const [audioTracks, currentTrack, setCurrentTrack] = useAudioTracks(videoElement);
useDebugInfo("playerEl", videoElement);
useDebugInfo("previewTrackEl", previewTrack);
......@@ -87,6 +87,7 @@ export function Player(
<TtmlRenderer
className={classes.subtitleCanvas}
trackElement={subtitleTrack}
subtitle={subtitle}
duration={duration}
/>
</div>
......@@ -101,18 +102,28 @@ export function Player(
<strong>{track.lang}</strong>
&nbsp;{track.labels}
&nbsp;
<button onClick={() => videoElement?.setAudioTrack(track)}>Choose</button>
<button
disabled={currentTrack === track}
onClick={() => setCurrentTrack(track)}
>
Choose
</button>
</li>
))}
</ul>
<h3>Subtitles</h3>
<ul>
{content.subtitles.map(track => (
<li key={track.src}>
<strong>{track.language}</strong>
&nbsp;{track.specifier}
{[null, ...content.subtitles].map(track => (
<li key={track?.src || "none"}>
<strong>{track?.language || "none"}</strong>
&nbsp;{track?.specifier}
&nbsp;
<button onClick={() => setSubtitle(track)}>Choose</button>
<button
disabled={subtitle === track}
onClick={() => setSubtitle(track)}
>
Choose
</button>
</li>
))}
</ul>
......
import {useEffect, useState} from "react";
import TtmlHelper from "./TtmlHelper";
import {Subtitle} from "../../../api/models/Subtitle";
interface Props {
trackElement: HTMLTrackElement | null,
subtitle: Subtitle | null,
duration: number,
className?: string,
}
export function TtmlRenderer(
{trackElement, duration, className}: Props
{trackElement, subtitle, duration, className}: Props
) {
const [subtitleCanvas, setSubtitleCanvas] = useState<HTMLElement | null>(null);
useEffect(() => {
if (subtitleCanvas && trackElement) {
if (subtitleCanvas && trackElement && subtitle) {
return TtmlHelper.bindToTrack(trackElement, subtitleCanvas, duration)
}
}, [subtitleCanvas, trackElement, duration]);
}, [subtitleCanvas, subtitle, trackElement, duration]);
return (
<div ref={setSubtitleCanvas} className={className}/>
<div
ref={setSubtitleCanvas}
lang={subtitle?.language || undefined}
className={className}
/>
)
}
......@@ -73,7 +73,22 @@ export const DashVideoElement = forwardRef<VideoApi, PropsWithChildren<Props>>(f
}
return !Number.isNaN(player.duration());
},
setAudioTrack(track: MediaInfo) {
getAudioTracks(): MediaInfo[] {
if (!player.isReady()) {
return [];
}
return player.getTracksFor("audio").map((info: MediaInfo) => {
return info;
})
},
getCurrentAudioTrack(): MediaInfo | null {
if (!player.isReady()) {
return null;
}
return player.getCurrentTrackFor("audio");
},
setCurrentAudioTrack(track: MediaInfo) {
if (!player.isReady()) {
return;
}
......@@ -86,14 +101,6 @@ export const DashVideoElement = forwardRef<VideoApi, PropsWithChildren<Props>>(f
removeEventListener(event: string, listener: () => void) {
player.off(event, listener);
},
getAudioTracks(): MediaInfo[] {
if (!player.isReady()) {
return [];
}
return player.getTracksFor("audio").map((info: MediaInfo) => {
return info;
})
},
debug(): any {
return player;
}
......
......@@ -84,7 +84,10 @@ export const RawVideoElement = forwardRef<VideoApi, PropsWithChildren<Props>>(fu
getAudioTracks(): MediaInfo[] {
return [];
},
setAudioTrack(track: MediaInfo) {
setCurrentAudioTrack(track: MediaInfo) {
},
getCurrentAudioTrack(): MediaInfo | null {
return null;
},
addEventListener(event: string, listener: () => void) {
if (!videoElement) {
......
......@@ -24,7 +24,9 @@ export interface VideoApi {
getAudioTracks(): MediaInfo[]
setAudioTrack(track: MediaInfo): void
getCurrentAudioTrack(): MediaInfo | null
setCurrentAudioTrack(track: MediaInfo): void
addEventListener(event: string, listener: () => void): void
......
import {useEffect, useState} from "react";
import {useCallback, useEffect, useState} from "react";
import {VideoApi} from "../../routes/player/video/VideoApi";
import {MediaInfo} from "dashjs";
export const useAudioTracks = (video: VideoApi | null) => {
export function useAudioTracks(video: VideoApi | null):
[MediaInfo[], MediaInfo | null, (track: MediaInfo) => void] {
const [audioTracks, setAudioTracks] = useState<MediaInfo[]>([]);
useEffect(() => {
if (video !== null) {
if (video.canPlay()) {
setAudioTracks(video.getAudioTracks());
} else {
const listener = () => {
const [currentTrack, setCurrentTrack] = useState<MediaInfo | null>(null);
const listener = useCallback(() => {
window.requestAnimationFrame(() => {
if (video !== null) {
setAudioTracks(video.getAudioTracks());
setCurrentTrack(video.getCurrentAudioTrack);
}
})
};
video.addEventListener(video.METADATA_EVENT, listener)
}, [video]);
const updateAudioTracks = useCallback((track: MediaInfo) => {
video?.setCurrentAudioTrack(track);
listener();
}, [video, listener]);
useEffect(() => {
if (video?.canPlay()) {
setAudioTracks(video.getAudioTracks());
setCurrentTrack(video.getCurrentAudioTrack);
} else {
video?.addEventListener(video.METADATA_EVENT, listener)
return () => {
video.removeEventListener(video.METADATA_EVENT, listener)
}
video?.removeEventListener(video.METADATA_EVENT, listener)
}
}
}, [video]);
return audioTracks;
}, [listener, video]);
return [audioTracks, currentTrack, updateAudioTracks];
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment