# Video Tasks
[View original](https://ittybit.com/docs/video)
## Required props
As with all [Tasks](/docs/tasks), you must provide:
* either a `file_id` or a `url` to use as the input file
* the `kind` of task to create
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
}
// Pass options to an SDK or API request e.g:
const task = await ittybit.tasks.create(options);
```
***
### File ID
The `file_id` should be the unique ID of a file in your project's [Files](/docs/files) collection.
e.g. `"file_id": "file_abcdefgh1234"`
***
### URL
The `url` should be the URL of the video file to process.
This should be a publicly accessible or signed URL.
e.g. `"url": "https://example.com/video.mp4"`
***
### Kind
For video tasks, this is always `video`.
e.g. `"kind": "video"`
***
## Default settings
If you don't specify any options, the default task will create a new video file with the following settings:
| Setting | Default Value |
| ----------- | --------------------------------------- |
| Width | Same as input file |
| Height | Same as input file |
| Frame Rate | Same as input file, where possible [^1] |
| Video Codec | `h264` |
| Audio Codec | `aac` |
| Container | `mp4` |
| Bitrate | Auto-selected for quality/size balance |
| Duration | Full video (no trimming) |
| Overlays | None |
If you just want to normalise uploaded videos for web playback, this is a reasonable set of defaults.
We always place the [moov atom](https://developer.apple.com/documentation/quicktime-file-format/movie_atom) to the start of output files, as this enables `preload="metadata"` and helps with playback issues on some devices.
***
## Shared options
All tasks support the following *(optional)* props:
* `filename`
* `folder`
* `ref`
See the [Tasks](/docs/tasks) documentation for more information on these options.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
folder: "uploads/user123",
filename: "intro-20250101.mp4"
}
```
***
## Video options
Video tasks support a number of optional properties, which are used to control the output video.
If you want to go wild you can create a video with a custom width, height, fit, position, background, fps, format, start, and end ... then add some overlays.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
width: 720,
height: 1280,
fit: 'contain',
position: 'center',
background: '#20B075',
fps: 30,
format: 'mp4',
quality: 80,
start: 0,
end: 10,
layers: [
{
kind: 'image',
url: 'https://example.com/image.png',
position: 'bottom right',
width: 100,
height: 100,
},
{
kind: 'text',
text: 'Hello, world!',
font: 'Inter',
font_size: 32,
color: '#FFFFFF',
position: 'bottom left',
},
],
}
const task = await ittybit.tasks.create(options);
```
***
### Width
The width of the video to encode in pixels or as a percentage of the input file. [^2]
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
width: 720, // or e.g. "50%"
}
```
If you specify a percentage, the output file's width will be relative to the input file's width. For example, if the input file is 1920x1080, and you specify `"width": "50%"`, the output file will be 960px wide.
***
### Height
The height of the video to encode in pixels or as a percentage of the input file.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
height: 1280, // or e.g. "50%"
}
```
If you specify a percentage, the output file's height will be relative to the input file's height. For example, if the input file is 1920x1080, and you specify `"height": "50%"`, the output file will be 540px tall.
***
### Fit
How the video should be scaled to fit the width and height.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
width: 720,
height: 1280,
fit: 'contain',
}
```
Available fits are:
* `fill`: (default) This will stretch the video to fit the width and height values given, even if that changes the aspect ratio and distorts the video.
* `cover` - This will scale the video up to cover the width and height given. Therefore, the output video may be cropped but it will retain the original aspect ratio.
* `contain` - This will scale the video down to fit the width and height given. Therefore the output video may have extra empty padding but the aspect ratio will be preserved.
If only one of width or height is specified, the other will be calculated to maintain the original aspect ratio and `fit` will be ignored.
***
### Position
Used in conjunction with `fit: cover` or `fit: contain`, this will specify the position of the video within the width and height.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
width: 720,
height: 1280,
fit: 'contain',
position: 'top left',
}
```
Available positions are:
* `center`: (default) The video will be scaled to fit the width and height, and then centered within the output frame.
* `top` | `bottom`: The video will be placed against the top or bottom of the output frame, and centered horizontally (same as passing `top center` or `bottom center`).
* `left` | `right`: The video will be placed against the left or right of the output frame, and centered vertically (same as passing `center left` or `center right`).
* `top left` | `top right` | `bottom left` | `bottom right`: The video will be placed against both edges specified.
If only one of width or height is specified, the other will be calculated to maintain the original aspect ratio. Then `position` will have no effect and will be ignored.
***
### Background
Used in conjunction with `fit: contain`, this will specify the color used to fill any extra space in the output frame.
The background color is specified as a hex color.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
width: 720,
height: 1280,
fit: 'contain',
background: '#20B075',
}
```
If not specified, the background will be black (hex color: `#000000`).
If only one of width or height is specified, or any value other than `fit: contain` is passed in, then `background` will have no effect and will be ignored.
***
### FPS
The frame rate of the output video in frames per second. The value should be a number (integer or float) between 1 and 60.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
fps: 30,
}
```
If not specified, the frame rate will be the same as the input file.
If the input file has a frame rate that is not supported by the output format, the frame rate will be converted to the nearest supported value.
If you require more granular control over output frame rates, please [contact us](/support) and we can activate on an org-by-org basis.
***
### Format
The format of the video to encode. Shorthand for `container` and `codec`.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
format: 'mp4',
}
```
Available formats are:
* `mp4` (shorthand for `"container": "mp4", "codec": "h264"`)
* `webm` (shorthand for `"container": "webm", "codec": "vp9"`)
***
### Codec
The codec of the output video.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
codec: 'h264',
}
```
Available codecs are:
* `h264` (audio will use `aac` audio codec)
* `vp9` (audio will use `opus` audio codec)
If you require `hevc`, `av1`, or other codec support, please [contact us](/support) and we can activate on an org-by-org basis.
***
### Container
The container of the output video.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
codec: 'h264',
container: 'mp4',
}
```
Available containers are:
* `mp4`
* `webm`
Whilst you can technically specify a `vp9` codec inside an `mp4` container, or `h264` codec inside a `webm` container, these files are not supported by all players.
***
### Quality
The desired quality of the output video. This is a number between 1 and 100, and it's a relative scale to the input file's quality.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
quality: 80,
}
```
Default is `80`, which balances quality and filesize.
***
### Start
From where in the video to start encoding in seconds.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
start: 10.0,
}
```
If not specified, the video will start at the beginning of the input file.
If your value is greater than the input file duration, the task will fail.
***
### End
Where in the video to stop encoding in seconds.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
end: 30.0,
}
```
If not specified, the video will be encoded to the end of the input file.
If your value is greater than the input file duration, the output file will stop at the end of the input file.
***
### Duration
The duration of the output video in seconds. An alternative to `end`.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
duration: 20.0,
}
```
If not specified, the video will be encoded to the end of the input file.
If your value is greater than the input file duration, the output file will stop at the end of the input file.
You can combine `start` and `end`, `start` and `duration`, or `end` and `duration` props. This gives you a lot of flexibility to output a specific segment of the input file.
***
### Layers
Layers are used to add text and image overlays to the output video. The layers prop accepts an array of layer objects.
```js
const options = {
url: 'https://example.com/video.mp4',
kind: 'video',
layers: [
{
kind: 'image',
url: 'https://example.com/logo.png',
position: 'top left',
width: 100,
height: 100,
},
{
kind: 'text',
text: '@exampleusername',
font: 'Inter',
font_size: 32,
color: '#FFFFFF',
position: 'bottom right',
},
],
}
```
*Note: we're adding a complete guide to layers, packed with visual examples, soon. If you'd like to see an early preview, please [contact us](/support) and we'd be happy to show you a draft.*
***
## Supported Inputs
Input files can contain:
| Property | Values |
| ------------------ | -------------------------------------------- |
| Video Stream Codec | `h264/avc`, `h265/hevc`, `vp8`, `vp9`, `av1` |
| Audio Stream Codec | `aac`, `opus`, `mp3`, `flac`, `vorbis` |
| Media Container | `mp4`, `webm`, `mov`, `avi`, `mkv` |
***
## Limits
Output files can be:
* upto `4096px` on the longest edge
* upto `16MP` in total pixels
* upto `4 hours` in duration
* upto `4TB` in size
***
## Guides
... are coming soon!
***
[^1]: h264 has different profiles, each with different limitations on the resolution and frame rates supported (see [Levels](https://en.wikipedia.org/wiki/Advanced_Video_Coding#Levels)). We default to `High` profile at `Level 4.1`, for the broadest compatibility (see, for example, [Apple Authoring Guidelines for Video](https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices) or [Google TV support](https://developers.google.com/cast/docs/media#google_tv_streamer)). If the requested dimensions or framerate require, and the input file supports it, we can use upto `High` profile at `Level 5.2` (supports 4k\@60fps). *If you require a different profile, please [contact us](/support) and we can activate it on an org-by-org basis.*
[^2]: It's not a hard and fast rule, but ideally your output video dimensions should be a multiple of 16. This is because h264 and vp9 codecs use 16x16 pixel blocks to encode the video, and it's (one of the reasons) why digital TV resolutions are 1280x720, 1920x1080, 3840x2160, etc.