{"id":20604,"date":"2019-04-11T11:30:41","date_gmt":"2019-04-11T11:30:41","guid":{"rendered":"https:\/\/www.heartinternet.uk\/blog\/?p=20604"},"modified":"2019-04-11T11:30:41","modified_gmt":"2019-04-11T11:30:41","slug":"best-practices-for-optimising-video-streams-on-the-web","status":"publish","type":"post","link":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/","title":{"rendered":"Best practices for optimising video streams on the web"},"content":{"rendered":"<p>When I think of video streaming, I typically think of Netflix, Amazon or YouTube \u2014 the major providers of video on the web today. When I think of \u201cvideo on the web,\u201d I generally think about pages with a background video, or another fun immersive feature that makes the page engaging. Generally (as a web developer), I assume that these pages use the video tag, not streaming.<\/p>\n<p>However, if the top companies delivering video content on the web are streaming their videos &#8211; and most other pages are not &#8211; is there something that can be learned here? Could streaming video be faster, more efficient, and have a better customer experience? I believe the answer is yes, but there is a little legwork that must be done to ensure that your video is streaming to its optimal potential.<\/p>\n<p>Finally, setting up video streaming is fairly straightforward, and no longer requires any specialised hardware &#8211; any HTTP server can serve streaming content.<\/p>\n<h3>What is Adaptive Bitrate Streaming?<\/h3>\n<p>When delivering a video with the video tag&#8230;<\/p>\n<p><code>&lt;video src=\"myvideo_1080.mp4\"&gt;<\/code><\/p>\n<p>\u2026 there is just one file \u2014 no matter the size of the screen, or the quality of the network. In the example above, we can assume that the video is 1080p, which may be larger than required for mobile handsets. The additional pixels will make the file larger, and therefore take longer to arrive on slower networks.<\/p>\n<p>How can we deliver smaller videos? Perhaps we could write some JavaScript to deliver \u201cmyvideo_1080.mp4\u201d to devices with large screens, and \u201cmyvideo_720.mp4\u201d just to mobile devices. This would certainly be a step forward, but what if the mobile device was on fast Wi-Fi and could have handled the faster video? Or what if the device with the larger screen was on a slower network (or the network conditions changed during playback)?<\/p>\n<p>This is where adaptive bitrate shines. Each video is created with several different streams, at different resolutions and quality (read: size of the video). Then each of these streams is divided into segment (or chunks), each typically two to five seconds long.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20607\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/video-streaming-example-e1554372075241.png\" alt=\"\" width=\"650\" height=\"321\" \/><\/p>\n<p>Now the player on the device has a number of different options for playing video, depending on the device and the network. For advanced players, if the network changes, and it appears that the video can no longer download fast enough, a switch can be made to a more appropriate bitrate video \u2014 in the middle of playback!<\/p>\n<p>Also, if the stream has separate audio and video tracks, the player can choose the appropriate audio stream, based on the browser language (eg German for German speakers).<\/p>\n<p>With all of these features, a well-built streaming video will deliver precisely the right quality for the device and the available network speed.<\/p>\n<h3>How does ABS work?<\/h3>\n<p>We will use the \u00a0HTTP Live Streaming (HLS) format to understand how streaming works. HLS is currently the most popular format for building video streams (another popular format is MPEG-DASH).<\/p>\n<p>When a video is delivered to the player on the device, the first file to arrive is the manifest file. \u00a0This file is the \u201cmenu\u201d of streams available for playback. The manifest lists all available streams, audio channels, subtitles that the player can utilise in video playback. For simplicity, let\u2019s start with a simple manifest with just video files:<\/p>\n<p><code><a href=\"https:\/\/tools.ietf.org\/html\/draft-pantos-http-live-streaming\">#EXTM3U<br \/>\n<\/a>#EXT-X-STREAM-INF:BANDWIDTH=1566000,CODECS=\"avc1.4D401F,mp4a.40.2\",RESOLUTION=1280x720<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.m3u8\">https:\/\/res.cloudinary.com\/dougsillars\/video\/upload<br \/>\n\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.m3u8<\/a><br \/>\n#EXT-X-STREAM-INF:BANDWIDTH=972000,CODECS=\"avc1.4D401F,mp4a.40.2\",RESOLUTION=960x540<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_960,h_540,vc_h264:main:3.1,br_3500k\/v1543082006\/Campus_mfkz6z.m3u8\">https:\/\/res.cloudinary.com\/dougsillars\/video\/upload<br \/>\n\/c_limit,w_960,h_540,vc_h264:main:3.1,br_3500k\/v1543082006\/Campus_mfkz6z.m3u8<\/a><br \/>\n#EXT-X-STREAM-INF:BANDWIDTH=1670000,CODECS=\"avc1.42C01E,mp4a.40.2\",RESOLUTION=640x360<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_640,h_360,vc_h264:baseline:3.0,br_2m\/v1543082006\/Campus_mfkz6z.m3u8\">https:\/\/res.cloudinary.com\/dougsillars\/video\/upload<br \/>\n\/c_limit,w_640,h_360,vc_h264:baseline:3.0,br_2m\/v1543082006\/Campus_mfkz6z.m3u8<\/a><br \/>\n#EXT-X-STREAM-INF:BANDWIDTH=1021000,CODECS=\"avc1.42C01E,mp4a.40.2\",RESOLUTION=480x270<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_480,h_270,vc_h264:baseline:3.0,br_800k\/v1543082006\/Campus_mfkz6z.m3u8\">https:\/\/res.cloudinary.com\/dougsillars\/video\/upload<br \/>\n\/c_limit,w_480,h_270,vc_h264:baseline:3.0,br_800k\/v1543082006\/Campus_mfkz6z.m3u8<\/a><br \/>\n#EXT-X-STREAM-INF:BANDWIDTH=341000,CODECS=\"avc1.42C01E,mp4a.40.2\",RESOLUTION=320x180<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_320,h_240,vc_h264:baseline:3.0,br_192k\/v1543082006\/Campus_mfkz6z.m3u8\">https:\/\/res.cloudinary.com\/dougsillars\/video\/upload<br \/>\n\/c_limit,w_320,h_240,vc_h264:baseline:3.0,br_192k\/v1543082006\/Campus_mfkz6z.m3u8<\/a><\/code><\/p>\n<p>In this example, there are five video streams available. Each stream uses two lines to list all of the stream attributes, and then a link to a child manifest file that lists the segments. The first stream in this list is a 1.57 Mbps video with a resolution of 1280&#215;720.<\/p>\n<h4>The first stream<\/h4>\n<p>The first stream in the HLS manifest is extremely important. That\u2019s because the player has to choose a stream to start the video playback, and typically, the first stream in the list is chosen. \u00a0The video startup time, and initial quality is thus determined by the stream at the top of the list.<\/p>\n<p>The next request by the player is for the child manifest of this bitrate. This manifest file lists information about each segment of the stream:<\/p>\n<p><code><a href=\"https:\/\/tools.ietf.org\/html\/draft-pantos-http-live-streaming\">#EXTM3U<\/a><br \/>\n#EXT-X-VERSION:4<br \/>\n#EXT-X-TARGETDURATION:8<br \/>\n#EXT-X-MEDIA-SEQUENCE:0<br \/>\n#EXTINF:8.341667,<br \/>\n#EXT-X-BYTERANGE:1632216@0<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXTINF:8.341667,<br \/>\n#EXT-X-BYTERANGE:1134956@1632216<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXTINF:8.341667,<br \/>\n#EXT-X-BYTERANGE:1594804@2767172<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXTINF:8.341667,<br \/>\n#EXT-X-BYTERANGE:1193048@4361976<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXTINF:8.341667,<br \/>\n#EXT-X-BYTERANGE:1208464@5555024<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXTINF:8.341667,<br \/>\n#EXT-X-BYTERANGE:1008432@6763488<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXTINF:0.834167,<br \/>\n#EXT-X-BYTERANGE:95504@7771920<br \/>\n<a href=\"https:\/\/res.cloudinary.com\/dougsillars\/video\/upload\/c_limit,w_1280,h_720,vc_h264:main:3.1,br_5500k\/v1543082006\/Campus_mfkz6z.ts\">Campus_mfkz6z.ts<\/a><br \/>\n#EXT-X-ENDLIST<\/code><\/p>\n<p>Each segment in this manifest is represented by three rows of data. <code>#EXTINF<\/code> represents the length of the segment in seconds. <code>EXT-X-BYTERANGE<\/code> gives the <code>&lt;number of bytes in segment&gt;@&lt;starting bytes of segment&gt;<\/code>, and the third line is the URL of the segment to be downloaded.<\/p>\n<p>We can monitor this process with <a href=\"https:\/\/www.webpagetest.org\/\">WebPageTest<\/a>:<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20609\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/web-page-test-example.png\" alt=\"An image showing the loading speed at which a web page loads\" width=\"641\" height=\"157\" \/><\/p>\n<ol>\n<li>Webpage HTML<\/li>\n<li><a href=\"https:\/\/github.com\/video-dev\/hls.js\/\">hls.js<\/a>, a JavaScript streaming video player<\/li>\n<li>Master M3U8 manifest file<\/li>\n<li>404 \u2014 I don\u2019t have a favicon on this site<\/li>\n<li>Child M3U8 file<\/li>\n<li>ts file \u2014 the initial video segment<\/li>\n<li>ts file \u2014 the initial video segment<\/li>\n<\/ol>\n<h3>Ongoing playback<\/h3>\n<p>Once the stream has started, the player can track how quickly the chunks of video are downloaded \u2014 estimating the bandwidth of the connection. If the bitrate is higher than the bandwidth, the video will not download fast enough to keep pace with playback, so the player will switch to a lower quality stream that will allow uninterrupted playback.<\/p>\n<p>Expanding the WebPageTest waterfall above: request 8 is for another child m3u8 (for a lower bitrate stream), and the subsequent ts files are downloaded faster, allowing for the video buffer to fill up faster. This indicates that the player decided that a lower bitrate would allow better playback of the video.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-20610 size-full\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/webpage-test-lower-bit-rate-e1554372353528.png\" alt=\"webpage test results showing the video was streamed at a lower bitrate\" width=\"650\" height=\"235\" \/><\/p>\n<h3>Double take on bitrate changes<\/h3>\n<p>The player will continue to adjust the downloaded segments to optimise the quality of the video, while ensuring that the video fits underneath the network bandwidth cap. In the waterfall below, there are three child m3u8 files requested:<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20613\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/webpage-test-with-three-video-files-used.png\" alt=\"Webpage test results showing three files being requested as the video player adjusts to network coniditions\" width=\"727\" height=\"430\" \/><\/p>\n<p>This allows the player to adjust the video when network conditions vary, or become less than ideal.<\/p>\n<h2>Streaming solves a number of tough problems<\/h2>\n<p>With this setup, the player and the server communicate back and forth to ensure that the best quality video is displayed to the end user \u2014 no matter the device or network quality. As opposed to a single video (perhaps with JavaScript guessing the ideal stream based on initial parameters), we are already delivering a better product to our customers than a static video file. \u00a0But we can probably do better!<\/p>\n<h3>Optimising video streams<\/h3>\n<p>There are so many variables that you can adjust when it comes to video streaming \u2014 the bitrates of each stream, the order of the streams, the video encoding, the audio profiles, etc. In the context of this short article, we will stick to optimising the video streams for three of the top metrics used to identify good quality streams:<\/p>\n<ol>\n<li>Startup time<\/li>\n<li>Stalls<\/li>\n<li>Video quality<\/li>\n<\/ol>\n<p>By focusing on these three metrics you can make a lot of headway towards optimising your videos.<\/p>\n<h4>Video startup<\/h4>\n<p><a href=\"https:\/\/www.conviva.com\/research\/convivas-2018-annual-state-streaming-tv-industry\/\">According to Conviva<\/a> (a popular video analytics company), in Q3 2018, 18 percent of mobile and 31 percent of desktop video streams were never consumed. They either failed to start, or the user exited before the video could begin playing.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-20616 size-full\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/video-play-pie-chart-e1554372675445.png\" alt=\"A chart showing that 31% of video streams never start or the user quits before the video starts\" width=\"650\" height=\"367\" \/><\/p>\n<p>Why are so many videos failing to play? It turns out that the average video start time was 3.47s on mobile and 6.29s on desktop. The longer a customer has to wait for a video, the more likely they are to abandon the playback.<\/p>\n<h4>Setting the initial bitrate<\/h4>\n<p>To prevent video playback abandonment, the video needs to start as quickly as possible. For the video to start playing, it must be on the device \u2014 which means the faster the first segment (or two) of video can be delivered to the player, the faster the video will start. This can be easily done by modifying the first stream in the manifest to a slower bitrate stream. In the example video above, I modified the initial stream in the manifest to 370 Kbps, 972 Kbps and 1.57 Mbps to see if the video startup time changed significantly. I tested each of these streams with WebPageTest, using a <a href=\"https:\/\/www.webpagetest.org\/video\/compare.php?tests=190216_Z4_595e23c271800f695eb9c0f8230c7978%2C190216_VH_b45284735bb06905e99cb2a178c93b2e%2C190216_E8_8a764b99f21e1019654712c8f1191864&amp;thumbSize=200&amp;ival=500&amp;end=visual\">Nexus 5 with LTE network speed<\/a>:<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20617\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/webpage-test-start-up-times-e1554372747160.png\" alt=\"An image showing how a large initial video stream leads to a slower startup time\" width=\"650\" height=\"530\" \/><\/p>\n<p>Each frame represents 0.5s. The 370 Kbps video starts over one second faster than the 972 Kbps, which is 200 to 300 milliseconds faster than the 1.57 Mbps stream.<\/p>\n<p>The effect is more pronounced when testing at <a href=\"https:\/\/www.webpagetest.org\/video\/compare.php?tests=190216_1A_102df279108289c105fdaf88c170a899%2C190216_JJ_cda3c97151dcc7c303cd43a1ca2e36ee%2C190216_VH_5ad758a9e04c42084dd30dae0f2a4771&amp;thumbSize=200&amp;ival=1000&amp;end=visual\">3G<\/a>:<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-20619 size-full\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/webpage-test-start-up-times-on-3g-e1554372850611.png\" alt=\"An image showing that a larger initial video stream has an even bigger impact on startup time over a 3g network\" width=\"650\" height=\"617\" \/><\/p>\n<p>In this screenshot, each frame is five seconds apart, indicating that the 1 Mbps stream is five seconds faster than 1.57 Mbps, and 370 Kbps is 10 seconds faster. In this test, all three streams downloaded the first segment, and the player fell back to the lowest possible stream. The top row was already there and kept streaming, but the other two streams took longer to download the larger first segment, adding seconds to the video startup time.<\/p>\n<p>Of course, this means that the initial few seconds of video stream may be at a lower quality, so it\u2019s important to test how a change to a lower bitrate affects engagement.<\/p>\n<p>In examining 3,000 video streams with the <a href=\"https:\/\/httparchive.org\/\">HTTP Archive<\/a> in January 2019, 58 percent start with the lowest bandwidth stream to ensure that the video will startup as quickly as possible. Thirty percent of videos have an initial bitrate set above 1.5 Mbps. Since the HTTP Archive tests mobile devices with a throughput of 1.5 Mbps, these sites will have a longer initial delay as the player will have to fall back to a lower quality video before playback can begin.<\/p>\n<p>This is an important cutoff point for video, as US mobile networks \u00a0(using marketing terms like \u201cSmooth Stream\u201d and Binge On\u201d) throttle video at 1.5 Mbps. Videos that begin with a stream above 1.5 Mbps will not play until the first segment is downloaded, and then the player degrades the video quality, leading to a significant startup delay.<\/p>\n<p><strong>Best practice: <\/strong>Start with an initial bitrate as low as possible to ensure fast video startup.<\/p>\n<h4>M3U8 list of streams<\/h4>\n<p>For longer videos, there may be 10 seconds or hundreds of segments listed in the m3u8 file. \u00a0This list is highly repetitive, making these files an ideal case for gzip compression. Below are two examples of m3u8 lists of segments.<\/p>\n<p>The first is not zipped, so the 104 KB file uses 104 KB on the wire.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20622\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/m3u8-list-e1554373110420.png\" alt=\"An example of an m3u8 list of segments\" width=\"650\" height=\"143\" \/><\/p>\n<p>This page has three m3u8 files with lists of segments, but the files are compressed. Rather than use over 750 KB on the wire, less than 30 KB are used \u2014 allowing the files to be delivered faster \u2014 and allowing the request for the first segment of video to be requested faster.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20625\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/m3u8-list-2.png\" alt=\"A list of m3u8 segments that have been zipped to compress their size\" width=\"918\" height=\"220\" \/><\/p>\n<p><strong>Best practice: <\/strong>Always zip text files for faster transfer over the network.<\/p>\n<h4>Video playback<\/h4>\n<p>Now that the video has started playing, the Adaptive Bitrate player is not done. The next biggest cause of video abandonment is due to the video stalling. This occurs when there is no more video present on the device to play, and the player must wait for further segments to arrive over the network. The number of stalls that occur during playback is the rebuffering ratio. The Conviva report indicates that this occurs on 1.1 percent of mobile plays, and 0.9 percent PC plays. As this number is reduced, the engagement and length of viewing increases. <a href=\"https:\/\/www.xushichang.com\/papers\/video_imc17.pdf\">Research has shown that starting with a lower bitrate allows for more segments to be quickly downloaded<\/a>, and decreases the percentage of stalls.<\/p>\n<p>Some video players aggressively push for higher bitrates, which may lead to more changes in stream. The more often a player changes the stream, the more likely it is that a video will stall. A future post will evaluate various players for their aggressiveness, and how this relates to stalls.<\/p>\n<p>In a sample of 3000 streaming videos from the HTTP Archive, 2.6 percent had just one stream, which negates the possibility to tune the video to the customer\u2019s device or network.<\/p>\n<h4>Video quality<\/h4>\n<p>As the video player monitors the available video segments and the network speed, it can adjust the download to a lower or higher quality bitrate to ensure continued video playback. When bitrates are chosen correctly, this should \u2018just work\u2019, but there are a few tricks to make it work better.<\/p>\n<h4>Appropriate bitrates<\/h4>\n<p>As noted above, US carriers throttle video to 1.5 Mbps, so it\u2019s important to have at least one stream with a bitrate below 1.3 Mbps, which essentially maximises the quality for all mobile customers in the USA. Examining the data in the HTTP Archive, 1.8 of the videos studied have 0 streams that will play below 1.25 Mbps, and are unlikely to stream on a US mobile phone, while 276 sites have just one available stream to mobile customers in the states, which prevents the video from adapting as needed.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20628\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/available-streams-graph.png\" alt=\"A graph showing the number of available streams below 1.25mbps\" width=\"488\" height=\"376\" \/><\/p>\n<h4>Even stream distribution<\/h4>\n<p>In the chart below, I have graphed the available stream bitrates, and highlighted the space between streams 4 and 5.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20631\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/stream-bitrate-graph.png\" alt=\"A graph showing uneven stream distribution\" width=\"766\" height=\"399\" \/><\/p>\n<p>The change in bitrates for streams 1 to 4 is fairly linear, as are the changes in 5 to 8, meaning that adjustments for the player are straightforward. However, the change from 4 to 5 is a much larger adjustment than any of the others, which makes it hard for the player to make \u2018the leap\u2019 to the higher bitrates. Additionally, we can see that the jump goes from 1 Mbps to 3.5 Mbps, which are common streaming rates on mobile. This forces all mobile users to the lower quality range, even if they have a 3 Mbps stream.<\/p>\n<p><strong>Best practice for quality: <\/strong>Have a stream of around 1.3 Mpbs for mobile customers in the USA, and keep stream changes small or evenly distributed.<\/p>\n<h3>Conclusion<\/h3>\n<p>Mobile streaming is the \u201cresponsive\u201d way to deliver video on the web. Rather than one static MP4 file for all customers, the video can be adapted for the screen size and also for the available network conditions. With proper tuning of the video parameters, the ideal video can be delivered to all consumers, improving video startup times, reducing stalls, and optimising the amount of data transferred. We\u2019ve walked through some of the basics of how streaming works, and some best practices that further enhance the quality of streaming video.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Struggling with the task of ensuring the videos you include on the sites you build are optimisied for streaming? Our guide explains how you can give visitors a good video experience every time.<\/p>\n","protected":false},"author":2,"featured_media":20176,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,24,28],"tags":[],"class_list":{"0":"post-20604","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-guest-posts","8":"category-web-design","9":"category-your-business"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Best practices for optimising video streams on the web - Heart Internet<\/title>\n<meta name=\"description\" content=\"Find out how to optimise video streams on the web so the sites you create deliver a great video experience to visitors without delays and buffering\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Best practices for optimising video streams on the web - Heart Internet\" \/>\n<meta property=\"og:description\" content=\"Find out how to optimise video streams on the web so the sites you create deliver a great video experience to visitors without delays and buffering\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\" \/>\n<meta property=\"og:site_name\" content=\"Heart Internet\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/heartinternet\/\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-11T11:30:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"733\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eliot Chambers-Ostler\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:site\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eliot Chambers-Ostler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\"},\"author\":{\"name\":\"Eliot Chambers-Ostler\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\"},\"headline\":\"Best practices for optimising video streams on the web\",\"datePublished\":\"2019-04-11T11:30:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\"},\"wordCount\":2270,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg\",\"articleSection\":[\"Guest Posts\",\"Web Design\",\"Your Business\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\",\"name\":\"Best practices for optimising video streams on the web - Heart Internet\",\"isPartOf\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg\",\"datePublished\":\"2019-04-11T11:30:41+00:00\",\"description\":\"Find out how to optimise video streams on the web so the sites you create deliver a great video experience to visitors without delays and buffering\",\"breadcrumb\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg\",\"width\":1100,\"height\":733},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.heartinternet.uk\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Best practices for optimising video streams on the web\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/heartblog.victory.digital\/#website\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"name\":\"Heart Internet\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/heartblog.victory.digital\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\",\"name\":\"Heart Internet\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"width\":992,\"height\":252,\"caption\":\"Heart Internet\"},\"image\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/heartinternet\/\",\"https:\/\/x.com\/heartinternet\",\"https:\/\/www.linkedin.com\/company\/heart-internet-ltd\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\",\"name\":\"Eliot Chambers-Ostler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"caption\":\"Eliot Chambers-Ostler\"},\"url\":\"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Best practices for optimising video streams on the web - Heart Internet","description":"Find out how to optimise video streams on the web so the sites you create deliver a great video experience to visitors without delays and buffering","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/","og_locale":"en_GB","og_type":"article","og_title":"Best practices for optimising video streams on the web - Heart Internet","og_description":"Find out how to optimise video streams on the web so the sites you create deliver a great video experience to visitors without delays and buffering","og_url":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/","og_site_name":"Heart Internet","article_publisher":"https:\/\/www.facebook.com\/heartinternet\/","article_published_time":"2019-04-11T11:30:41+00:00","og_image":[{"width":1100,"height":733,"url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg","type":"image\/jpeg"}],"author":"Eliot Chambers-Ostler","twitter_card":"summary_large_image","twitter_creator":"@heartinternet","twitter_site":"@heartinternet","twitter_misc":{"Written by":"Eliot Chambers-Ostler","Estimated reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#article","isPartOf":{"@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/"},"author":{"name":"Eliot Chambers-Ostler","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28"},"headline":"Best practices for optimising video streams on the web","datePublished":"2019-04-11T11:30:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/"},"wordCount":2270,"commentCount":1,"publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg","articleSection":["Guest Posts","Web Design","Your Business"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/","url":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/","name":"Best practices for optimising video streams on the web - Heart Internet","isPartOf":{"@id":"https:\/\/heartblog.victory.digital\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg","datePublished":"2019-04-11T11:30:41+00:00","description":"Find out how to optimise video streams on the web so the sites you create deliver a great video experience to visitors without delays and buffering","breadcrumb":{"@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#primaryimage","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/01\/video-camera-filming.jpg","width":1100,"height":733},{"@type":"BreadcrumbList","@id":"https:\/\/www.heartinternet.uk\/blog\/best-practices-for-optimising-video-streams-on-the-web\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.heartinternet.uk\/blog\/"},{"@type":"ListItem","position":2,"name":"Best practices for optimising video streams on the web"}]},{"@type":"WebSite","@id":"https:\/\/heartblog.victory.digital\/#website","url":"https:\/\/heartblog.victory.digital\/","name":"Heart Internet","description":"","publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/heartblog.victory.digital\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/heartblog.victory.digital\/#organization","name":"Heart Internet","url":"https:\/\/heartblog.victory.digital\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","width":992,"height":252,"caption":"Heart Internet"},"image":{"@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/heartinternet\/","https:\/\/x.com\/heartinternet","https:\/\/www.linkedin.com\/company\/heart-internet-ltd"]},{"@type":"Person","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28","name":"Eliot Chambers-Ostler","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","caption":"Eliot Chambers-Ostler"},"url":"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/"}]}},"_links":{"self":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/20604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/comments?post=20604"}],"version-history":[{"count":0,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/20604\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media\/20176"}],"wp:attachment":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media?parent=20604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/categories?post=20604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/tags?post=20604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}