-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
149 changed files
with
7,927 additions
and
2,767 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"extends": ["@jonny/eslint-config/react"], | ||
"rules": { | ||
"no-console": "error", | ||
"react/function-component-definition": "off", | ||
"react/require-default-props": "off", | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
node_modules | ||
|
||
/.cache | ||
build | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# @remotion/convert | ||
|
||
Video conversion tool - convert.remotion.dev | ||
|
||
[![NPM Downloads](https://img.shields.io/npm/dm/@remotion/convert.svg?style=flat&color=black&label=Downloads)](https://npmcharts.com/compare/@remotion/convert?minimal=true) | ||
|
||
## Installation | ||
|
||
```bash | ||
npm install @remotion/convert --save-exact | ||
``` | ||
|
||
When installing a Remotion package, make sure to align the version of all `remotion` and `@remotion/*` packages to the same version. | ||
Remove the `^` character from the version number to use the exact version. | ||
|
||
## Usage | ||
|
||
See the [documentation](https://convert.remotion.dev) for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type {AudioTrack} from '@remotion/media-parser'; | ||
import {Table, TableBody, TableCell, TableRow} from './ui/table'; | ||
|
||
export const AudioTrackOverview: React.FC<{ | ||
readonly track: AudioTrack; | ||
}> = ({track}) => { | ||
return ( | ||
<Table> | ||
<TableBody> | ||
<TableRow> | ||
<TableCell colSpan={3}>Type</TableCell> | ||
<TableCell className="text-right">Audio</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Codec</TableCell> | ||
<TableCell className="text-right"> | ||
{track.codecWithoutConfig} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>WebCodecs Codec String</TableCell> | ||
<TableCell className="text-right">{track.codec}</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Channels</TableCell> | ||
<TableCell className="text-right">{track.numberOfChannels}</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Sample Rate</TableCell> | ||
<TableCell className="text-right">{track.sampleRate}</TableCell> | ||
</TableRow> | ||
</TableBody> | ||
</Table> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import {Table, TableBody, TableCell, TableRow} from '@/components/ui/table'; | ||
import type { | ||
Dimensions, | ||
MediaParserAudioCodec, | ||
MediaParserVideoCodec, | ||
ParseMediaContainer, | ||
} from '@remotion/media-parser'; | ||
import React from 'react'; | ||
import {formatBytes} from '~/lib/format-bytes'; | ||
import {Skeleton} from './ui/skeleton'; | ||
|
||
const formatSeconds = (seconds: number) => { | ||
const minutes = Math.floor(seconds / 60); | ||
const secondsLeft = seconds % 60; | ||
|
||
return `${minutes}:${secondsLeft < 10 ? '0' : ''}${Math.round(secondsLeft)} min`; | ||
}; | ||
|
||
export const ContainerOverview: React.FC<{ | ||
readonly dimensions: Dimensions | null; | ||
readonly durationInSeconds: number | null; | ||
readonly videoCodec: MediaParserVideoCodec | null; | ||
readonly audioCodec: MediaParserAudioCodec | null; | ||
readonly size: number | null; | ||
readonly fps: number | null | undefined; | ||
readonly container: ParseMediaContainer | null; | ||
}> = ({ | ||
container, | ||
dimensions, | ||
videoCodec, | ||
durationInSeconds, | ||
audioCodec, | ||
size, | ||
fps, | ||
}) => { | ||
return ( | ||
<Table> | ||
<TableBody> | ||
<TableRow> | ||
<TableCell colSpan={3}>Size</TableCell> | ||
<TableCell className="text-right"> | ||
{size === null ? ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
) : ( | ||
<>{formatBytes(size)}</> | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Container</TableCell> | ||
<TableCell className="text-right"> | ||
{container ? ( | ||
<>{String(container)}</> | ||
) : ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Duration</TableCell> | ||
<TableCell className="text-right"> | ||
{durationInSeconds === null ? ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
) : ( | ||
<>{formatSeconds(durationInSeconds)}</> | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Dimensions</TableCell> | ||
<TableCell className="text-right"> | ||
{dimensions === null ? ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
) : ( | ||
<> | ||
{dimensions.width}x{dimensions.height} | ||
</> | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Frame Rate</TableCell> | ||
<TableCell className="text-right"> | ||
{fps === undefined ? ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
) : fps ? ( | ||
<>{fps} FPS</> | ||
) : ( | ||
'N/A' | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Video Codec</TableCell> | ||
<TableCell className="text-right"> | ||
{videoCodec === null ? ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
) : ( | ||
videoCodec | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
<TableRow> | ||
<TableCell colSpan={3}>Audio Codec</TableCell> | ||
<TableCell className="text-right"> | ||
{audioCodec === null ? ( | ||
<Skeleton className="h-3 w-[100px] inline-block" /> | ||
) : ( | ||
audioCodec | ||
)} | ||
</TableCell> | ||
</TableRow> | ||
</TableBody> | ||
</Table> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import {Button} from '@/components/ui/button'; | ||
import {CardContent, CardTitle} from '@/components/ui/card'; | ||
import {Label} from '@/components/ui/label'; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectGroup, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from '@/components/ui/select'; | ||
import {convertMedia} from '@remotion/webcodecs'; | ||
import {useCallback, useState} from 'react'; | ||
import {Badge} from './ui/badge'; | ||
|
||
export default function ConvertUI({src}: {readonly src: string}) { | ||
const [abortController] = useState<AbortController>( | ||
() => new AbortController(), | ||
); | ||
|
||
const [container, setContainer] = useState('webm'); | ||
const [videoCodec, setVideoCodec] = useState('vp8'); | ||
const [audioCodec, setAudioCodec] = useState('opus'); | ||
|
||
const onClick = useCallback(async () => { | ||
await convertMedia({ | ||
src, | ||
onVideoFrame: () => { | ||
// console.log('frame', frame); | ||
return Promise.resolve(); | ||
}, | ||
onMediaStateUpdate: () => { | ||
// console.log('update', s); | ||
}, | ||
videoCodec: videoCodec as 'vp8', | ||
audioCodec: audioCodec as 'opus', | ||
to: container as 'webm', | ||
signal: abortController.signal, | ||
}); | ||
}, [abortController.signal, src, container, videoCodec, audioCodec]); | ||
|
||
return ( | ||
<div className="w-[380px]"> | ||
<CardContent className="gap-4"> | ||
<div className="grid w-full items-center gap-4"> | ||
<div className="flex flex-row"> | ||
<CardTitle>Convert video</CardTitle> | ||
<div className="w-2" /> | ||
<Badge variant={'default'}>Alpha</Badge> | ||
</div> | ||
<div> | ||
<Label htmlFor="container">Container</Label> | ||
<Select value={container} onValueChange={setContainer}> | ||
<SelectTrigger id="container"> | ||
<SelectValue placeholder="Select a container" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectGroup> | ||
<SelectItem value="webm">WebM</SelectItem> | ||
</SelectGroup> | ||
</SelectContent> | ||
</Select> | ||
</div> | ||
<div> | ||
<Label htmlFor="videoCodec">Video codec</Label> | ||
<Select value={videoCodec} onValueChange={setVideoCodec}> | ||
<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={setAudioCodec}> | ||
<SelectTrigger id="audioCodec"> | ||
<SelectValue placeholder="Select a audio codec" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectGroup> | ||
<SelectItem value="opus">Opus</SelectItem> | ||
</SelectGroup> | ||
</SelectContent> | ||
</Select> | ||
</div> | ||
</div> | ||
<div className="h-4" /> | ||
<Button className="block w-full" type="button" onClick={onClick}> | ||
Convert | ||
</Button> | ||
</CardContent> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.