Skip to content

Commit

Permalink
resolve options
Browse files Browse the repository at this point in the history
  • Loading branch information
JonnyBurger committed Nov 10, 2024
1 parent ecb2ada commit 1005f3d
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 65 deletions.
39 changes: 39 additions & 0 deletions packages/convert/app/components/AudioCodecSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {AudioOperation} from '@remotion/webcodecs';
import React from 'react';
import {AudioOperationOption} from './AudioOperationOption';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from './ui/select';

export const AudioCodecSelection: React.FC<{
readonly audioTrackOptions: AudioOperation[];
readonly index: number;
readonly setIndex: (v: number) => void;
}> = ({audioTrackOptions, index, setIndex}) => {
return (
<Select value={String(index)} onValueChange={(v) => setIndex(Number(v))}>
<SelectTrigger id="audioCodec">
<SelectValue placeholder="Select a audio codec" />
</SelectTrigger>
<SelectContent>
{audioTrackOptions.map((operation, i) => {
return (
<SelectGroup key={i}>
<SelectItem
// eslint-disable-next-line react/jsx-key
value={String(i)}
>
<AudioOperationOption operation={operation} />
</SelectItem>
</SelectGroup>
);
})}
</SelectContent>
</Select>
);
};
20 changes: 20 additions & 0 deletions packages/convert/app/components/AudioOperationOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {AudioOperation} from '@remotion/webcodecs';
import {renderAudioCodecLabel} from '@remotion/webcodecs/src/codec-id';

