<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ VideoJS - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ VideoJS - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 24 Aug 2026 19:20:34 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/videojs/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ HLS Video Streaming: What it is, and When to Use it ]]>
                </title>
                <description>
                    <![CDATA[ By Anton Garcia Diaz In this short article I will focus on HLS, the most extended adaptive bitrate protocol for video delivery. I'll answer some of the main questions that anyone considering HLS for the first time will likely ask: what it is, when to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-hls-and-when-to-use-it/</link>
                <guid isPermaLink="false">66d45da33dce891ac3a967b0</guid>
                
                    <category>
                        <![CDATA[ Adaptive Bitrate ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hls ]]>
                    </category>
                
                    <category>
                        <![CDATA[ media ]]>
                    </category>
                
                    <category>
                        <![CDATA[ video ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Video.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ VideoJS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 18 Dec 2019 22:59:12 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/12/HLS-video.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Anton Garcia Diaz</p>
<p>In this short article I will focus on HLS, the most extended adaptive bitrate protocol for video delivery. I'll answer some of the main questions that anyone considering HLS for the first time will likely ask: what it is, when to use it, and how to use it. </p>
<p>To help along the way, I will show some examples using <a target="_blank" href="https://abraia.me/video/">an online video publishing tool</a> that you can freely use to test out the performance of HLS on your own.</p>
<h2 id="heading-what-is-hls-and-how-does-it-work">What is HLS and how does it work?</h2>
<p>HLS is a protocol defined by Apple to implement an adaptive bitrate streaming format that can be supported on their devices and software. Over the time, it has gained widespread support. </p>
<p>The most important feature of HLS is its ability to adapt the bitrate of the video to the actual speed of the connection. This optimizes the quality of the experience. </p>
<p>HLS videos are encoded in different renditions at different resolutions and bitrates. This is usually referred to as the bitrate ladder. When a connection gets slower, the protocol automatically adjusts the requested bitrate to the bandwidth available. </p>
<p>Compared to progressive videos, HLS avoids re-buffering and stalling effects as well as bloating the client connection. We can see it at work in this video.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/HLS-video/HLS_video-at-work/index.html">https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/HLS-video/HLS_video-at-work/index.html</a></div>
<p>In essence, HLS provides a much better user experience when we use video content in our apps or sites.</p>
<p>It has native support in iOS and Android. It is also supported by Safari, and by using some JavaScript it is supported in all the main browsers (Chrome, Firefox, Edge). While using HLS requires some effort, it's not a big deal. </p>
<p>Let's see when we should use it and how.</p>
<h2 id="heading-when-should-we-use-hls">When should we use HLS?</h2>
<p>There are cases where videos are not that heavy. For instance, you could have a sequence of images encoded as a 1-2 seconds video, with a weight of less than 1 MB. In this case, a progressive video – that can be consumed, like an image, using plain HTML5 – is for sure the best option. HLS does not offer any advantage here.</p>
<p>But, HLS does make sense when we want to deliver high resolution videos (HD or over) with a weight over 3MB. This type of content may kill our web UX when viewed on an average mobile connection. </p>
<p>It's worth noting that this is the case in an increasing amount of media content, including many short videos of less than 20 seconds used in ecommerce and marketing contexts. In the example at the beginning of the post, we have a full HD video of only 9 seconds that weights in at over 6MB.</p>
<h2 id="heading-how-can-we-use-hls-in-our-sites">How can we use HLS in our sites?</h2>
<p>To use HLS we have to address a number of aspects. I'll focus on two important points:  </p>
<ul>
<li>the need to encode the video, and, </li>
<li>the need to embed it in our page. </li>
</ul>
<p>For a more comprehensive view on what a general video publishing pipeline entails, you may check out <a target="_blank" href="https://www.freecodecamp.org/news/short-videos-in-web-and-ecommerce-workflows/">this post</a>.</p>
<h3 id="heading-hls-encoding">HLS encoding</h3>
<p>We can encode videos in HLS in-house or by using a third party service. To build an in-house encoder, the best option is to use FFMPEG, a powerful open source library for video processing and encoding. In this case, we should analyse the content we are going to encode and set a number of parameters. </p>
<p>In HLS we should define a bitrate ladder (the bitrates and resolutions of each step) and the length of chunks. When we encode a video, we end with a set of playlists and chunks. Typically, we end the former with .m3u8 and the latter with .ts extensions. We can see an example in the next image.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/imaxe.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We can see one master playlist, one additional playlist per rendition, and all the chunks of each rendition. The master playlist specifies the bitrate ladder and the relative path to each rendition.</p>
<p>Apple makes a generic recommendation specifying the bitrate ladder and a chunk duration of 10 seconds.  However, this is not very useful for many types of content, like the short videos common in ecommerce and marketing. </p>
<p>In fact, the best approach is to tune the bitrate ladder specifically to the content of the video. In this case, if you want to make the most of HLS and you're not expert in encoding, a third party service providing per-title encoding (with HLS) is likely the right choice.</p>
<h2 id="heading-hls-players">HLS players</h2>
<p>Here, we find two main options. We can stick to the HTML5 player or we can use one implemented in JavaScript.</p>
<h3 id="heading-html5-player">HTML5 player</h3>
<p>Recent Safari versions support HLS. In this case, you may use HLS playlists in the same manner as progressive videos. With other browsers, you may use a tiny JavaScript library to implement the HLS protocol and again use the HTML5 player for progressive videos. </p>
<p>This can be done with HLS.js. This library just implements the negotiation of renditions, based on the available bandwidth. Support is almost universal, only conditional on the support of the media element's API.</p>
<h3 id="heading-javascript-player">JavaScript Player</h3>
<p>In case we need to customise the video experience – which is pretty common in marketing and stories pages – then we need to use something other than the default HTML5 player. </p>
<p>While there are many commercial options out there, Video.js is a good choice. It's an open source player that supports a high degree of customization, including different skins and controls. </p>
<p>A player like Video.js also supports the tracking of video-related events (like play or pause actions) so we can include them in our own analytics. In fact, including these data in our Google Analytics is really easy.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/imaxe-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>GA data for events tracked in a video viewed with a Video.js player</em></p>
<h2 id="heading-summary">Summary</h2>
<p>I've tackled the first questions about HLS that most potential users will have: what it is, and when we should use it.</p>
<p>While a video publishing pipeline reliant on HLS can be implemented and deployed in-house with open source tools like FFMPEG and video.js, it may be a good idea to use a <a target="_blank" href="https://abraia.me/video/">video publishing service</a> if you're not an expert in the tech. They bring advanced features like per-title encoding, take care of all the hard work, and let us focus on our customization needs.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to deploy a complete video publishing pipeline for web and ecommerce ]]>
                </title>
                <description>
                    <![CDATA[ By Anton Garcia Diaz From ffmpeg and cloud video transcoding to HLS, delivery, players, Video.js, and analytics. After the conquest of social networks, video is spreading through web businesses. As a media consultant working for several of the larges... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/short-videos-in-web-and-ecommerce-workflows/</link>
                <guid isPermaLink="false">66d45d9f3a8352b6c5a2aa03</guid>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hls ]]>
                    </category>
                
                    <category>
                        <![CDATA[ publishing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[  #Transcoding  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ video ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Video.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ VideoJS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 13 Nov 2019 08:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/Video-Publishing-Demo.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Anton Garcia Diaz</p>
<p><em>From ffmpeg and cloud video transcoding to HLS, delivery, players, Video.js, and analytics.</em></p>
<p>After the conquest of social networks, video is spreading through web businesses. As a media consultant working for several of the <a target="_blank" href="https://www.similarweb.com/top-websites/category/lifestyle/fashion-and-apparel">largest fashion ecommerce sites</a> in the world, I feel safe saying the video-everywhere trend is all but unstoppable.  </p>
<p>In this post, I review the main aspects to consider when publishing short-format videos in a web workflow. I comment about open source resources that make an in-house solution possible for each step, like ffmpeg or Video.js. Besides, I use an example with <a target="_blank" href="https://abraia.me/video/">Abraia's video optimization and publishing demo</a> - specially tailored to short videos for fashion ecommerce. </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Short-Video-Publishing-Demo/Workflow/index.html">https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Short-Video-Publishing-Demo/Workflow/index.html</a></div>
<p>It gives full access to the resources created: chunks, playlists, and html code for the video player. This brings quick insights on the inner workings of a complete pipeline. </p>
<p>The content should be helpful either to pursue an in-house processing and publishing pipeline or to sort out the best combination of services. </p>
<h2 id="heading-quality-of-experience-qoe-and-other-business-related-concerns">Quality of experience (QoE) and other business related concerns.</h2>
<p>There are two main concerns that are closely linked. The fear of bloating the bandwidth of users, which damages UX and engagement, and the fear of delivering poor visual quality, which potentially damages brand image. </p>
<p>The balance between these two antagonising factors is what determines the QoE. Keeping a <strong>high QoE</strong> requires delivering nearly the <strong>best possible quality, without rebuffering or stalling</strong> effects or noticeable drops of page speed.  </p>
<p>Of course, there are other issues that matter</p>
<ul>
<li>the customisation of the viewing experience to match the branding of the business</li>
<li>the cost increase of delivering higher bandwidth content </li>
<li>and the additional burden in terms of devops</li>
</ul>
<p>...just to name a few.</p>
<h2 id="heading-a-first-choice-progressive-vs-adaptive-bitrate-abr">A first choice: progressive vs adaptive bitrate (ABR).</h2>
<p>Regarding <a target="_blank" href="https://www.freecodecamp.org/news/video-formats-for-the-web/">video format selection</a>, there are two main options with important implications: progressive video and ABR.</p>
<p>Progressive videos may be delivered and consumed like images, using plain HTML5 code. Moreover, progressive mp4 videos with H264 encoding have universal support across browsers and systems. So, they're the straightforward approach.</p>
<p>However, in the likely event that QoE is a main concern we should go for ABR. More specifically for HLS -again with H264 encoding – which is a broadly supported option. </p>
<p>With <strong>HLS</strong> we'll be able, in most cases, to keep the <strong>bits per second - the bitrate - of the video within the connection capacity limits</strong>. This avoids rebuffering, stalling, or blocking other content. In HLS, the video is available at different bitrates and is split in pieces. This allows the client to request the best quality affordable, based on the network speed at any time. The only caveat is that we'll need to use a player in our front-end (basically a piece of JavaScript). In apps, it's easier because both iOS and Android feature native support for the protocol. </p>
<h2 id="heading-the-pipeline-and-the-workflow">The pipeline and the workflow</h2>
<p>That said, let's see what a video optimization and delivery pipeline for web entails. The pipeline is supposed to process a master or pristine video with a high quality and make it suited to the web. It's also supposed to meet brand requirements on visualization, and to integrate the video events in the analytics of the site. </p>
<p>In sum, our pipeline should address the following problems:</p>
<ul>
<li>Content management</li>
<li>Transcoding and optimization</li>
<li>Delivery</li>
<li>Visualization</li>
<li>Analytics</li>
</ul>
<p>In the end, the pipeline should allow a workflow similar to that of social video platforms - where you upload a video and get a <a target="_blank" href="https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Short-Video-Publishing-Demo/Video-Freecodecamp/index.html">link like this</a> to embed or share elsewhere - but under all the custom requirements of our business.</p>
<p>To keep this post short and focused, I'll skip the content management issue, which is basically the way we handle all the resources, including the collaborative media editing and approval workflows. Next, I go through the main optimization and delivery ingredients found in a video publishing pipeline.</p>
<h2 id="heading-transcoding-and-optimization">Transcoding and optimization</h2>
<p>For progressive videos to be responsive, we can create versions with different resolution and quality to be consumed based on breakpoints, similar to images. </p>
<p>In an in-house scheme this operation can be <a target="_blank" href="https://medium.com/abraia/video-transcoding-and-optimization-for-web-with-ffmpeg-made-easy-511635214df0">easily accomplished with ffmpeg</a>. It's an open source tool that performs resizing, compression, and many other operations very efficiently. For instance, to scale a 4K video to fullHD with good visual quality you may simply use:</p>
<pre><code>ffmpeg -y -i input.mp4 -vf scale=<span class="hljs-number">1920</span>:<span class="hljs-number">-2</span> -c:v libx264 -crf <span class="hljs-number">22</span> -profile:v high -pix_fmt yuv420p -color_primaries <span class="hljs-number">1</span> -color_trc <span class="hljs-number">1</span> -colorspace <span class="hljs-number">1</span> -movflags +faststart -an output.mp4
</code></pre><p>Alternatively, with a cloud platform the operation should be a no brainer, although in many cases we loose effective control of the quality settings and possible breakpoints.</p>
<p>Encoding for <strong>HLS</strong> is a bit trickier. First, <strong>we have to define a coding ladder</strong>. Each step of the ladder will feature a different bitrate, from a maximum to a minimum. They set respectively the maximum and minimum quality. </p>
<p>For each bitrate in the ladder, we also have to set the resolution, again from maximum to minimum. Ideally, we should use bitrates specifically tuned to the video content to optimize the use of bandwidth. When done automatically, <strong>on a per video basis</strong>, this is called <strong>per title encoding</strong>. </p>
<p>We have to code the video with the resolutions and bitrates defined and then cut each rendition in chunks. We also have to decide the duration of the chunk. That is, how frequently is HLS renegotiating the quality to request, based on the current network speed. We can do all of the encoding with ffmpeg or with a cloud service.</p>
<p>Let's see the files generated for our example. We have a folder containing all the chunks (.ts extension), and the playlists ( .m3u8 extension). </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/imaxe-7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The playlists contain all the information about the renditions available. Next, we can see the content of the master playlist: the ladder - bitrates and resolutions - and the relative route to the renditions.</p>
<pre><code>#EXTM3U
#EXT-X-VERSION:<span class="hljs-number">3</span>
#EXT-X-STREAM-INF:BANDWIDTH=<span class="hljs-number">3374012</span>,RESOLUTION=<span class="hljs-number">1920</span>x1080
<span class="hljs-number">1080</span>p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=<span class="hljs-number">1836580</span>,RESOLUTION=<span class="hljs-number">1280</span>x720
<span class="hljs-number">720</span>p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=<span class="hljs-number">1002050</span>,RESOLUTION=<span class="hljs-number">856</span>x480
<span class="hljs-number">480</span>p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=<span class="hljs-number">649329</span>,RESOLUTION=<span class="hljs-number">640</span>x360
<span class="hljs-number">360</span>p.m3u8
</code></pre><p>That is, for each rendition we have an additional playlist containing the information about the duration and route to the corresponding chunks. We also need a poster to use as thumbnail and get covered in the event of a very slow connection or HLS compatibility issues. In our example, all the resources are in the same folder so the route to each resource is simply the name.</p>
<h2 id="heading-delivery">Delivery</h2>
<p><strong>Videos should be delivered through a CDN</strong>. If you make a poor transcoding, many users may suffer slow page loads. But at least if you use a CDN you won't take your site down because the server is unable to handle the load. I've seen big sites that more than doubled their peak traffic the day they decided to use videos in their home page. So videos, whether progressive or HLS, should be delivered as static files cached and delivered by a CDN.</p>
<p>If you are using a cloud platform for video publishing, you should be covered. Any decent one offers video delivery through at least one CDN. If you need coverage in some countries like China, you need to look into each specific platform and the CDN used, since some of them do not work there.</p>
<h2 id="heading-visualization">Visualization</h2>
<p>While for progressive videos HTML5 is enough to ensure visualization, in the case of HLS we need a <strong>JavaScript player with HLS support</strong>. </p>
<p>There are many commercial options, but there are also open source alternatives with very high quality. A good example is <strong>Video.js</strong>. It has a wide support among browsers, only limited by the dependency on the <a target="_blank" href="https://caniuse.com/#search=media%20source">Media Source Extensions API</a>. It brings a high degree of customization using skins and a flexible configuration, for instance allowing you to use autoplay or different video controls.</p>
<p>The player may be inserted in the page code, or it can be in an html static that is embedded as an iframe. </p>
<p>Going back to our example, when we publish the video we create an <a target="_blank" href="https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Tests/PexelsVideos2795392/index.html">html resource</a> that has a Video.js player with default settings. The content url should point to the master playlist and the thumbnail to the poster image extracted from the video.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/imaxe-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In this case, the html resource also adds <strong>oembed compatibility</strong>. Besides directly access in the browser this html - or a different one in which we copy/paste the player's code - to play <a target="_blank" href="https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Tests/PexelsVideos2795392/index.html">the video</a>, we can embed it in a content management system (CMS). For instance, when writing this post for freeCodeCamp.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Short-Video-Publishing-Demo/Embedding/index.html">https://store.abraia.me/05bf471cbb3f9fa9ed785718e6f60e28/Short-Video-Publishing-Demo/Embedding/index.html</a></div>
<h2 id="heading-analytics">Analytics</h2>
<p>In short videos, typical analytics of interest are the <strong>ratio of users that play the video, the ratio of those who view it in full, or the ratio of playback failures</strong>. </p>
<p>Again, there are many commercial options available. However in many cases a widespread free option like Google Analytics (GA) may be enough. If we are using Video.js, we only have to instrument the html resource with GA, like for any other web page. Going back to our example, we can see it in the editable HTML created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/imaxe-5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To track the video use in GA, we just have to track the video events in the player. For instance:</p>
<pre><code>    player.analytics({
      <span class="hljs-attr">defaultVideoCategory</span>: <span class="hljs-string">'Video'</span>,
      <span class="hljs-attr">events</span>: [{
        <span class="hljs-attr">name</span>: <span class="hljs-string">'play'</span>,
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Video-Freecodecamp'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'play'</span>,
      }, {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'pause'</span>,
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Video-Freecodecamp'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'pause'</span>,
      }, {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'ended'</span>,
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Video-Freecodecamp'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'ended'</span>,
      }, {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'error'</span>,
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Video-Freecodecamp'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'error'</span>,
      }]
    });
</code></pre><p>Then, in GA we can see the events taking place. This screenshot shows my own real-time activity - with two devices and browsers - on the video example created for this post.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/imaxe-4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-summary">Summary</h2>
<p>I have reviewed the main aspects involved in a video publishing pipeline, from transcoding, to delivery, visualization, and analytics. I have made reference to potential use of different resources, including two prominent open source initiatives like ffmpeg and Video.js.</p>
<p>I have supported the explanation with a simple example using our <a target="_blank" href="https://abraia.me/video/">video publishing demo</a>. It gives full access to the resources created. You'll be able to download, modify, and use the resources in your tests. You can freely use it to repeat the process with a short video of your choice. </p>
<p>Remember to start with a high quality video. The example here is based on a 9 seconds 4k video from <a target="_blank" href="https://www.pexels.com/@cottonbro">@cottonbro</a>. Overall, I expect the post to bring a bird's eye view of what a custom deployment for video publishing entails.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
