Video Hosting on AWS

Michael Wittig – 14 Dec 2021

How to embed a video into your website? There is an alternative that looks and feels much more professional than embedding a YouTube video. Read on to learn how to host video-on-demand with the help of Amazon Web Services (AWS).

Video Hosting in AWS

First of all, delivering video content comes with three challenges.

  1. Distributing content around the globe to optimize bandwidth. A user from Europe should not download video files from the Americas.
  2. Adapting the bitrate depending on the device and connectivity. A smartphone with low connectivity cannot stream HD video.
  3. Being compatible with major platforms like iOS, Android, macOS, and Windows. Most devices only support a subset of the available video codecs.

Delivering video-on-demand is challenging!

Alternative to YouTube for video-on-demand

It is not that complicated to embed videos into your website without using YouTube. Combining the following technologies allows you to do so without data privacy implications (YouTube, …) or baseline costs (Vimeo, …).

  • Dash and HLS for adaptive streaming
  • AWS Elemental MediaConvert to transcode videos into Dash and HLS
  • Amazon S3 to store the video files
  • Amazon CloudFront to deliver the content to users all around the world
  • Video.js to embed videos in Dash and HLS to any website

Next, let’s dive into the details.

What is adaptive streaming?

Nowadays, we consume video content in many different situations: while commuting on the train, at home with a big screen, or with the laptop on our lap. The capabilities of the devices we use for this vary greatly. The same applies to the Internet connection and its maximum bandwidth. Therefore, the quality - and thus the bitrate - needs to adapt when streaming a video.

How does adaptive streaming work? A simplified explanation.

  1. Transcode the original video file into multiple video files with different bitrates.
  2. Split the video files into small chunks.
  3. Create a manifest file containing information about the available bitrates and files.

The client will download the manifest file first. Next, the client will decide which bitrate fits best and start downloading the necessary video files on the fly. If necessary, the client can even switch to another bitrate.

There are a handful of standards for adaptive streaming. In our scenario, we rely on two standards.

  • Dynamic Adaptive Streaming over HTTP (Dash)
  • HTTP Live Streaming (HLS)

IOS and macOS support Apple’s HLS out-of-the-box. Most browsers do not support Dash, but Video.js comes with a fallback implementation.

What is AWS Elemental MediaConvert?

But how to generate and transcode all those video files for Dash and HLS? In theory, you can do so on your local machine. But doing so will take some time, as this is a compute intense operation. Luckily, AWS provides a service for that: AWS Elemental MediaConvert, which I will call MediaConvert in the following. MediaConvert outsources the task of transcoding video files to the cloud. To do so, MediaConvert reads and writes media files from and to S3.

MediaConvert transcodes the original video into files for adaptive streaming

Looking for a new challenge?

  • tecRacer

    Cloud Consultant • AWS Migrations

    tecRacer • Premier AWS Consulting Partner • Germany, Austria, Portugal, and Switzerland
    Assessment Transformation Change Management

    Senior Lead Full Stack Developer

    DEMICON • AWS Advanced Consulting Partner • Remote
    AWS JavaScript/TypeScript Angular React

The following steps guide you through generating the HLS and Dash files for a video.

  1. Make sure you have uploaded the original video to S3. For example, s3://cloudonaut-video/input/001.
  2. Open MediaConvert.
  3. Create a new job (HLS).
    1. Open the list of job templates*.
    2. Select System Templates.
    3. Select category OTT-HLS.
    4. Create a new job based on the System-Ott_Hls_Ts_Avc_Aac template.
    5. Choose output destination s3://cloudonaut-video/output/001/
    6. Add input and select the original video file from s3://cloudonaut-video/input/001/
    7. Go to AWS Integration in the Job settings and select IAM role MediaConvertDefaultRole.
    8. Press the Create button to start the job.
  4. Create a new job (Dash).
    1. Open the list of job templates*.
    2. Select System Templates.
    3. Select category OTT-DASH.
    4. Create a new job based on the System-Ott_Dash_Mp4_Avc_Aac template.
    5. Choose output destination s3://cloudonaut-video/output/001/
    6. Add input and select the original video file from s3://cloudonaut-video/input/001/
    7. Go to AWS Integration in the Job settings and select IAM role MediaConvertDefaultRole.
    8. Press the Create button to start the job.
  5. Wait until both jobs succeed.

