Last updated: November 20, 2024

<span aria-hidden="true" id="guide-to-encoding-videos-for-streaming-with-transloadit"></span>

# Guide to encoding videos for streaming with Transloadit

![Tyler McAllister](/assets/images/teammates/tyler.png?dpl=dpl_AsMTCxwVXNuJ5TmdPevSCe63JuJo)

**Tyler McAllister**

Technical Writer · Trondheim, Norway · Show bio

Like us at Transloadit, you are probably a fan of streaming services 🎥 But have you ever considered starting your own? Our [/video/adaptive](/docs/robots/video-adaptive.md) Robot has you covered in case you did have a wild idea like that! You can use this Robot to encode`mp4` or `webm` video to either HLS (HTTP Live Streaming) or MPEG-DASH.

In this blog post, we'll walk you through the process of creating a basic proof-of-concept adaptive player in React that supports streaming HLS, MPEG-DASH, or MP4 video, depending on the compatibility of the browser, in a similar vein to[one of our JavaScript demos](/demos/video-encoding/compatibility-in-2018.md).

![The Guide to encoding videos for streaming with Transloadit](/_next/static/immutable/media/opengraph-image.079a7rzxmn3qr.png)

<span aria-hidden="true" id="what-are-hls-and-mpeg-dash"></span>

## What are HLS and MPEG-DASH?

Before we get started, let's clarify what HLS and MPEG-Dash are exactly. Both are streaming protocols that split up video data into small chunks that can be downloaded to a device over HTTP. But which format should you choose? HLS may seem like the go-to option since it's the most widely supported, especially on Apple devices (since they are its creators). The downside to HLS is that it only supports its own DRM, so providing heavy-duty protection can be a bit more complicated.

MPEG-DASH, on the other hand, is an open-source standard. It can also benefit users who want to use their data efficiently, as it allows video quality to be switched on the fly. The downside to MPEG-DASH is that relatively few browsers — and none of the iOS devices — support it.

For this walkthrough, we'll encode to both formats, and use them to work with an adaptive video player.

<span aria-hidden="true" id="storing-our-files-via-assembly"></span>

## Storing our files via Assembly

We can jump straight into the Assembly below for an overview of how to use theRobot.

```json
{
  "steps": {
    ":original": {
      "robot": "/upload/handle"
    },
    "hls-encode": {
      "use": ":original",
      "robot": "/video/encode",
      "ffmpeg_stack": "{{stacks.ffmpeg.recommended_version}}",
      "preset": "hls-720p"
    },
    "dash-encode": {
      "use": ":original",
      "robot": "/video/encode",
      "ffmpeg_stack": "{{stacks.ffmpeg.recommended_version}}",
      "preset": "dash-720p-video"
    },
    "thumbnailed": {
      "use": "hls-encode",
      "robot": "/video/thumbs",
      "result": true,
      "ffmpeg_stack": "{{stacks.ffmpeg.recommended_version}}"
    },
    "hls-adaptive": {
      "use": {
        "steps": ["hls-encode"],
        "bundle_steps": true
      },
      "robot": "/video/adaptive",
      "ffmpeg_stack": "{{stacks.ffmpeg.recommended_version}}",
      "playlist_name": "my_playlist.m3u8",
      "segment_duration": 6,
      "closed_captions": false,
      "technique": "hls"
    },
    "dash-adaptive": {
      "use": {
        "steps": ["dash-encode"],
        "bundle_steps": true
      },
      "robot": "/video/adaptive",
      "ffmpeg_stack": "{{stacks.ffmpeg.recommended_version}}",
      "playlist_name": "my_playlist.mpd",
      "segment_duration": 6,
      "technique": "dash"
    },
    "export-plain": {
      "use": ["thumbnailed", "dash-encode"],
      "robot": "/google/store",
      "credentials": "stream-test",
      "acl": "public-read",
      "path": "stream-videos/${file.name}"
    },
    "export-hls": {
      "use": "hls-adaptive",
      "robot": "/google/store",
      "credentials": "stream-test",
      "acl": "public-read",
      "path": "stream-videos/hls-video/${file.name}"
    },
    "export-dash": {
      "use": "dash-adaptive",
      "robot": "/google/store",
      "credentials": "stream-test",
      "acl": "public-read",
      "path": "stream-videos/dash-video/${file.name}"
    }
  }
}

```

