How to embed video in HTML

We are going to revise the different options to embed a video in an html resource. We'll start with the use of the HTML5 video player, for streaming progressive videos first and for HLS adaptive bitrate video streaming next. Then we'll take a look at video.js, a powerful open source video player. We'll consider more advanced possibilities to embed videos using iFrames and Oembed links. Finally, we'll see the fastest way to make our own tests with players and formats.

Embed mp4 (and webm) videos in plain HTML

The most straightforward approach to stream video over HTTP is to use the HTML5 video player, and videos encoded in H264 format in a mp4 container.

It's as simple as using the video element tag with the url of the video in the source attribute. Like images, the video element supports multiple sources to allow the browser to pick the best it can play. If we transcode the video using recent standards with higher efficiency but limited support, we may cascade the options from the most to the least efficient, so that the browser picks the best it can reproduce. For instance, we may put H265 at the top of the list, then VP9, and finally as fallback H264 -which is universally supported.

<video width="100%" controls>
  <source src="videoName.mp4" type="video/mp4; codecs=hevc">
  <source src="videoName.webm" type="video/webm; codecs=vp9">
  <source src="videoName.m4v" type="video/mp4">

The video element has a number of attributes (controls, autoplay, loop) that we can use to somewhat customize the appearance and behavior of our video. The simplicity and safety of the HTML5 video player makes it a compelling solution to embed short videos in our web.

However, for videos with a high resolution (over VGA) and even a few seconds long, streaming progressive formats may damage the quality of experience. At high resolutions, bitrates grow rapidly even at average quality, risking to bloat the connection for users in saturated or weak mobile networks. Bloating connections result in reduced page speed, and video stalling and rebuffering.

A bit of javascript, hls.js

To cope with the diversity of connections, we'll need to use an adaptive bitrate video streaming protocol like HLS. In HLS video streaming, instead of a simple video file, we'll have the video transcoded in different renditions with different qualities and split in chunks. We provide the browser with a playlist -tipically with m3u8 extension- detailing the qualities available and then it chooses depending on the current network speed. With HLS we'll have the best possible quality that the network allows, at any time.

We can still use the default HTML5 video player, but in some cases we'll need to add a piece of javascript that checks the network speed and negotiates the quality with the server.

While HLS is supported natively by iOS and Android as well as by Safari in recent macOS versions, important browsers like Chrome, Edge, or Firefox don't support it and need some javascript that implements the protocol. Fortunately, there is a javascript library -hls.js- that does just this for those browsers supporting the Media Source Extensions API.

To stream HLS video with hls.js, we'll have to insert some code like this in our HTML.

<video id="player"></video>
<script src=""></script>
  var video = document.getElementById('player');
  if (Hls.isSupported()) {
    var hls = new Hls({ autoStartLoad: false });
    hls.on(Hls.Events.MEDIA_ATTACHED, function () {
      hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {;
  } else {
    // fallback

A fully custom player, video.js

While the attributes of the HTML5 video player offer some capability to control the behavior and appearance of our video, they're quite basic. If we seek to costumize the video experience for our users, we'll need a javascript viewer.

A great open source option is video.js. It brings a high degree of customization using skins and a flexible configuration, for instance allowing you to use autoplay or different video controls.

Video.js is able to play both progressive videos and HLS streams. Again, the use of HLS requires suport of the Media Source Extensions API, which most browsers do. The code to implement the player may be very simple as the following example shows.

<video id="player" class="video-js vjs-default-skin vjs-big-play-centered" width="100%" controls autoplay muted loop preload>
<script src=""></script>
  const player = videojs('player', {
    responsive: true,
    fluid: true
    src: '',
    type: 'application/x-mpegURL'

Interestingly, video.js also supports the tracking of video-related events (like play or pause actions) so we can include them in our own analytics. For instance, we may include the following code in our player.{
  defaultVideoCategory: 'Video',
  events: [{
    name: 'play',
    label: 'Video-Title',
    action: 'play',
  }, {
    name: 'pause',
    label: 'Video-Title',
    action: 'pause',
  }, {
    name: 'ended',
    label: 'Video-Title',
    action: 'ended',
  }, {
    name: 'error',
    label: 'Video-Title',
    action: 'error',

And we'll find the data collected on the tracked events available in our Google Analytics.

Finally, there is still the option to decouple the visualization of the video from the HTML code of the page where we want to embed it. In this case we create an HTML resource where we have the code of the player and the url of the video. Then we insert this HTML document in the HTML code of the page where we want to embed the video.

If we have direct access to the code of the page we can do it using the HTML5 element iFrame with the source attribute pointing to the url the HTML to embed. For instance,

<div style="position:relative;width:100%;height:0;padding-bottom:56.25%;">
  <iframe src="" style="border:0;top:0;left:0;width:100%;height:100%;position:absolute;" width="1920" height="1080" allowfullscreen></iframe>

Alternatively, we can use oEmbed links to embed the video when we work in a content management system in which we don't want or cannot modify the code of the page, provided the CMS supports oEmbed.

oEmbed allows a CMS to display embedded content (such as photos or videos) just with a link to that resource, without having to parse it directly. In this case the provider of the resource should implement the oEmbed API providing a description of the resource that allows the CMS to fetch the resource. For instance,

  "title":"Abraia Embed Video in HTML Demo",
  "description":"Embed video in html demo using iFrames and oEmbed links",
  "html":"<div style=\"position:relative;width:100%;height:0;padding-bottom:56.25%;\"><iframe src=\"\" style=\"border:0;top:0;left:0;width:100%;height:100%;position:absolute;\" width=\"1920\" height=\"1080\" allowfullscreen></iframe></div>"

How to make your own tests

Abraia tools cover the whole video publishing pipeline from editing, branding, and transcoding to publishing, embedding, and viewing.

You can make tests in Abraia's video optimization console with your own videos and you'll have access to all the intermediate resources. Just log in to Abraia, upload a video and click publish. You will get the link to the published resource. Then you can access the folder generated with the HLS renditions and the HTML code of the viewer.

You may also convert the video to other formats, creating derivatives in the bulk tab of the console.

We've seen the main ways to embed a video in a HTML resource, with examples of code, as well as specific online tools to make your own tests quickly with almost no effort.