Next, we need to talk about delivering the video content to your users.

What is CloudFront?

So far, both the original video files and the transcoded video files for adaptive streaming are stored on Simple Storage Service (S3). In theory, users can download the video files directly from S3. However, the files are stored in a single region only - for example, Europe (Ireland). When a user far away from Ireland wants to stream the video, the bandwidth or latency might not be optimal. Therefore, it is a best practice to use a Content Delivery Network (CDN) to distribute the video files all around the globe.

Amazon CloudFront is the CDN provided by AWS. It works with S3 out-of-the-box. When a user streams a video, the browser will send an HTTPS request to a CloudFront edge location nearby. CloudFront will try to answer the request from the local cache. Only when necessary will CloudFront fetch the data from S3.

CloudFront is a Content Delivery Network (CDN) to distribute your video files globally

What is Video.js?

There is only one more building block missing. In theory, HTML5 comes with a built-in video player. But browsers implement all kinds of different standards. Therefore, it is helpful to add a layer of abstraction. Video.js is an open-source HTML5 player framework I have had a perfect experience with. It is crucial to notice that Video.js also includes a fallback implementation if the browser does not support Dash or HLS natively.

So how to embed a video into your website. The following snippet shows a video element referencing an HLS (.m3u8) and Dash (.mpd) manifest file.

<video controls preload="auto" class="video-js">
<source src="/001/video.m3u8" type="application/x-mpegURL">
<source src="/001/video.mpd" type="application/dash+xml">

Also, the following snippet shows the JavaScript to configure the video player. Most important are the configuration parameters for hls. For example, smoothQualityChange tells the player to switch to a lower or higher bitrate when necessary.

document.querySelectorAll('.video-js').forEach(function(element) {
var player = videojs(element, {
controls: true,
autoplay: false,
preload: 'auto',
html5: {
hls: {
limitRenditionByPlayerDimensions: false,
smoothQualityChange: true,
overrideNative: false

How to embed a video into your website?

That’s it. All you need for hosting videos is HLS/Dash, Video.js, and three cloud services provided by AWS:

  • AWS Elemental MediaConvert to transcode the original video file into HLS and Dash video files.
  • S3 to store the original video and the video files ready for adaptive streaming.
  • CloudFront to deliver the content globally.

How does that look and feel in the real world? Check out the following example built with all the technologies discussed above.

Remember, it is not that hard to host videos yourself. YouTube is the obvious choice but comes with privacy implications.

One more thing: there are no baseline costs for the presented solution. MediaConvert, S3, and CloudFront are billed per usage. So you only pay for what you use. And let’s be honest, your company’s image video will most likely not go viral.

Become a cloudonaut supporter

Michael Wittig

Michael Wittig ( Email, Twitter, or LinkedIn )

We launched the cloudonaut blog in 2015. Since then, we have published 360 articles, 50 podcast episodes, and 48 videos. It's all free and means a lot of work in our spare time. We enjoy sharing our AWS knowledge with you.

Please support us

Have you learned something new by reading, listening, or watching our content? With your help, we can spend enough time to keep publishing great content in the future. Learn more

Amount must be a multriply of 5. E.g, 5, 10, 15.

Thanks to Alan Leech, Alex DeBrie, ANTHONY RAITI, Christopher Hipwell, Jaap-Jan Frans, Jason Yorty, Jeff Finley, Jens Gehring, jhoadley, Johannes Grumböck, Johannes Konings, John Culkin, Jonas Mellquist, Juraj Martinka, Kamil Oboril, Ken Snyder, Markus Ellers, Ross Mohan, Ross Mohan, sam onaga, Satyendra Sharma, Shawn Tolidano, Simon Devlin, Thorsten Hoeger, Todd Valentine, Victor Grenu, and all anonymous supporters for your help! We also want to thank all supporters who purchased a cloudonaut t-shirt.