Don't let the size of these Assembly Instructions worry you. Let's break it down.

In the first Step, the [/upload/handle](/docs/robots/upload-handle.md) Robot's usage is clear. We utilize it to get a video from an end-user.

Secondly, the [/video/encode](/docs/robots/video-encode.md) Robot encodes the uploaded video into HLS and MPEG-DASH at the `hls-encode` and `dash-encode` Steps, respectively. These are necessary Steps for the[/video/adaptive](/docs/robots/video-adaptive.md) Robot.

Thirdly, since we're going to be working with a video player, it would be useful if we could easily extract a thumbail from our video. Luckily, that's exactly what the[/video/thumbs](/docs/robots/video-thumbs.md) Robot is doing at the `thumbnailed` Step ✨

Now we reach the star of the show - the [/video/adaptive](/docs/robots/video-adaptive.md) Robot. In the Assembly, we have split its tasks up into two separateSteps: `hls-adaptive` and `dash-adaptive`. Let's take a look at the parameters thisRobot is given. They take their respective encoded videos and generate a `.m3u8` and`.mpd` playlist. MPEG-DASH and HLS protocol files are composed of a **playlist** (*.m3u8* or *.mpd*) and a sequence of **segments**. The playlist file simply looks for the associated segments necessary for streaming the video and plays through them sequentially.

Using `segment_duration`, we can define the maximum amount of time each segment of the streaming video will have. This can be an important thing to consider when thinking about your user's data and download capacity. Another quirk of these protocols is that we need to make sure their segments are always in the same directory as their playlist, otherwise the playlists will be looking for segments they can't find. Thankfully, at the last overall Step, the[/google/store](/docs/robots/google-store.md) Robot sets the path for the MPEG-DASH and HLS files to a defined path like - `stream-videos/dash-video/${file.name}`. This means that everything should be bunched together nicely. Just be sure to set up `store.object.create` [permissions](/docs/robots/google-store.md) in your Bucket. We also store the`.mp4` video and thumbnail using the same Robot.

<span aria-hidden="true" id="a-proof-of-concept-via-react"></span>

## A proof of concept via React

[Griffith⁠](https://github.com/zhihu/griffith) is a video player for React that is very easy to get started with. It takes props containing the properties of the player and an object `sources`consisting of the URL of the video along with its format.

```javascript
var sources = {
  hd: {
    bitrate: 905,
    size: 10105235,
    duration: 0,
    width: 1280,
    height: 720,
    play_url: 'https://storage.googleapis.com/yourbucket/streamvideos/hls-video/my_playlist.m3u8',
  },
}

```

We can detect the browser's compatibility with MPEG-DASH and HLS by using the following code:

```javascript
function checkCompatibility() {
  var compatibility = document.createElement('video')
  if (compatibility.canPlayType('application/x-mpegURL')) {
    return build_sources('m3u8', 'my_playlist')
  }
  if (compatibility.canPlayType('application/dash+xml')) {
    return build_sources('mpd', 'my_playlist')
  }
  if (compatibility.canPlayType('video/mp4')) {
    return build_sources('mp4', 'my_playlist')
  } else {
    console.log('No compatible video found')
  }
}

```

You can find my basic implementation[here⁠](https://github.com/mcallistertyler95/video-adaptive-blogpost-tutorial). The[/video/adaptive](/docs/robots/video-adaptive.md) Robot really does streamline the generation of streaming media. As people consume more videos over the internet, we're confident that this Robot could prove to be a useful utility for those looking for a simple and sleek solution.

For further reading, our demo:[Make video compatible for all devices](/demos/video-encoding/compatibility-in-2018.md) may interest you as it illustrates how to mix and match this with other formats, depending on what the playback device supports, and provides sample code for a non-React player: [Plyr⁠](https://plyr.io/).

[#video-encoding-service](/blog/tags/video-encoding-service.md)[#video-adaptive-robot](/blog/tags/video-adaptive-robot.md)[#assembly](/blog/tags/assembly.md)[#walkthrough](/blog/tags/walkthrough.md)[#google-store-robot](/blog/tags/google-store-robot.md)[#video-thumbs-robot](/blog/tags/video-thumbs-robot.md)[#upload-handle-robot](/blog/tags/upload-handle-robot.md)[#video-encode-robot](/blog/tags/video-encode-robot.md)

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed

Cancel anytime
