Skip to content

Commit fa8fb4a

Browse files
committed
let's go
1 parent 1821511 commit fa8fb4a

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

packages/convert/app/components/ConvertProgress.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@ import {formatSeconds} from '~/lib/format-seconds';
55
import {Container, getNewName} from '~/lib/generate-new-name';
66
import {Card} from './ui/card';
77
import {Skeleton} from './ui/skeleton';
8+
import {VideoThumbnail} from './VideoThumbnail';
89

910
export const ConvertProgress: React.FC<{
1011
readonly state: ConvertMediaState;
1112
readonly name: string | null;
1213
readonly container: Container;
13-
}> = ({state, name, container}) => {
14+
readonly currentFrame: VideoFrame | null;
15+
}> = ({state, name, container, currentFrame}) => {
1416
return (
1517
<>
1618
<Card className="overflow-hidden">
19+
<VideoThumbnail thumbnail={currentFrame} />
20+
<div className="border-b-2 border-black" />
1721
<div className="h-5 overflow-hidden">
1822
{state.overallProgress ? (
1923
<div

packages/convert/app/components/ConvertUi.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,24 @@ export default function ConvertUI({src}: {readonly src: Source}) {
2525
const [audioCodec, setAudioCodec] = useState('opus');
2626
const [state, setState] = useState<ConvertState>({type: 'idle'});
2727
const [name, setName] = useState<string | null>(null);
28+
const [currentFrame, setCurrentFrame] = useState<VideoFrame | null>(null);
2829

2930
const onClick = useCallback(() => {
3031
const abortController = new AbortController();
3132

3233
let _n: string | null = null;
3334

35+
let videoFrames = 0;
36+
3437
convertMedia({
3538
src: src.type === 'url' ? src.url : src.file,
3639
reader: src.type === 'file' ? webFileReader : fetchReader,
37-
onVideoFrame: () => {
40+
onVideoFrame: (frame) => {
41+
if (videoFrames % 30 === 0) {
42+
setCurrentFrame(frame.clone());
43+
}
44+
45+
videoFrames++;
3846
return Promise.resolve();
3947
},
4048
logLevel: 'verbose',
@@ -145,6 +153,7 @@ export default function ConvertUI({src}: {readonly src: Source}) {
145153
state={state.state}
146154
name={name}
147155
container={container}
156+
currentFrame={currentFrame}
148157
/>
149158
<div className="h-2" />
150159
<Button className="block w-full" type="button" onClick={cancel}>
@@ -157,6 +166,7 @@ export default function ConvertUI({src}: {readonly src: Source}) {
157166
state={state.state}
158167
name={name}
159168
container={container}
169+
currentFrame={currentFrame}
160170
/>
161171
<div className="h-2" />
162172
<Button className="block w-full" type="button" onClick={onDownload}>

packages/convert/app/components/VideoThumbnail.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,39 @@ const ThumbnailContent: React.FC<{readonly thumbnail: VideoFrame}> = ({
88
}) => {
99
const ref = useRef<HTMLCanvasElement>(null);
1010

11-
const scaleRatio = THUMBNAIL_HEIGHT / thumbnail.displayHeight;
12-
const width = Math.round(thumbnail.displayWidth * scaleRatio);
13-
1411
const [color, setColor] = useState<string>('transparent');
12+
const [width, setWidth] = useState<number>(0);
1513

1614
useEffect(() => {
15+
const scaleRatio = THUMBNAIL_HEIGHT / thumbnail.displayHeight;
16+
const w = Math.round(thumbnail.displayWidth * scaleRatio);
17+
setWidth(w);
18+
1719
createImageBitmap(thumbnail, {
18-
resizeWidth: width,
20+
resizeWidth: w,
1921
resizeHeight: THUMBNAIL_HEIGHT,
2022
}).then((bitmap) => {
21-
const twoDContext = ref.current?.getContext('2d');
23+
const canvas = ref.current;
24+
if (!canvas) {
25+
return;
26+
}
27+
canvas.width = w;
28+
const twoDContext = canvas.getContext('2d');
2229
if (!twoDContext) {
2330
return;
2431
}
2532

2633
twoDContext.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
2734
const color = new FastAverageColor().getColor(ref.current);
2835
setColor(color.hex);
36+
thumbnail.close();
2937
});
30-
}, [scaleRatio, thumbnail, width]);
38+
}, [thumbnail]);
3139

3240
return (
3341
<div className="flex justify-center" style={{backgroundColor: color}}>
3442
<canvas
3543
ref={ref}
36-
width={width}
3744
height={THUMBNAIL_HEIGHT}
3845
style={{
3946
maxHeight: THUMBNAIL_HEIGHT,
@@ -47,10 +54,7 @@ export const VideoThumbnail: React.FC<{
4754
readonly thumbnail: VideoFrame | null;
4855
}> = ({thumbnail}) => {
4956
return (
50-
<div
51-
className="border-b-2 border-black "
52-
style={{height: THUMBNAIL_HEIGHT}}
53-
>
57+
<div className="border-b-2 border-black" style={{height: THUMBNAIL_HEIGHT}}>
5458
{thumbnail ? <ThumbnailContent thumbnail={thumbnail} /> : null}
5559
</div>
5660
);

0 commit comments

Comments
 (0)