> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://uploadcare.com/docs/llms.txt.

# Adaptive bitrate streaming

> Optimize video streaming with Uploadcare to deliver adaptive video quality based on device and connection.

Uploadcare allows optimized video streaming with adaptive bitrate streaming, dynamically adjusting video quality based on the viewer's device capabilities and internet connection speed.

HLS is used as the video delivery protocol, which ensures that end-users always
receive the best possible video quality regardless of the type of device used
and without unnecessary data consumption.

Upload a video file to the server and instantly receive a link to stream the adaptive video.
After processing, the video can be cached like all other files.

## Availability

* Available on all plans
* Enabled by default for new projects
* Existing projects can enable it in project settings
* Requires video upload and processing

> **Tip**
>
> **Tip:** Learn how to enable **Adaptive bitrate streaming** step by step\
> in the new [Optimize videos guide](https://app.uploadcare.com/projects/-/get-started/optimize-video/).

> **Note**
>
> **Note:** Adaptive bitrate streaming is not supported for files stored in AWS S3 buckets.

## How it works

Adaptive bitrate streaming is enabled by default for new projects.\
For existing projects, you can enable it in the [Delivery section](https://app.uploadcare.com/projects/-/settings/#delivery).
The feature will be applied to all video files uploaded to this project.

### uc-video solution

Use [uc-video](https://www.npmjs.com/package/@uploadcare/uc-video) - our solution, powered by Video.js.

Pre-install before starting to work with video:

```sh
npm install @uploadcare/uc-video
```

Connect components from your script file:

```js
import '@uploadcare/uc-video';
import '@uploadcare/uc-video/style'
```

Add component in your application markup:

```html
<uc-video
  cdnCname="https://:subdomain.ucarecd.net/"
  uuid=":UUID"
  controls
  playsinline
  showLogo="false"
/>
```

**Uploadcare parameters:**

* `cdnCname`: Your delivery subdomain. Find it in [Delivery](https://app.uploadcare.com/projects/-/settings/#delivery).
* `uuid`: Unique file identifier assigned when uploading a video.
* `showLogo`: Set to `"false"` to hide the Uploadcare logo.

**Account type:**

* **New projects created after September 4, 2025** use personal delivery subdomains (`*.ucarecd.net`) and must include `cdnCname`.
* **Legacy projects created before September 4, 2025** use the shared `ucarecdn.com` domain, where `cdnCname` is optional (auto-detected).

**Video.js / HTML attributes:**

* `controls`: Display player controls
* `playsinline`: Prevent fullscreen auto-open on iOS

For a complete list of parameters, see the [uc-video package documentation](https://www.npmjs.com/package/@uploadcare/uc-video).

Learn more about delivery domains in [CDN and Proxy domains](/docs/delivery/cdn/).

### JS video player

Use Video.js (an open-source HTML5 player library) or any JS video player that supports HLS.

Pre-install before starting to work with video:

```sh
npm install video-js
```

Then start displaying the video file:

```html
<video id="player" class="video-js" width="720">
    <source src="https://:subdomain.ucarecd.net/:UUID/adaptive_video/" type="application/x-mpegURL" />
</video>
```

`:subdomain` is your project's subdomain. Find it in [Delivery](https://app.uploadcare.com/projects/-/settings/#delivery).

## Video processing settings

Configure codec and resolution settings for your project from the [Delivery section](https://app.uploadcare.com/projects/-/settings/#delivery). These settings apply to all videos in the project.

### Codec selection

For each resolution, you can select **H.264**, **H.265**, or **both**.

**H.264** is the default and provides instant, universal playback. HLS becomes available immediately after upload, and H.264 plays on every device. At least one H.264 rendition is required.

**H.265** offers up to 50% smaller file sizes, but renditions are only available after full processing completes. Browser and device support is also more limited. See [browser compatibility](https://caniuse.com/hevc).

**Both** is the recommended choice for higher resolutions (1440p, 2160p): capable devices get the bandwidth savings of H.265, while everyone else still plays H.264 instantly.

### Resolution selection

Available resolutions: 240p, 360p, 480p, 576p, 720p, 1080p, 1440p, 2160p (4K).

**Default preset:** 360p, 720p, 1080p (H.264 only).

* Minimum 1 resolution must be selected; maximum 8.
* At least one selected resolution must be ≥ 360p.
* No upscaling: if the source resolution is lower than a selected resolution, that resolution is skipped during processing.
* Higher resolutions (1440p, 2160p) incur higher billing costs and longer processing times.

### Frame rate

All renditions are encoded at a constant 29.97 fps, regardless of the source frame rate. Frame rate is not configurable.

* Sources above 30 fps, such as 50 or 60 fps, are reduced to 29.97 fps.
* Sources below 30 fps, such as 24 or 25 fps, are converted to 29.97 fps by repeating frames.

The original file is not modified.

### Source file size and duration

Adaptive bitrate streaming doesn't set its own limit on source file size or duration. Source files are limited only by the project's [maximum upload file size](/docs/moderation/#maximum-file-size).

## Playback speed

If you want to choose the video playback speed, you need to add `playbackRates`:

```js
const player = videojs('player', {
		playbackRates: [0.5, 1, 1.5, 2]
    }
  )
```

An array of numbers strictly greater than 0, where 1 means regular speed (100%), 0.5 means half-speed (50%), 2 means double-speed (200%), etc.
For more information about the vjs-playback-rate video playback rate control, see the [Video.js Options Reference](http://videojs.org).

## Quality selector

### uc-video solution

If you use [uc-video](https://www.npmjs.com/package/@uploadcare/uc-video) solution, the quality selector is already built-in.

### JS video player

If you use a different player, it is also possible to implement a quality selector.

First, install:

```sh
npm install videojs-hls-quality-selector
```

After that import `videojs-hls-quality-selector`:

```js
import videojs from "video.js";
import "video.js/dist/video-js.css";
import 'videojs-hls-quality-selector/dist/videojs-hls-quality-selector.js'
```

```html
<video id="player" class="video-js vjs-default-skin">
    <source src="https://:subdomain.ucarecd.net/:UUID/adaptive_video/" type="application/x-mpegURL">
</video>
```

```js
const player = videojs('player', {
  controls: true,
  playbackRates: [0.5, 1, 1.5, 2],
  plugins: {
    hlsQualitySelector: {
      displayCurrentQuality: true
     }
   }
 }
)
```

Or you can add it differently:

```js
import videojs from "video.js";
import "video.js/dist/video-js.css";
import 'videojs-hls-quality-selector/dist/videojs-hls-quality-selector.js'
```

```html
<video id="player" class="video-js vjs-default-skin">
</video>
```

```js
const player = videojs('player', {
  controls: true,
  html5: {
    hls: {
      overrideNative: true,
    },
    vhs: { overrideNative: true }
  },
  playbackRates: [0.5, 1, 1.5, 2],
  sources: [{
    src: "https://:subdomain.ucarecd.net/:UUID/adaptive_video/",
    type: "application/x-mpegURL"
  }],
  plugins: {
    hlsQualitySelector: {
      displayCurrentQuality: true
     }
   }
 }
)
```

## Signed URLs

Restrict access to video links via [signed URLs](/docs/security/secure-delivery/).

Note that this function works when using a [custom CNAME](/docs/delivery/cdn/#custom-cdn-cname).

An adaptive video isn't a single file: the master HLS playlist at
`/{uuid}/adaptive_video/` references subpaths: per-resolution variant playlists such as
`/{uuid}/adaptive_video/-/variant/720p/` and the underlying video segments. A token
scoped to the exact URL authorizes only the master playlist, so the player receives
`403` responses when it requests the variants and segments.

Sign the whole `adaptive_video/` tree with a wildcard
[ACL](/docs/security/secure-delivery/#authenticated-urls) instead:

```
acl=/{uuid}/adaptive_video/*
```

The trailing `*` matches the master playlist and everything beneath it, so one token
covers the entire stream. Uploadcare appends that same token to the child URLs inside
the playlist, and the player reuses it for every follow-up request.

## Analytics

Check the [Analytics tab](https://app.uploadcare.com/projects/-/analytics/) in the Dashboard for details on CDN traffic and operations performed.

## Billing

* Billing rates vary by codec and resolution. Learn how we charge for [Adaptive bitrate streaming operations](/docs/billing#adaptive-bitrate-streaming).