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

Fix errors, improve seeking

parent 386a39a5
No related branches found
No related tags found
No related merge requests found
import React, {useMemo} from "react";
import {useImage} from "../../util/media/useImage";
import {useTextTrackCues} from "../../util/media/useTextTrackCues";
import {parseImageSprite} from "../../util/sprite/parseImageSprite";
import {useImage} from "../../util/media/useImage";
import {useImageSprite} from "../../util/sprite/useImageSprite";
interface Props {
......@@ -14,10 +14,9 @@ export function PreviewViewer({previewTrack, position}: Props) {
const activeCue = cues.find(it => it.startTime <= position && it.endTime >= position)
const activeUrl = activeCue ? new URL(activeCue.text, previewTrack.src).toString() : null;
const imageSprite = useMemo(() => parseImageSprite(activeUrl), [activeUrl]);
console.log("active", activeUrl, imageSprite);
const image = useImage(imageSprite?.src || null);
const sprite = useImageSprite(imageSprite, image);
return useMemo(() => (
<img src={sprite || undefined}/>
<img alt="" src={sprite || undefined}/>
), [sprite]);
}
......@@ -13,9 +13,10 @@ interface MousePosition {
relative: number
}
function getMousePosition(event: React.MouseEvent<HTMLDivElement>): MousePosition {
function getMousePosition(event: React.MouseEvent<HTMLDivElement>): MousePosition | null {
const position = event.clientX - event.currentTarget.offsetLeft;
const width = event.currentTarget.offsetWidth;
if (position > width) return null;
return {
absolute: position,
relative: position / width
......@@ -35,12 +36,18 @@ export function SeekBar({video, previewTrack, duration}: Props) {
onMouseLeave={() => setSeekPosition(null)}
onClick={(event) => {
const position = getMousePosition(event);
if (position === null) {
return;
}
if (video) {
video.currentTime = position.relative * duration;
}
}}
onMouseMove={(event) => {
const position = getMousePosition(event);
if (position === null) {
return;
}
if (seekHeadRef.current) {
seekHeadRef.current.style.transform = `translate3d(${position.absolute}px, 0, 0)`
}
......@@ -57,7 +64,7 @@ export function SeekBar({video, previewTrack, duration}: Props) {
}}
/>
</div>
), [classes.seekBar, classes.seekHead, duration, isVisible]);
), [classes.seekBar, classes.seekHead, duration, isVisible, video]);
return (
<div>
......@@ -80,7 +87,7 @@ const useStyles = createUseStyles({
position: "absolute",
top: 0,
bottom: 0,
left: 0,
left: "-0.05rem",
width: "0.1rem",
background: "#f00",
}
......
import {useEffect, useRef, useState} from "react";
import {useEffect, useMemo, useState} from "react";
export const useImage = (url: string | null): HTMLImageElement | null => {
const image = useRef(new Image())
image.current.setAttribute("crossorigin", "anonymous");
const [imageData, setImageData] = useState<HTMLImageElement | null>(null);
useEffect(() => {
try {
image.current.src = url || "";
image.current.decode().then(() => {
setImageData(image.current);
})
} catch (_) {
const image = useMemo(() => {
if (url === null) {
return null;
} else {
const image = new Image();
image.setAttribute("crossorigin", "anonymous");
image.src = url;
return image;
}
}, [url]);
useEffect(() => {
let isCancelled = false;
image?.decode().then(() => {
if (!isCancelled) {
setImageData(image);
}
}).catch(err => {
console.error("Error while decoding image " + url + ": ", err);
});
return () => {
isCancelled = true;
}
}, [image, url]);
return imageData;
}
......@@ -9,9 +9,9 @@ export const usePosition = (video: HTMLVideoElement | null) => {
setPosition(video.currentTime);
})
};
video.addEventListener("progress", listener)
video.addEventListener("timeupdate", listener)
return () => {
video.removeEventListener("progress", listener)
video.removeEventListener("timeupdate", listener)
}
}
}, [video]);
......
......@@ -7,14 +7,18 @@ export const useTextTrackCues = (track: HTMLTrackElement) => {
if (track.readyState >= 1) {
setCues(Array.from(track.track.cues || []))
} else {
let animationFrame: number | null = null;
const listener = () => {
window.requestAnimationFrame(() => {
animationFrame = window.requestAnimationFrame(() => {
setCues(Array.from(track.track.cues || []))
})
};
track.addEventListener("load", listener)
return () => {
track.removeEventListener("load", listener)
track.removeEventListener("load", listener);
if (animationFrame) {
window.cancelAnimationFrame(animationFrame);
}
}
}
}, [track]);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment