diff --git a/src/pages/tools/video/video-to-gif/index.tsx b/src/pages/tools/video/video-to-gif/index.tsx index a8eba09..68b570e 100644 --- a/src/pages/tools/video/video-to-gif/index.tsx +++ b/src/pages/tools/video/video-to-gif/index.tsx @@ -1,8 +1,11 @@ import { Box } from '@mui/material'; import React, { useState } from 'react'; +import * as Yup from 'yup'; import ToolContent from '@components/ToolContent'; import { ToolComponentProps } from '@tools/defineTool'; import { GetGroupsType } from '@components/options/ToolOptions'; +import TextFieldWithDesc from '@components/options/TextFieldWithDesc'; +import { updateNumberField } from '@utils/string'; import { InitialValuesType } from './types'; import ToolVideoInput from '@components/input/ToolVideoInput'; import ToolFileResult from '@components/result/ToolFileResult'; @@ -13,9 +16,19 @@ import { fetchFile } from '@ffmpeg/util'; const initialValues: InitialValuesType = { quality: 'mid', fps: '10', - scale: '320:-1:flags=bicubic' + scale: '320:-1:flags=bicubic', + start: 0, + end: 100 }; +const validationSchema = Yup.object({ + start: Yup.number().min(0, 'Start time must be positive'), + end: Yup.number().min( + Yup.ref('start'), + 'End time must be greater than start time' + ) +}); + export default function VideoToGif({ title, longDescription @@ -26,14 +39,16 @@ export default function VideoToGif({ const compute = (values: InitialValuesType, input: File | null) => { if (!input) return; - const { fps, scale } = values; + const { fps, scale, start, end } = values; let ffmpeg: FFmpeg | null = null; let ffmpegLoaded = false; const convertVideoToGif = async ( file: File, fps: string, - scale: string + scale: string, + start: number, + end: number ): Promise => { setLoading(true); @@ -58,6 +73,10 @@ export default function VideoToGif({ await ffmpeg.exec([ '-i', fileName, + '-ss', + start.toString(), + '-to', + end.toString(), '-vf', `fps=${fps},scale=${scale},palettegen`, 'palette.png' @@ -68,6 +87,10 @@ export default function VideoToGif({ fileName, '-i', 'palette.png', + '-ss', + start.toString(), + '-to', + end.toString(), '-filter_complex', `fps=${fps},scale=${scale}[x];[x][1:v]paletteuse`, outputName @@ -92,7 +115,7 @@ export default function VideoToGif({ } }; - convertVideoToGif(input, fps, scale); + convertVideoToGif(input, fps, scale, start, end); }; const getGroups: GetGroupsType | null = ({ @@ -141,6 +164,28 @@ export default function VideoToGif({ /> ) + }, + { + title: 'Timestamps', + component: ( + + + updateNumberField(value, 'start', updateField) + } + value={values.start} + label="Start Time" + sx={{ mb: 2, backgroundColor: 'background.paper' }} + /> + + updateNumberField(value, 'end', updateField) + } + value={values.end} + label="End Time" + /> + + ) } ]; @@ -148,9 +193,22 @@ export default function VideoToGif({ - } + renderCustomInput={({ start, end }, setFieldValue) => { + return ( + { + setFieldValue('start', start); + setFieldValue('end', end); + }} + trimStart={start} + trimEnd={end} + /> + ); + }} resultComponent={ loading ? (