export const AudioOperationOption: React.FC<{
readonly operation: AudioOperation;
}> = ({operation}) => {
if (operation.type === 'reencode') {
return renderAudioCodecLabel(operation.audioCodec);
}

if (operation.type === 'copy') {
return 'Copy';
}

if (operation.type === 'drop') {
return 'Drop audio track';
}

throw new Error('Unknown operation type');
};
105 changes: 56 additions & 49 deletions packages/convert/app/components/ConvertForm.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {
ConvertMediaAudioCodec,
ConvertMediaContainer,
ConvertMediaVideoCodec,
} from '@remotion/webcodecs';
import {ConvertMediaContainer} from '@remotion/webcodecs';
import React from 'react';
import {Container} from '~/lib/generate-new-name';
import {AudioCodecSelection} from './AudioCodecSelection';
import {SupportedConfigs} from './get-supported-configs';
import {SelectionSkeleton} from './SelectionSkeleton';
import {VideoTrackLabel} from './TrackSelectionLabels';
import {Checkbox} from './ui/checkbox';
import {Label} from './ui/label';
import {
Expand All @@ -16,39 +15,37 @@ import {
SelectTrigger,
SelectValue,
} from './ui/select';
import {VideoCodecSelection} from './VideoCodecSelection';

export const ConvertForm: React.FC<{
readonly container: ConvertMediaContainer;
readonly setContainer: React.Dispatch<
React.SetStateAction<ConvertMediaContainer>
>;
readonly videoCodec: ConvertMediaVideoCodec;
readonly setVideoCodec: React.Dispatch<
React.SetStateAction<ConvertMediaVideoCodec>
>;
readonly audioCodec: ConvertMediaAudioCodec;
readonly setAudioCodec: React.Dispatch<
React.SetStateAction<ConvertMediaAudioCodec>
>;
readonly flipHorizontal: boolean;
readonly setFlipHorizontal: React.Dispatch<React.SetStateAction<boolean>>;
readonly flipVertical: boolean;
readonly setFlipVertical: React.Dispatch<React.SetStateAction<boolean>>;
readonly supportedConfigs: SupportedConfigs | null;
readonly videoConfigIndex: Record<number, number>;
readonly audioConfigIndex: Record<number, number>;
readonly setAudioConfigIndex: (trackId: number, i: number) => void;
readonly setVideoConfigIndex: (trackId: number, i: number) => void;
}> = ({
container,
setContainer,
setVideoCodec,
videoCodec,
audioCodec,
setAudioCodec,
flipHorizontal,
flipVertical,
setFlipHorizontal,
setFlipVertical,
supportedConfigs,
audioConfigIndex,
setAudioConfigIndex,
videoConfigIndex,
setVideoConfigIndex,
}) => {
const [showAdvanced, setShowAdvanced] = React.useState(false);

console.log(supportedConfigs);

return (
Expand All @@ -69,38 +66,48 @@ export const ConvertForm: React.FC<{
</SelectContent>
</Select>
</div>
<div>
<Label htmlFor="videoCodec">Video codec</Label>
<Select
value={videoCodec}
onValueChange={(v) => setVideoCodec(v as ConvertMediaVideoCodec)}
>
<SelectTrigger id="videoCodec">
<SelectValue placeholder="Select a video codec" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="vp8">VP8</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
<div>
<Label htmlFor="audioCodec">Audio codec</Label>
<Select
value={audioCodec}
onValueChange={(a) => setAudioCodec(a as ConvertMediaAudioCodec)}
>
<SelectTrigger id="audioCodec">
<SelectValue placeholder="Select a audio codec" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="opus">Opus</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
{supportedConfigs ? (
supportedConfigs.videoTrackOptions.map((track) => {
return (
<div key={track.trackId}>
<VideoTrackLabel
trackId={track.trackId}
totalVideoTracks={supportedConfigs.videoTrackOptions.length}
/>
<VideoCodecSelection
index={videoConfigIndex[track.trackId] ?? 0}
setIndex={(i) => {
setVideoConfigIndex(track.trackId, i);
}}
videoOperations={track.operations}
/>
</div>
);
})
) : (
<SelectionSkeleton />
)}
{supportedConfigs ? (
supportedConfigs.audioTrackOptions.map((track) => {
return (
<div key={track.trackId}>
<VideoTrackLabel
trackId={track.trackId}
totalVideoTracks={supportedConfigs.audioTrackOptions.length}
/>
<AudioCodecSelection
index={audioConfigIndex[track.trackId] ?? 0}
setIndex={(i) => {
setAudioConfigIndex(track.trackId, i);
}}
audioTrackOptions={track.operations}
/>
</div>
);
})
) : (
<SelectionSkeleton />
)}
{showAdvanced ? (
<>
<div className="flex flex-row">
Expand Down
44 changes: 29 additions & 15 deletions packages/convert/app/components/ConvertUi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ import {Button} from '@/components/ui/button';
import {CardTitle} from '@/components/ui/card';
import {fetchReader} from '@remotion/media-parser/fetch';
import {webFileReader} from '@remotion/media-parser/web-file';
import {
convertMedia,
ConvertMediaAudioCodec,
ConvertMediaContainer,
ConvertMediaVideoCodec,
} from '@remotion/webcodecs';
import {convertMedia, ConvertMediaContainer} from '@remotion/webcodecs';
import {useCallback, useEffect, useRef, useState} from 'react';
import {ConvertState, Source} from '~/lib/convert-state';
import {getNewName} from '~/lib/generate-new-name';
Expand All @@ -26,13 +21,31 @@ export default function ConvertUI({
readonly supportedConfigs: SupportedConfigs | null;
}) {
const [container, setContainer] = useState<ConvertMediaContainer>('webm');
const [videoCodec, setVideoCodec] = useState<ConvertMediaVideoCodec>('vp8');
const [audioCodec, setAudioCodec] = useState<ConvertMediaAudioCodec>('opus');
const [videoConfigIndex, _setVideoConfigIndex] = useState<
Record<number, number>
>({});
const [audioConfigIndex, _setAudioConfigIndex] = useState<
Record<number, number>
>({});
const [state, setState] = useState<ConvertState>({type: 'idle'});
const [name, setName] = useState<string | null>(null);
const [flipHorizontal, setFlipHorizontal] = useState(false);
const [flipVertical, setFlipVertical] = useState(false);

const setVideoConfigIndex = useCallback((trackId: number, i: number) => {
_setVideoConfigIndex((prev) => ({
...prev,
[trackId]: i,
}));
}, []);

const setAudioConfigIndex = useCallback((trackId: number, i: number) => {
_setAudioConfigIndex((prev) => ({
...prev,
[trackId]: i,
}));
}, []);

const abortSignal = useRef<AbortController | null>(null);

const onClick = useCallback(() => {
Expand Down Expand Up @@ -69,8 +82,9 @@ export default function ConvertUI({
},
});
},
videoCodec,
audioCodec,
// TODO: This should be optional
videoCodec: 'vp8',
audioCodec: 'opus',
container: container as 'webm',
signal: abortController.signal,
fields: {
Expand Down Expand Up @@ -118,7 +132,7 @@ export default function ConvertUI({
return () => {
abortController.abort();
};
}, [src, videoCodec, audioCodec, container, flipHorizontal, flipVertical]);
}, [src, container, flipHorizontal, flipVertical]);

const cancel = useCallback(() => {
if (state.type !== 'in-progress') {
Expand Down Expand Up @@ -206,15 +220,15 @@ export default function ConvertUI({
{...{
container,
setContainer,
setVideoCodec,
videoCodec,
audioCodec,
setAudioCodec,
flipHorizontal,
flipVertical,
setFlipHorizontal,
setFlipVertical,
supportedConfigs,
audioConfigIndex,
videoConfigIndex,
setAudioConfigIndex,
setVideoConfigIndex,
}}
/>
</div>
Expand Down
11 changes: 11 additions & 0 deletions packages/convert/app/components/SelectionSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import {Skeleton} from './ui/skeleton';

export const SelectionSkeleton: React.FC = () => {
return (
<div>
<Skeleton className="h-4 w-[100px] inline-block mt-2" />
<Skeleton className="h-10 w-full block" />
</div>
);
};
24 changes: 24 additions & 0 deletions packages/convert/app/components/TrackSelectionLabels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import {Label} from './ui/label';

export const VideoTrackLabel: React.FC<{
readonly trackId: number;
readonly totalVideoTracks: number;
}> = ({trackId, totalVideoTracks}) => {
if (totalVideoTracks === 1) {
return <Label htmlFor="videoCodec">Video Codec</Label>;
}

return <Label htmlFor="videoCodec">Video Codec for track {trackId}</Label>;
};

export const AudioTrackLabel: React.FC<{
readonly trackId: number;
readonly totalAudioTracks: number;
}> = ({trackId, totalAudioTracks}) => {
if (totalAudioTracks === 1) {
return <Label htmlFor="audioCodec">Audio Codec</Label>;
}

return <Label htmlFor="audioCodec">Audio Codec for track {trackId}</Label>;
};
39 changes: 39 additions & 0 deletions packages/convert/app/components/VideoCodecSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {VideoOperation} from '@remotion/webcodecs';
import React from 'react';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from './ui/select';
import {VideoOperationOption} from './VideoOperationOption';

export const VideoCodecSelection: React.FC<{
readonly videoOperations: VideoOperation[];
readonly index: number;
readonly setIndex: (v: number) => void;
}> = ({videoOperations, index, setIndex}) => {
return (
<Select value={String(index)} onValueChange={(v) => setIndex(Number(v))}>
<SelectTrigger id="videoCodec">
<SelectValue placeholder="Select a video codec" />
</SelectTrigger>
<SelectContent>
{videoOperations.map((operation, i) => {
return (
<SelectGroup key={i}>
<SelectItem
// eslint-disable-next-line react/jsx-key
value={String(i)}
>
<VideoOperationOption operation={operation} />
</SelectItem>
</SelectGroup>
);
})}
</SelectContent>
</Select>
);
};
20 changes: 20 additions & 0 deletions packages/convert/app/components/VideoOperationOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {VideoOperation} from '@remotion/webcodecs';
import {renderVideoCodecLabel} from '@remotion/webcodecs/src/codec-id';

export const VideoOperationOption: React.FC<{
readonly operation: VideoOperation;
}> = ({operation}) => {
if (operation.type === 'reencode') {
return renderVideoCodecLabel(operation.videoCodec);
}

if (operation.type === 'copy') {
return 'Copy';
}

if (operation.type === 'drop') {
return 'Drop video track';
}

throw new Error('Unknown operation type');
};
Loading

0 comments on commit 1005f3d

Please sign in to comment.