Skip to content

Commit

Permalink
Merge pull request #36 from CarlaPaiva/feat/video-converter
Browse files Browse the repository at this point in the history
feat: full video converter
  • Loading branch information
CarlaPaiva authored Jan 27, 2024
2 parents 8754b6d + da27dcd commit c5813c4
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/components/converter-content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import VideoConverter from '../video-converter';

const items = [
{
label: 'Video To GIF',
label: 'Video Converter',
key: '1',
children: <VideoConverter/>
}
Expand Down
6 changes: 4 additions & 2 deletions src/components/converter/converter-steps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type ConverterStepsProps = {
convert: () => Promise<void>
clearStates: () => void
downloadFiles: () => void
updateSelectedExtension: (extension: string) => void
}

const ConverterSteps = memo(function ConverterStepsComponent(props: ConverterStepsProps): JSX.Element {
Expand All @@ -43,8 +44,9 @@ const ConverterSteps = memo(function ConverterStepsComponent(props: ConverterSte
allowedUploadingFormats={props.allowedUploadingFormats}
extensionOptions={props.extensionOptions}
onConvertClick={onConvertClick}
populateFileList={props.populateFileList} />
}, [props.allowedUploadingFormats, props.extensionOptions, props.populateFileList, onConvertClick])
populateFileList={props.populateFileList}
updateSelectedExtension={props.updateSelectedExtension} />
}, [props.allowedUploadingFormats, props.extensionOptions, props.populateFileList, props.updateSelectedExtension, onConvertClick])

const getResultStep = useCallback(() => {
return <ResultStep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type UploadStepProps = {
allowedUploadingFormats: string[]
populateFileList: (files: UploadFile[]) => void
onConvertClick: () => void
updateSelectedExtension: (extension: string) => void
}

type ErrorMessage = {
Expand Down Expand Up @@ -59,7 +60,8 @@ const UploadStep = memo(function UploadStepComponent(props: Readonly<UploadStepP

const onSelectedFormatChange = useCallback((value: string) => {
setFormat(value)
}, [])
props.updateSelectedExtension(value)
}, [props])

const onClick = useCallback(() => {

Expand Down
10 changes: 6 additions & 4 deletions src/components/converter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ type ConverterProps = {
const Converter = memo(function ConverterComponent(props: ConverterProps): JSX.Element {
const [fileList, setFileList] = useState<UploadFile[]>([])
const [convertedFiles, setConvertedFiles ] = useState<ConvertedFile[]>([])

const [selectedExtension, setSelectedExtension ] = useState('')

const onUploadDone = useCallback((files: UploadFile[]) => {
setFileList(files)
}, [])
Expand All @@ -35,9 +36,9 @@ const Converter = memo(function ConverterComponent(props: ConverterProps): JSX.E
}, [])

const convert = useCallback(async () => {
const files = await convertFiles(fileList)
const files = await convertFiles(fileList, selectedExtension)
setConvertedFiles(files)
}, [fileList])
}, [fileList, selectedExtension])

const downloadFiles = useCallback(() => {
convertedFiles.forEach(file => {
Expand All @@ -62,7 +63,8 @@ const Converter = memo(function ConverterComponent(props: ConverterProps): JSX.E
populateFileList={onUploadDone}
convert={convert}
clearStates={clearStates}
downloadFiles={downloadFiles} />
downloadFiles={downloadFiles}
updateSelectedExtension={setSelectedExtension} />
)
})

Expand Down
23 changes: 20 additions & 3 deletions src/components/video-converter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,31 @@ import { Format } from "../../model/format"
import Converter from "../converter"

const uploadingFormat: string[] = [
".mp4"
"video/mp4",
"video/x-m4v",
"video/*"
]

const optionsToConvertTo: Format[] = [
{
name: "GIF",
extension: ".gif",
mimeType: "image/gif"
extension: ".gif"
},
{
name: "MP4",
extension: ".mp4"
},
{
name: "AVI",
extension: ".avi"
},
{
name: "WMV",
extension: ".wmv"
},
{
name: "MP3",
extension: ".mp3"
}
]

Expand Down
2 changes: 0 additions & 2 deletions src/model/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ export type Format = {
name: string
/** Extension with a dot */
extension: string
/** Mime type of this format, that allow it to be downloaded */
mimeType: string
}
33 changes: 25 additions & 8 deletions src/services/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@ import { createFFmpeg } from "@ffmpeg/ffmpeg";
import { UploadFile } from "antd";
import { ConvertedFile } from "../model/converted-file";

async function convertFiles(fileList: UploadFile[]): Promise<ConvertedFile[]>{
const mimeType = {
".gif": "image/gif",
".mp4": "video/mp4",
".avi": "video/x-msvideo",
".wmv": "video/x-ms-wmv",
".mp3": "audio/mp3",
}

async function convertFiles(fileList: UploadFile[], extension: string): Promise<ConvertedFile[]>{
const blobList: ConvertedFile[] = []

for (const file of fileList) {
const sourceBuffer = await file.originFileObj?.arrayBuffer() as ArrayBuffer
console.log('sourceBuffer', sourceBuffer)
const nameWithoutExt = file.name.split('.')[0]
const outputName = `${nameWithoutExt}.gif`
const outputName = `${nameWithoutExt}${extension}`

const ffmpeg = createFFmpeg({ log: true });
await ffmpeg.load();
Expand All @@ -23,12 +31,21 @@ async function convertFiles(fileList: UploadFile[]): Promise<ConvertedFile[]>{
await ffmpeg.run("-i", file.name, outputName);

const output = ffmpeg.FS("readFile", outputName);
const blob = new Blob([output.buffer], { type: "image/gif" })
blobList.push({
newFileName: outputName,
blob,
result: "success"
})

if (output === null || output.buffer.byteLength <= 0 ) {
blobList.push({
newFileName: outputName,
result: "error",
blob: new Blob()
})
} else {
const blob = new Blob([output.buffer], { type: mimeType[extension as keyof typeof mimeType] })
blobList.push({
newFileName: outputName,
blob,
result: "success"
})
}
}

return blobList
Expand Down

0 comments on commit c5813c4

Please sign in to comment.