Skip to content

Commit

Permalink
more file types
Browse files Browse the repository at this point in the history
  • Loading branch information
cccaaannn committed Aug 16, 2024
1 parent 37e6058 commit 65b4cd2
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 20 deletions.
81 changes: 69 additions & 12 deletions src/hooks/useFFmpeg/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ export type ConversionResult = ConversionSuccessResult | ConversionErrorResult;

export interface ConversionProps {
file: File;
outputFormat: SupportedFormats;
width: string;
height: string;
outputFormat: SupportedFormat;
width: number | null;
height: number | null;
}

export interface FFmpegCommandParameters {
inputFileName: string;
outputFileName: string;
width: string;
height: string;
outputFormat: SupportedFormat;
width: number | null;
height: number | null;
}

export enum ImageMimeTypes {
Expand All @@ -37,35 +38,91 @@ export enum ImageMimeTypes {
ICON = "image/x-icon",
}

export enum SupportedFormats {
export enum SupportedFormat {
PNG = "png",
JPG = "jpg",
JPEG = "jpeg",
WEBP = "webp",
ICO = "ico"
ICO = "ico",
SVG = "svg",
GIF = "gif",
APNG = "apng"
}

interface ImageFormatDetailType {
extension: string;
mimeType: ImageMimeTypes;
maxWidth: number;
maxHeight: number;
defaultWidth: number;
defaultHeight: number;
}

export const ImageFormatDetail: Record<SupportedFormats, ImageFormatDetailType> = {
export const ImageFormatDetail: Record<SupportedFormat, ImageFormatDetailType> = {
png: {
extension: "png",
mimeType: ImageMimeTypes.PNG
mimeType: ImageMimeTypes.PNG,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
},
jpg: {
extension: "jpg",
mimeType: ImageMimeTypes.JPEG
mimeType: ImageMimeTypes.JPEG,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
},
jpeg: {
extension: "jpeg",
mimeType: ImageMimeTypes.JPEG,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
},
webp: {
extension: "webp",
mimeType: ImageMimeTypes.WEBP
mimeType: ImageMimeTypes.WEBP,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
},
ico: {
extension: "ico",
mimeType: ImageMimeTypes.ICON
mimeType: ImageMimeTypes.ICON,
maxWidth: 256,
maxHeight: 256,
defaultWidth: 256,
defaultHeight: 256
},
svg: {
extension: "svg",
mimeType: ImageMimeTypes.SVG,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
},
gif: {
extension: "gif",
mimeType: ImageMimeTypes.GIF,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
},
apng: {
extension: "apng",
mimeType: ImageMimeTypes.APNG,
maxWidth: Infinity,
maxHeight: Infinity,
defaultWidth: -1,
defaultHeight: -1
}
}

export interface UseFFmpeg {
Expand Down
20 changes: 17 additions & 3 deletions src/hooks/useFFmpeg/useFFmpeg.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { SupportedFormats, ImageFormatDetail } from '@/hooks/useFFmpeg/types';
import { SupportedFormat, ImageFormatDetail } from '@/hooks/useFFmpeg/types';
import FileUtils from '@/utils/file-utils';
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { FileData, LogEvent } from '@ffmpeg/ffmpeg/dist/esm/types';
import { fetchFile } from '@ffmpeg/util';
import { createSignal, onMount, onCleanup } from 'solid-js';
import { ConversionProps, ConversionResult, FFmpegCommandParameters, UseFFmpeg } from './types';

const getSizeForFormat = (format: SupportedFormat, width: number | null, height: number | null): { width: number, height: number } => {
const formatDetail = ImageFormatDetail[format];

const maxWidth = (!width || width > formatDetail.maxWidth) ? formatDetail.defaultWidth : width;
const maxHeight = (!height || height > formatDetail.maxHeight) ? formatDetail.defaultHeight : height;

return {
width: Math.min(maxWidth, formatDetail.maxWidth),
height: Math.min(maxHeight, formatDetail.maxHeight)
};
}

const formatFFmpegCommand = (parameters: FFmpegCommandParameters): string[] => {
const command = ["-i", parameters.inputFileName];

const size = getSizeForFormat(parameters.outputFormat, parameters.width, parameters.height);

command.push("-vf");
const scale = `${parameters.width ?? -1}:${parameters.height ?? -1}`;
const scale = `${size.width}:${size.height}`;
command.push(`scale=${scale}`);

command.push(parameters.outputFileName);
Expand Down Expand Up @@ -67,7 +81,7 @@ const useFFmpeg = (): UseFFmpeg => {
};
}

const inputFormat = extension.toLowerCase() as SupportedFormats;
const inputFormat = extension.toLowerCase() as SupportedFormat;

const inputFileName = `img.${ImageFormatDetail[inputFormat].extension}`;
const outputFileName = `${name}.${ImageFormatDetail[conversionProps.outputFormat].extension}`;
Expand Down
10 changes: 5 additions & 5 deletions src/pages/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ConvertButton from '@/components/convert-button';
import DragDropFilePicker from '@/components/drag-drop-file-picker';
import SelectBox from '@/components/select-box';
import useFFmpeg from '@/hooks/useFFmpeg/useFFmpeg';
import { SupportedFormats } from '@/hooks/useFFmpeg/types';
import { SupportedFormat } from '@/hooks/useFFmpeg/types';
import FileUtils from '@/utils/file-utils';
import { Show, createSignal } from 'solid-js';
import Spinner from '@/components/spinner';
Expand All @@ -18,12 +18,12 @@ import { SelectBoxItem } from "@/components/select-box";
import InfoIcon from '@/components/icons/info-icon';
import InfoAlert from '@/components/info-alert';

export const SupportedFormatsList = Object.values(SupportedFormats).map<SelectBoxItem<SupportedFormats>>(format => { return { label: format, value: format as SupportedFormats } });
export const SupportedFormatsList = Object.values(SupportedFormat).map<SelectBoxItem<SupportedFormat>>(format => { return { label: format, value: format as SupportedFormat } });

function Home() {
const [selectedFile, setSelectedFiles] = createSignal<File | null>(null);

const [outputFormat, setOutputFormat] = createSignal<SupportedFormats>(SupportedFormats.ICO);
const [outputFormat, setOutputFormat] = createSignal<SupportedFormat>(SupportedFormat.ICO);

const { settingsVisible, setSettingsVisible, scale, setScale } = useAdvancedSettings();

Expand All @@ -41,8 +41,8 @@ function Home() {
const conversionProps: ConversionProps = {
file: file,
outputFormat: outputFormat(),
width: scale().width || "-1",
height: scale().height || "-1"
width: scale().width ? parseInt(scale().width, 10) : null,
height: scale().height ? parseInt(scale().height, 10) : null
}

const conversionResult = await convert(conversionProps);
Expand Down

0 comments on commit 65b4cd2

Please sign in to comment.