Merge branch 'main' of https://github.com/iib0011/omni-tools into fork/AshAnand34/merge-video-tool

This commit is contained in:
Ibrahima G. Coulibaly
2025-07-18 02:35:35 +01:00
323 changed files with 20828 additions and 2044 deletions

View File

@@ -9,6 +9,7 @@ import ToolFileResult from '@components/result/ToolFileResult';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util';
import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
newSpeed: 2
@@ -18,6 +19,7 @@ export default function ChangeSpeed({
title,
longDescription
}: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const [loading, setLoading] = useState(false);
@@ -128,13 +130,13 @@ export default function ChangeSpeed({
updateField
}) => [
{
title: 'New Video Speed',
title: t('changeSpeed.newVideoSpeed'),
component: (
<Box>
<TextFieldWithDesc
value={values.newSpeed.toString()}
onOwnChange={(val) => updateField('newSpeed', Number(val))}
description="Default multiplier: 2 means 2x faster"
description={t('changeSpeed.defaultMultiplier')}
type="number"
/>
</Box>
@@ -149,21 +151,32 @@ export default function ChangeSpeed({
<ToolVideoInput
value={input}
onChange={setInput}
title={'Input Video'}
title={t('changeSpeed.inputTitle')}
/>
}
resultComponent={
loading ? (
<ToolFileResult title="Setting Speed" value={null} loading={true} />
<ToolFileResult
title={t('changeSpeed.settingSpeed')}
value={null}
loading={true}
/>
) : (
<ToolFileResult title="Edited Video" value={result} extension="mp4" />
<ToolFileResult
title={t('changeSpeed.resultTitle')}
value={result}
extension="mp4"
/>
)
}
initialValues={initialValues}
getGroups={getGroups}
setInput={setInput}
compute={compute}
toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
toolInfo={{
title: t('changeSpeed.toolInfo.title', { title }),
description: longDescription
}}
/>
);
}

View File

@@ -2,12 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Change speed',
path: 'change-speed',
icon: 'material-symbols-light:speed-outline',
description:
'This online utility lets you change the speed of a video. You can speed it up or slow it down.',
shortDescription: 'Quickly change video speed',
keywords: ['change', 'speed'],
component: lazy(() => import('./index'))
icon: 'material-symbols:speed',
keywords: ['video', 'speed', 'playback', 'fast', 'slow'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:changeSpeed.title',
description: 'video:changeSpeed.description',
shortDescription: 'video:changeSpeed.shortDescription'
}
});

View File

@@ -11,6 +11,7 @@ import { compressVideo, VideoResolution } from './service';
import SimpleRadio from '@components/options/SimpleRadio';
import Slider from 'rc-slider';
import 'rc-slider/assets/index.css';
import { useTranslation } from 'react-i18next';
export const initialValues = {
width: 480 as VideoResolution,
@@ -68,6 +69,7 @@ const presetOptions = [
];
export default function CompressVideo({ title }: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const [loading, setLoading] = useState(false);
@@ -100,7 +102,7 @@ export default function CompressVideo({ title }: ToolComponentProps) {
updateField
}) => [
{
title: 'Resolution',
title: t('compress.resolution'),
component: (
<Box>
{resolutionOptions.map((option) => (
@@ -117,7 +119,7 @@ export default function CompressVideo({ title }: ToolComponentProps) {
)
},
{
title: 'Quality (CRF)',
title: t('compress.quality'),
component: (
<Box sx={{ mb: 2 }}>
<Slider
@@ -129,9 +131,9 @@ export default function CompressVideo({ title }: ToolComponentProps) {
updateField('crf', typeof value === 'number' ? value : value[0]);
}}
marks={{
0: 'Lossless',
23: 'Default',
51: 'Worst'
0: t('compress.lossless'),
23: t('compress.default'),
51: t('compress.worst')
}}
/>
</Box>
@@ -160,16 +162,16 @@ export default function CompressVideo({ title }: ToolComponentProps) {
<ToolVideoInput
value={input}
onChange={setInput}
title={'Input Video'}
title={t('compress.inputTitle')}
/>
}
resultComponent={
<ToolFileResult
title={'Compressed Video'}
title={t('compress.resultTitle')}
value={result}
extension={'mp4'}
loading={loading}
loadingText={'Compressing video...'}
loadingText={t('compress.loadingText')}
/>
}
initialValues={initialValues}

View File

@@ -2,12 +2,9 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Compress Video',
path: 'compress',
icon: 'icon-park-outline:compression',
description:
'Compress videos by scaling them to different resolutions like 240p, 480p, 720p, etc. This tool helps reduce file size while maintaining acceptable quality. Supports common video formats like MP4, WebM, and OGG.',
shortDescription: 'Compress videos by scaling to different resolutions',
keywords: [
'compress',
'video',
@@ -16,5 +13,10 @@ export const tool = defineTool('video', {
'resolution',
'reduce size'
],
component: lazy(() => import('./index'))
component: lazy(() => import('./index')),
i18n: {
name: 'video:compress.title',
description: 'video:compress.description',
shortDescription: 'video:compress.shortDescription'
}
});

View File

@@ -1,13 +1,14 @@
import { Box, TextField, Typography, Alert } from '@mui/material';
import { useCallback, useState, useEffect } from 'react';
import ToolFileResult from '@components/result/ToolFileResult';
import { Box, Typography, TextField, Alert } from '@mui/material';
import React, { useState, useCallback } from 'react';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
import { GetGroupsType } from '@components/options/ToolOptions';
import { debounce } from 'lodash';
import ToolVideoInput from '@components/input/ToolVideoInput';
import { cropVideo, getVideoDimensions } from './service';
import { InitialValuesType } from './types';
import ToolVideoInput from '@components/input/ToolVideoInput';
import { GetGroupsType } from '@components/options/ToolOptions';
import ToolFileResult from '@components/result/ToolFileResult';
import { debounce } from 'lodash';
import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
x: 0,
@@ -17,6 +18,7 @@ const initialValues: InitialValuesType = {
};
export default function CropVideo({ title }: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const [loading, setLoading] = useState(false);
@@ -30,19 +32,23 @@ export default function CropVideo({ title }: ToolComponentProps) {
if (!videoDimensions) return '';
if (values.x < 0 || values.y < 0) {
return 'X and Y coordinates must be non-negative';
return t('cropVideo.errorNonNegativeCoordinates');
}
if (values.width <= 0 || values.height <= 0) {
return 'Width and height must be positive';
return t('cropVideo.errorPositiveDimensions');
}
if (values.x + values.width > videoDimensions.width) {
return `Crop area extends beyond video width (${videoDimensions.width}px)`;
return t('cropVideo.errorBeyondWidth', {
width: videoDimensions.width
});
}
if (values.y + values.height > videoDimensions.height) {
return `Crop area extends beyond video height (${videoDimensions.height}px)`;
return t('cropVideo.errorBeyondHeight', {
height: videoDimensions.height
});
}
return '';
@@ -68,9 +74,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
setResult(croppedFile);
} catch (error) {
console.error('Error cropping video:', error);
setProcessingError(
'Error cropping video. Please check parameters and video file.'
);
setProcessingError(t('cropVideo.errorCroppingVideo'));
} finally {
setLoading(false);
}
@@ -86,24 +90,26 @@ export default function CropVideo({ title }: ToolComponentProps) {
updateField
}) => [
{
title: 'Video Information',
title: t('cropVideo.videoInformation'),
component: (
<Box>
{videoDimensions ? (
<Typography variant="body2" sx={{ mb: 2 }}>
Video dimensions: {videoDimensions.width} ×{' '}
{videoDimensions.height} pixels
{t('cropVideo.videoDimensions', {
width: videoDimensions.width,
height: videoDimensions.height
})}
</Typography>
) : (
<Typography variant="body2" sx={{ mb: 2 }}>
Load a video to see dimensions
{t('cropVideo.loadVideoForDimensions')}
</Typography>
)}
</Box>
)
},
{
title: 'Crop Coordinates',
title: t('cropVideo.cropCoordinates'),
component: (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
{processingError && (
@@ -113,7 +119,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
)}
<Box sx={{ display: 'flex', gap: 2 }}>
<TextField
label="X (left)"
label={t('cropVideo.xCoordinate')}
type="number"
value={values.x}
onChange={(e) => updateField('x', parseInt(e.target.value) || 0)}
@@ -121,7 +127,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
inputProps={{ min: 0 }}
/>
<TextField
label="Y (top)"
label={t('cropVideo.yCoordinate')}
type="number"
value={values.y}
onChange={(e) => updateField('y', parseInt(e.target.value) || 0)}
@@ -131,7 +137,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
</Box>
<Box sx={{ display: 'flex', gap: 2 }}>
<TextField
label="Width"
label={t('cropVideo.width')}
type="number"
value={values.width}
onChange={(e) =>
@@ -141,7 +147,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
inputProps={{ min: 1 }}
/>
<TextField
label="Height"
label={t('cropVideo.height')}
type="number"
value={values.height}
onChange={(e) =>
@@ -183,7 +189,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
})
.catch((error) => {
console.error('Error getting video dimensions:', error);
setProcessingError('Failed to load video dimensions');
setProcessingError(t('cropVideo.errorLoadingDimensions'));
});
} else {
setVideoDimensions(null);
@@ -191,20 +197,20 @@ export default function CropVideo({ title }: ToolComponentProps) {
}
setInput(video);
}}
title={'Input Video'}
title={t('cropVideo.inputTitle')}
/>
)}
resultComponent={
loading ? (
<ToolFileResult
title={'Cropping Video'}
title={t('cropVideo.croppingVideo')}
value={null}
loading={true}
extension={''}
/>
) : (
<ToolFileResult
title={'Cropped Video'}
title={t('cropVideo.resultTitle')}
value={result}
extension={'mp4'}
/>

View File

@@ -2,13 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Crop video',
path: 'crop-video',
icon: 'mdi:crop',
description: 'Crop a video by specifying coordinates and dimensions',
shortDescription: 'Crop video to specific area',
keywords: ['crop', 'video', 'trim', 'cut', 'resize'],
longDescription:
'Remove unwanted parts from the edges of your video by cropping it to a specific rectangular area. Define the starting coordinates (X, Y) and the width and height of the area you want to keep.',
component: lazy(() => import('./index'))
icon: 'material-symbols:crop',
keywords: ['video', 'crop', 'trim', 'edit', 'resize'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:cropVideo.title',
description: 'video:cropVideo.description',
shortDescription: 'video:cropVideo.shortDescription'
}
});

View File

@@ -10,6 +10,7 @@ import ToolVideoInput from '@components/input/ToolVideoInput';
import { flipVideo } from './service';
import { FlipOrientation, InitialValuesType } from './types';
import SimpleRadio from '@components/options/SimpleRadio';
import { useTranslation } from 'react-i18next';
export const initialValues: InitialValuesType = {
orientation: 'horizontal'
@@ -30,6 +31,7 @@ const orientationOptions: { value: FlipOrientation; label: string }[] = [
];
export default function FlipVideo({ title }: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const [loading, setLoading] = useState(false);
@@ -58,13 +60,13 @@ export default function FlipVideo({ title }: ToolComponentProps) {
updateField
}) => [
{
title: 'Orientation',
title: t('flip.orientation'),
component: (
<Box>
{orientationOptions.map((orientationOption) => (
<SimpleRadio
key={orientationOption.value}
title={orientationOption.label}
title={t(`flip.${orientationOption.value}Label`)}
checked={values.orientation === orientationOption.value}
onClick={() => {
updateField('orientation', orientationOption.value);
@@ -84,20 +86,20 @@ export default function FlipVideo({ title }: ToolComponentProps) {
<ToolVideoInput
value={input}
onChange={setInput}
title={'Input Video'}
title={t('flip.inputTitle')}
/>
}
resultComponent={
loading ? (
<ToolFileResult
title={'Flipping Video'}
title={t('flip.flippingVideo')}
value={null}
loading={true}
extension={''}
/>
) : (
<ToolFileResult
title={'Flipped Video'}
title={t('flip.resultTitle')}
value={result}
extension={'mp4'}
/>

View File

@@ -2,14 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Flip Video',
path: 'flip',
icon: 'mdi:flip-horizontal',
description:
'This online utility allows you to flip videos horizontally or vertically. You can preview the flipped video before processing. Supports common video formats like MP4, WebM, and OGG.',
shortDescription: 'Flip videos horizontally or vertically',
keywords: ['flip', 'video', 'mirror', 'edit', 'horizontal', 'vertical'],
longDescription:
'Easily flip your videos horizontally (mirror) or vertically (upside down) with this simple online tool.',
component: lazy(() => import('./index'))
icon: 'material-symbols:flip',
keywords: ['video', 'flip', 'mirror', 'horizontal', 'vertical'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:flip.title',
description: 'video:flip.description',
shortDescription: 'video:flip.shortDescription'
}
});

View File

@@ -3,12 +3,14 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('gif', {
name: 'Change speed',
path: 'change-speed',
icon: 'material-symbols-light:speed-outline',
description:
'This online utility lets you change the speed of a GIF animation. You can speed it up or slow it down. You can set the same constant delay between all frames or change the delays of individual frames. You can also play both the input and output GIFs at the same time and compare their speeds',
shortDescription: 'Quickly change GIF speed',
keywords: ['change', 'speed'],
component: lazy(() => import('./index'))
icon: 'material-symbols:speed',
keywords: ['gif', 'speed', 'animation', 'fast', 'slow'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:gif.changeSpeed.title',
description: 'video:gif.changeSpeed.description',
shortDescription: 'video:gif.changeSpeed.shortDescription'
}
});

View File

@@ -11,6 +11,7 @@ import ToolFileResult from '@components/result/ToolFileResult';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { updateNumberField } from '@utils/string';
import * as Yup from 'yup';
import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
loops: 2
@@ -21,6 +22,7 @@ const validationSchema = Yup.object({
});
export default function Loop({ title, longDescription }: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const [loading, setLoading] = useState(false);
@@ -43,7 +45,7 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
updateField
}) => [
{
title: 'Loops',
title: t('loop.loops'),
component: (
<Box>
<TextFieldWithDesc
@@ -51,7 +53,7 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
updateNumberField(value, 'loops', updateField)
}
value={values.loops}
label={'Number of Loops'}
label={t('loop.numberOfLoops')}
/>
</Box>
)
@@ -66,14 +68,14 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
loading ? (
<ToolFileResult
value={null}
title={'Looping Video'}
title={t('loop.loopingVideo')}
loading={true}
extension={''}
/>
) : (
<ToolFileResult
value={result}
title={'Looped Video'}
title={t('loop.resultTitle')}
extension={'mp4'}
/>
)
@@ -83,7 +85,10 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
getGroups={getGroups}
setInput={setInput}
compute={compute}
toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
toolInfo={{
title: t('loop.toolInfo.title', { title }),
description: longDescription
}}
/>
);
}

View File

@@ -2,12 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Loop Video',
path: 'loop',
icon: 'ic:baseline-loop',
description:
'This online utility lets you loop videos by specifying the number of repetitions. You can preview the looped video before processing. Supports common video formats like MP4, WebM, and OGG.',
shortDescription: 'Loop videos multiple times',
keywords: ['loop', 'video', 'repeat', 'duplicate', 'sequence', 'playback'],
component: lazy(() => import('./index'))
icon: 'material-symbols:loop',
keywords: ['video', 'loop', 'repeat', 'continuous'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:loop.title',
description: 'video:loop.description',
shortDescription: 'video:loop.shortDescription'
}
});

View File

@@ -10,6 +10,7 @@ import ToolVideoInput from '@components/input/ToolVideoInput';
import { rotateVideo } from './service';
import { RotationAngle } from '../../pdf/rotate-pdf/types';
import SimpleRadio from '@components/options/SimpleRadio';
import { useTranslation } from 'react-i18next';
export const initialValues = {
rotation: 90
@@ -27,6 +28,7 @@ const angleOptions: { value: RotationAngle; label: string }[] = [
{ value: 270, label: '270° (90° Counter-clockwise)' }
];
export default function RotateVideo({ title }: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
const [loading, setLoading] = useState(false);
@@ -55,13 +57,13 @@ export default function RotateVideo({ title }: ToolComponentProps) {
updateField
}) => [
{
title: 'Rotation',
title: t('rotate.rotation'),
component: (
<Box>
{angleOptions.map((angleOption) => (
<SimpleRadio
key={angleOption.value}
title={angleOption.label}
title={t(`rotate.${angleOption.value}Degrees`)}
checked={values.rotation === angleOption.value}
onClick={() => {
updateField('rotation', angleOption.value);
@@ -81,20 +83,20 @@ export default function RotateVideo({ title }: ToolComponentProps) {
<ToolVideoInput
value={input}
onChange={setInput}
title={'Input Video'}
title={t('rotate.inputTitle')}
/>
}
resultComponent={
loading ? (
<ToolFileResult
title={'Rotating Video'}
title={t('rotate.rotatingVideo')}
value={null}
loading={true}
extension={''}
/>
) : (
<ToolFileResult
title={'Rotated Video'}
title={t('rotate.resultTitle')}
value={result}
extension={'mp4'}
/>

View File

@@ -2,12 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Rotate Video',
path: 'rotate',
icon: 'mdi:rotate-right',
description:
'This online utility lets you rotate videos by 90, 180, or 270 degrees. You can preview the rotated video before processing. Supports common video formats like MP4, WebM, and OGG.',
shortDescription: 'Rotate videos by 90, 180, or 270 degrees',
keywords: ['rotate', 'video', 'flip', 'edit', 'adjust'],
component: lazy(() => import('./index'))
icon: 'material-symbols:rotate-right',
keywords: ['video', 'rotate', 'orientation', 'degrees'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:rotate.title',
description: 'video:rotate.description',
shortDescription: 'video:rotate.shortDescription'
}
});

View File

@@ -11,6 +11,7 @@ import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util';
import { debounce } from 'lodash';
import ToolVideoInput from '@components/input/ToolVideoInput';
import { useTranslation } from 'react-i18next';
const ffmpeg = new FFmpeg();
@@ -28,6 +29,7 @@ const validationSchema = Yup.object({
});
export default function TrimVideo({ title }: ToolComponentProps) {
const { t } = useTranslation('video');
const [input, setInput] = useState<File | null>(null);
const [result, setResult] = useState<File | null>(null);
@@ -85,7 +87,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
updateField
}) => [
{
title: 'Timestamps',
title: t('trim.timestamps'),
component: (
<Box>
<TextFieldWithDesc
@@ -93,7 +95,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
updateNumberField(value, 'trimStart', updateField)
}
value={values.trimStart}
label={'Start Time'}
label={t('trim.startTime')}
sx={{ mb: 2, backgroundColor: 'background.paper' }}
/>
<TextFieldWithDesc
@@ -101,7 +103,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
updateNumberField(value, 'trimEnd', updateField)
}
value={values.trimEnd}
label={'End Time'}
label={t('trim.endTime')}
/>
</Box>
)
@@ -116,7 +118,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
<ToolVideoInput
value={input}
onChange={setInput}
title={'Input Video'}
title={t('trim.inputTitle')}
showTrimControls={true}
onTrimChange={(trimStart, trimEnd) => {
setFieldValue('trimStart', trimStart);
@@ -129,7 +131,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
}}
resultComponent={
<ToolFileResult
title={'Trimmed Video'}
title={t('trim.resultTitle')}
value={result}
extension={'mp4'}
/>

View File

@@ -2,12 +2,13 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Trim Video',
path: 'trim',
icon: 'mdi:scissors',
description:
'This online utility lets you trim videos by setting start and end points. You can preview the trimmed section before processing. Supports common video formats like MP4, WebM, and OGG.',
shortDescription: 'Trim videos by setting start and end points',
keywords: ['trim', 'cut', 'video', 'clip', 'edit'],
component: lazy(() => import('./index'))
icon: 'material-symbols:content-cut',
keywords: ['video', 'trim', 'cut', 'edit', 'time'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:trim.title',
description: 'video:trim.description',
shortDescription: 'video:trim.shortDescription'
}
});

View File

@@ -2,11 +2,13 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('video', {
name: 'Video to Gif',
path: 'video-to-gif',
icon: 'fluent:gif-16-regular',
description: 'This online utility lets you convert a short video to gif.',
shortDescription: 'Quickly convert a short video to gif',
keywords: ['video', 'to', 'gif', 'convert'],
component: lazy(() => import('./index'))
icon: 'material-symbols:gif',
keywords: ['video', 'gif', 'convert', 'animated', 'image'],
component: lazy(() => import('./index')),
i18n: {
name: 'video:videoToGif.title',
description: 'video:videoToGif.description',
shortDescription: 'video:videoToGif.shortDescription'
}
});