{"id":21438,"date":"2016-11-16T17:14:28","date_gmt":"2016-11-16T17:14:28","guid":{"rendered":"http:\/\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash"},"modified":"2025-03-02T15:00:32","modified_gmt":"2025-03-02T23:00:32","slug":"plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash","title":{"rendered":"HTTP Live Streaming Without the Hard Work"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><div class='c-callout  c-callout--note'><strong class='c-callout__title'>Update:<\/strong> <p>In this post, we clarify that not all browsers natively support HLS or MPEG-DASH, and thus in order to deliver adaptive streaming video to all devices, you should deliver it using a video player that supports your chosen format. In December of 2017, Cloudinary released its own Video Player, which enables you to easily embed a player in your web page that can stream any HLS or MPEG-DASH video. For details, see the <a href=\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\">Video Player announcement blog post<\/a> and the <a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_video_player\">Video Player documentation<\/a>.<\/p><\/div>\n<h2>Plug and play image for HTTP Live Streaming  and MPEG-DASH<\/h2>\n<p>You know <em>that moment when<\/em> you click a video link on your phone while on your way to grab a coffee from the office kitchen, but then you get that annoying buffering icon, and just give up? That video might have been interesting, maybe even valuable, but it\u2019s just not worth your time.<\/p>\n<p>Millions of users repeat this experience every day: stealing a couple minutes before starting work, stretching the time before going to sleep or getting out of bed, grabbing a quick break in between other planned tasks, etc. In any of these scenarios, a short video can be a great way to learn more about a concept, product, or get the latest news, but our \u2018free\u2019 moments are precious and we are not going to waste them waiting for heavy videos to download to our phones and other devices. Even when we do have more time to spare, we find ourselves too impatient to wait for any video that buffers for too long.<\/p>\n<p>If you deliver video on your website, you understand that great video content is of little value if it isn\u2019t delivered quickly enough to get your users watching and then keep their attention until the end. You may also know that the best way to minimize these incredibly costly failures is to deliver video using <a href=\"https:\/\/cloudinary.com\/glossary\/adaptive-bitrate-streaming\">adaptive bitrate streaming<\/a>.<\/p>\n<p><em><strong>Adaptive bitrate streaming is a video delivery technique that adjusts the quality of a video stream in real time according to detected bandwidth and CPU capacity of each user.<\/strong><\/em><\/p>\n<p>Two of the most popular adaptive bitrate streaming formats are <a href=\"https:\/\/cloudinary.com\/video_api\"><strong>HLS<\/strong> (HTTP Live Streaming)<\/a> and <strong>MPEG-DASH<\/strong> (Dynamic Adaptive Streaming over HTTP). If you can deliver video in both of these formats, you can probably minimize <a href=\"https:\/\/cloudinary.com\/glossary\/buffer\">buffering<\/a> time for just about all of your users. But each of these formats requires outputting every video multiple times at different qualities along with a set of additional required files. <a href=\"#how_adaptive_bitrate_streaming_works\">This process<\/a> is generally both complex and tedious. Services that help you create these files can be costly, and most don\u2019t provide an end-to-end solution.<\/p>\n<p>You can simplify the creation of these files using Cloudinary\u2019s adaptive streaming profile functionality, which enables you to automatically generate all of the required video files for each of the desired quality and bitrate levels, along with the corresponding index and master files. You just upload a video in any format, plug in the name of one of Cloudinary\u2019s predefined streaming profiles in an eager transformation request (or specify a custom streaming profile that you defined with the Admin API), and then deliver the automatically generated, fully packaged <code>.m3u8<\/code> or <code>.mpd<\/code> file using the HTTP Live Streaming or MPEG-DASH player of your choice. Literally <strong>Plug\u2026 and Play<\/strong>!<\/p>\n<h2>How adaptive bitrate streaming works<\/h2>\n<p>Providing a video using adaptive bitrate streaming means that you actually provide several versions (known as <strong>representations<\/strong> or <strong>variants<\/strong>) of your video, each with different qualities, bitrates, and codecs. Each video file must also be accompanied by an index file that specifies predefined segments or chunks of the video. These segments are usually 2, 5, or 10 seconds long. Additionally, there is a master playlist that points to the available representations with additional information about each one.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/blog_adaptive_streaming_model.png\" alt=\"adaptive bitmap streaming files, diagram\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"933\"\/>\n<em>Adaptive bitmap streaming files, diagram<\/em><\/p>\n<p>The adaptive streaming player uses this information to decide which of the available representations best matches a user\u2019s network conditions or preferences at any time. It can switch to another representation with higher or lower quality at each segment if the network conditions change. This helps maintain continuous viewing with the best possible quality to maximize the user experience.<\/p>\n<p>The example below simulates the process that an adaptive streaming player might follow as a user watches a video that\u2019s delivered via adaptive streaming:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/blog_adaptive_diagram.png\" alt=\"adaptive bitmap streaming simulation\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"425\"\/>\n<em>Adaptive bitmap streaming simulation<\/em><\/p>\n<p>&nbsp;<\/p>\n<table>\n<tbody>\n<tr>\n<td style=\"width: 70px; text-align: center;\">\n<p><span style=\"font-weight: 400;\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/1_circle.png\" alt=\"\" width=\"30\" height=\"30\" \/><\/span><\/p>\n<\/td>\n<td>\n<p><span style=\"font-weight: 400;\">User begins playing while connected to wifi. Video begins playing immediately using the smaller 640&#215;360 representation and simultaneously buffers.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">\n<p><span style=\"font-weight: 400;\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/2_circle.png\" alt=\"\" width=\"30\" height=\"30\" \/><\/span><\/p>\n<\/td>\n<td>\n<p><span style=\"font-weight: 400;\">After a few seconds, the user expands to full screen, and since the buffering is sufficient, the client delivers the higher resolution 1280&#215;720 representation.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">&nbsp;<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/3_circle.png\" alt=\"\" width=\"30\" height=\"30\" \/><\/td>\n<td>\n<p><span style=\"font-weight: 400;\">The user manually selects the 1920&#215;1080 representation from the player&rsquo;s resolution selection box.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">&nbsp;<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/4_circle.png\" alt=\"\" width=\"30\" height=\"30\" \/><\/td>\n<td>\n<p><span style=\"font-weight: 400;\">As the user walks from his home to his car and leaves his wifi range, he changes the player resolution selection back to automatic. The client recognizes the drop in network performance and reverts to 640&#215;360 play.<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>HTTP Live Streaming and MPEG-DASH adaptive bitrate streaming formats<\/h2>\n<p>The two leading adaptive bitrate streaming formats are <strong>HLS<\/strong> (HTTP Live Streaming) and <strong>MPEG-DASH<\/strong> (Dynamic Adaptive Streaming over HTTP).<\/p>\n<p><strong>HLS<\/strong> is an adaptive streaming communications protocol created by Apple. The Safari browser can play HLS streams within a web page, iPhones, and iPod touch devices. Since v2, all Apple TV devices also include an HTTP Live Streaming client. Apple\u2019s AppStore requires apps that stream videos longer than 10 minutes over a cellular network to deliver those videos via HLS adaptive streaming. For details, see <a href=\"https:\/\/developer.apple.com\/library\/ios\/qa\/qa1767\/_index.html\">https:\/\/developer.apple.com\/library\/ios\/qa\/qa1767\/_index.html<\/a><\/p>\n<p><strong>MPEG-DASH<\/strong> is an international standard for streaming video, intended to be a standardized replacement for proprietary HTTP streaming technologies, but is currently not natively supported in iOS devices. In other browsers and devices, it requires a javascript library or a video player that supports MPEG-DASH.<\/p>\n<p>As mentioned above, to deliver videos using adaptive bitrate streaming, you must generate multiple video representations, an index file per representation, and a master playlist. The formats and encoding for HLS and MPEG-DASH are different for each of these files. So, if you want to deliver both HTTP Live Streaming and MPEG-DASH formats, to cover both iOS and non-iOS devices, then you need to double the effort for every video you want to deliver. Additionally, for MPEG-DASH, the best practice is to deliver the audio and video separately, so chalk up even more files and complexity.<\/p>\n<h2>Cloudinary streaming profiles<\/h2>\n<p>Generating so many video outputs and creating all the required supporting files for every video you want to deliver, is a huge and potentially expensive challenge.<\/p>\n<p>To address this challenge, <a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> enables you to pick from a set of predefined streaming profiles or create your own custom profile. A Cloudinary streaming profile comprises a set of video representation definitions with various qualities, bitrates, and codecs. For example, the 4k predefined profile specifies 8 different representations in 16*9 aspect ratio, ranging from extremely high quality to audio-only.<\/p>\n<p>Once you pick (or define) a streaming profile, you simply upload your video file with a single eager transformation that instructs Cloudinary to generate all the required files for the requested profile in either HTTP Live Streaming or MPEG-DASH format. If you want to deliver both formats, all it takes is two <code>eager<\/code> transformations within your <code>upload<\/code> command, instead of one.<\/p>\n<p>For example, this Ruby code eagerly generates the <code>big_buck_bunny<\/code> video in both HTTP Live Streaming and MPEG-DASH formats using the full_hd built-in streaming profile, which yields 6 representations of the movie at a variety of quality levels.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">Cloudinary::Uploader.upload(<span class=\"hljs-string\">\"big_buck_bunny.mp4\"<\/span>, :<span class=\"hljs-function\"><span class=\"hljs-params\">resource_type<\/span> =&gt;<\/span> :video, \n :<span class=\"hljs-function\"><span class=\"hljs-params\">eager<\/span> =&gt;<\/span> &#91;\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">streaming_profile<\/span> =&gt;<\/span> <span class=\"hljs-string\">\"full_hd\"<\/span>, :<span class=\"hljs-function\"><span class=\"hljs-params\">format<\/span> =&gt;<\/span> <span class=\"hljs-string\">\"m3u8\"<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">streaming_profile<\/span> =&gt;<\/span> <span class=\"hljs-string\">\"full_hd\"<\/span>, :<span class=\"hljs-function\"><span class=\"hljs-params\">format<\/span> =&gt;<\/span> <span class=\"hljs-string\">\"mpd\"<\/span>}], \n :<span class=\"hljs-function\"><span class=\"hljs-params\">eager_async<\/span> =&gt;<\/span> <span class=\"hljs-literal\">true<\/span>,\n :<span class=\"hljs-function\"><span class=\"hljs-params\">eager_notification_url<\/span> =&gt;<\/span> <span class=\"hljs-string\">\"http:\/\/mysite\/notify_endpoint\"<\/span>,\n :<span class=\"hljs-function\"><span class=\"hljs-params\">public_id<\/span> =&gt;<\/span> <span class=\"hljs-string\">\"bb_bunny\"<\/span>)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>There are seven different predefined adaptive streaming profiles to choose from. The same profiles are relevant for both HLS and DASH. For full details on the available profiles, see <a href=\"https:\/\/cloudinary.com\/documentation\/adaptive_bitrate_streaming#predefined_streaming_profiles\">Predefined streaming profiles<\/a> in the Cloudinary documentation. You can use the Admin API to fine-tune the predefined profiles to fit your needs, or to create your own <a href=\"#custom_streaming_profiles\">custom streaming profiles<\/a>.<\/p>\n<p>When the eager upload is complete, the only thing left for you to do is to embed the relevant adaptive streaming client player(s) in your application. There are a number of open source and closed source HLS and DASH client players available.<\/p>\n<p>While you play an <code>m3u8<\/code> or <code>mpd<\/code> file generated using an adaptive streaming profile, you can take a look at the way the client player selects from your representations using the browser tools, such as the Chrome DevTools console:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/blog_hls_network_console.png\" alt=\"browser network console showing the active video representation\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"639\"\/>\n<em>Browser network console showing the active video representation<\/em><\/p>\n<p>For example, you can see above that the highlighted segment played using the 480&#215;360 resolution with 800k bitrate, while the following segment played the representation with 640&#215;480 resolution and 2m bitrate.<\/p>\n<p>The higher-level the streaming profile you select, the more levels the client player has to choose from, to serve up the best possible quality that will enable continuous playback for each user\u2019s current network conditions. However, do keep in mind that higher level profiles will use more storage and transformation resources in your Cloudinary account. If this is an issue, you may want to take advantage of the \u2018lean\u2019 predefined profiles, which include fewer representations, with somewhat bigger jumps between lower and higher quality. Also, remember that even though you now only need a single line of code to prepare your HLS and\/or MPEG-DASH output, these transformations involve a lot of overhead and must be done eagerly.<\/p>\n<p>(<strong>Note:<\/strong> Technically, Cloudinary does support transforming and delivering these files on-the-fly in the case that the total size of all the files together is less than 100MB, but due to the long encoding time, this on-the-fly option should be used only for debugging purposes.)<\/p>\n<p>You can also apply other transformations alongside your streaming profile transformation. For example, the following URL plays the bb_bunny video in HTTP Live Streaming format with a small logo overlaid in the top left corner of the movie.<\/p>\n<p><cld-code-widget\n      class=\" c-code-widget\"\n      snippets=\"[]\"\n      parsed-url=\"{&quot;url&quot;:&quot;https:\\\/\\\/res.cloudinary.com\\\/demo\\\/video\\\/upload\\\/l_cloudinary_icon,o_30,co_white,w_0.2,g_north_west\\\/sp_sd\\\/bb_bunny.m3u8&quot;,&quot;cloud_name&quot;:&quot;demo&quot;,&quot;host&quot;:&quot;res.cloudinary.com&quot;,&quot;type&quot;:&quot;upload&quot;,&quot;resource_type&quot;:&quot;video&quot;,&quot;transformation&quot;:[{&quot;overlay&quot;:&quot;cloudinary_icon&quot;,&quot;opacity&quot;:&quot;30&quot;,&quot;color&quot;:&quot;white&quot;,&quot;width&quot;:&quot;0.2&quot;,&quot;gravity&quot;:&quot;north_west&quot;},{&quot;streaming_profile&quot;:&quot;sd&quot;}],&quot;transformation_string&quot;:&quot;l_cloudinary_icon,o_30,co_white,w_0.2,g_north_west\\\/sp_sd&quot;,&quot;url_suffix&quot;:&quot;&quot;,&quot;version&quot;:&quot;&quot;,&quot;secure&quot;:true,&quot;public_id&quot;:&quot;bb_bunny.m3u8&quot;,&quot;extension&quot;:&quot;m3u8&quot;,&quot;format&quot;:&quot;m3u8&quot;,&quot;format_code&quot;:true,&quot;url_code&quot;:false,&quot;signature&quot;:&quot;&quot;,&quot;private_cdn&quot;:false,&quot;result_asset_type&quot;:&quot;video&quot;,&quot;error&quot;:{}}\"\n      with-url=\"true\"\n    >\n      <span class=\"u-visually-hidden\">Loading code examples<\/span>\n    <\/cld-code-widget><\/p>\n<p>(<strong>Note<\/strong>: The above URL can be viewed only in devices or players that support HLS)<\/p>\n<p>Applying transformations in this manner applies the same transformation to all representations. You can also apply different transformations to different representations in a profile, for example, to include a text overlay showing the user which resolution is currently playing. To do this, you need to create a custom streaming profile.<\/p>\n<h2>Custom Streaming Profiles<\/h2>\n<p>The predefined adaptive streaming profiles that Cloudinary provides are based on a set of selected best practices and one of them is likely to be a good fit for most standard scenarios.<\/p>\n<p>But what if none of the provided profiles exactly answer your needs? For example, you might want a different number of representations or different divisions of quality available for your profile. Or you might want to apply special transformations for different representations within the profile. To create a customized streaming profile, you use the <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#manage_adaptive_streaming_profiles\">streaming_profiles method of the Admin API<\/a>.<\/p>\n<p>For example, below we\u2019ve used the Ruby implementation of the Admin API to create an <code>hd_debug<\/code> profile, where each defined representation includes the relevant video transformations as well as text overlay that displays that resolution and <a href=\"https:\/\/cloudinary.com\/glossary\/bitrate\">bitrate<\/a>. This helps us debug and watch how the client switches from one representation to another as the video buffer grows, as we resize the screen, or as network conditions change.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">Cloudinary::Api.create_streaming_profile(<span class=\"hljs-string\">\"hd_debug\"<\/span>, :<span class=\"hljs-function\"><span class=\"hljs-params\">representations<\/span> =&gt;<\/span> \n&#91;{:<span class=\"hljs-function\"><span class=\"hljs-params\">transformation<\/span> =&gt;<\/span>\n   &#91;{:<span class=\"hljs-function\"><span class=\"hljs-params\">width<\/span>=&gt;<\/span><span class=\"hljs-number\">320<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">height<\/span>=&gt;<\/span><span class=\"hljs-number\">240<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">bit_rate<\/span>=&gt;<\/span><span class=\"hljs-string\">'192k'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">crop<\/span>=&gt;<\/span><span class=\"hljs-string\">'limit'<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">overlay<\/span>=&gt;<\/span><span class=\"hljs-string\">'text:Arial_24_bold:320x240--bitrate:192KB'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">color<\/span>=&gt;<\/span><span class=\"hljs-string\">'white'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">background<\/span>=&gt;<\/span><span class=\"hljs-string\">'rgb:00000020'<\/span>},  \n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">border<\/span>=&gt;<\/span><span class=\"hljs-string\">'6px_solid_rgb:00000020'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">gravity<\/span>=&gt;<\/span><span class=\"hljs-string\">'north'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">y<\/span>=&gt;<\/span><span class=\"hljs-number\">0.1<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">flags<\/span>=&gt;<\/span><span class=\"hljs-string\">'layer_apply'<\/span>}]},\n{:<span class=\"hljs-function\"><span class=\"hljs-params\">transformation<\/span> =&gt;<\/span>\n   &#91;{:<span class=\"hljs-function\"><span class=\"hljs-params\">width<\/span>=&gt;<\/span><span class=\"hljs-number\">480<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">height<\/span>=&gt;<\/span><span class=\"hljs-number\">270<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">video_codec<\/span>=&gt;<\/span><span class=\"hljs-string\">'h264:baseline:3.0'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">bit_rate<\/span>=&gt;<\/span><span class=\"hljs-string\">'800k'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">crop<\/span>=&gt;<\/span><span class=\"hljs-string\">'limit'<\/span>},                \n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">overlay<\/span>=&gt;<\/span><span class=\"hljs-string\">'text:Arial_24_bold:480x270--bitrate:800KB'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">color<\/span>=&gt;<\/span><span class=\"hljs-string\">'white'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">background<\/span>=&gt;<\/span><span class=\"hljs-string\">'rgb:00000020'<\/span>}\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">border<\/span>=&gt;<\/span><span class=\"hljs-string\">'6px_solid_rgb:00000020'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">gravity<\/span>=&gt;<\/span><span class=\"hljs-string\">'north'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">y<\/span>=&gt;<\/span><span class=\"hljs-number\">0.1<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">flags<\/span>=&gt;<\/span><span class=\"hljs-string\">'layer_apply'<\/span>}]},\n{:<span class=\"hljs-function\"><span class=\"hljs-params\">transformation<\/span> =&gt;<\/span>\n   &#91;{:<span class=\"hljs-function\"><span class=\"hljs-params\">width<\/span>=&gt;<\/span><span class=\"hljs-number\">640<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">height<\/span>=&gt;<\/span><span class=\"hljs-number\">360<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">video_codec<\/span>=&gt;<\/span><span class=\"hljs-string\">'h264:baseline:3.0'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">bit_rate<\/span>=&gt;<\/span><span class=\"hljs-string\">'2m'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">crop<\/span>=&gt;<\/span><span class=\"hljs-string\">'limit'<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">overlay<\/span>=&gt;<\/span><span class=\"hljs-string\">'text:Arial_24_bold:640x360--bitrate:2MB'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">color<\/span>=&gt;<\/span><span class=\"hljs-string\">'white'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">background<\/span>=&gt;<\/span><span class=\"hljs-string\">'rgb:00000020'<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">border<\/span>=&gt;<\/span><span class=\"hljs-string\">'6px_solid_rgb:00000020'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">gravity<\/span>=&gt;<\/span><span class=\"hljs-string\">'north'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">y<\/span>=&gt;<\/span><span class=\"hljs-number\">0.1<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">flags<\/span>=&gt;<\/span><span class=\"hljs-string\">'layer_apply'<\/span>}]},\n{:<span class=\"hljs-function\"><span class=\"hljs-params\">transformation<\/span> =&gt;<\/span>\n   &#91;{:<span class=\"hljs-function\"><span class=\"hljs-params\">width<\/span>=&gt;<\/span><span class=\"hljs-number\">960<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">height<\/span>=&gt;<\/span><span class=\"hljs-number\">540<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">video_codec<\/span>=&gt;<\/span><span class=\"hljs-string\">'h264:main:3.1'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">bit_rate<\/span>=&gt;<\/span><span class=\"hljs-string\">'3500k'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">crop<\/span>=&gt;<\/span><span class=\"hljs-string\">'limit'<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">overlay<\/span>=&gt;<\/span><span class=\"hljs-string\">'text:Arial_24_bold:960x540--bitrate:3.5MB'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">color<\/span>=&gt;<\/span><span class=\"hljs-string\">'white'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">background<\/span>=&gt;<\/span><span class=\"hljs-string\">'rgb:00000020'<\/span>},      \n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">border<\/span>=&gt;<\/span><span class=\"hljs-string\">'6px_solid_rgb:00000020'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">gravity<\/span>=&gt;<\/span><span class=\"hljs-string\">'north'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">y<\/span>=&gt;<\/span><span class=\"hljs-number\">0.1<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">flags<\/span>=&gt;<\/span><span class=\"hljs-string\">'layer_apply'<\/span>}]},\n{:<span class=\"hljs-function\"><span class=\"hljs-params\">transformation<\/span> =&gt;<\/span>\n   &#91;{:<span class=\"hljs-function\"><span class=\"hljs-params\">width<\/span>=&gt;<\/span><span class=\"hljs-number\">1280<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">height<\/span>=&gt;<\/span><span class=\"hljs-number\">720<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">video_codec<\/span>=&gt;<\/span><span class=\"hljs-string\">'h264:main:3.1'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">bit_rate<\/span>=&gt;<\/span><span class=\"hljs-string\">'5500k'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">crop<\/span>=&gt;<\/span><span class=\"hljs-string\">'limit'<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">overlay<\/span>=&gt;<\/span><span class=\"hljs-string\">'text:Arial_24_bold:1280x720--bitrate:5.5MB'<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">color<\/span>=&gt;<\/span><span class=\"hljs-string\">'white'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">background<\/span>=&gt;<\/span><span class=\"hljs-string\">'rgb:00000020'<\/span>},\n    {:<span class=\"hljs-function\"><span class=\"hljs-params\">border<\/span>=&gt;<\/span><span class=\"hljs-string\">'6px_solid_rgb:00000020'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">gravity<\/span>=&gt;<\/span><span class=\"hljs-string\">'north'<\/span>,:<span class=\"hljs-function\"><span class=\"hljs-params\">y<\/span>=&gt;<\/span><span class=\"hljs-number\">0.1<\/span>,\n     :<span class=\"hljs-function\"><span class=\"hljs-params\">flags<\/span>=&gt;<\/span><span class=\"hljs-string\">'layer_apply'<\/span>}]}])\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>After uploading the <code>bb_bunny<\/code> video with an eager transformation requesting to use this <code>hd_debug<\/code> profile in HLS (<code>.m3u8<\/code>) format, you can play the HLS video below natively in your mobile device or in an iOS browser, such as Safari. Give it a try! <br\/><\/p>\n<p><a href=\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/sp_hd_debug\/bb_bunny.m3u8\" target=\"_new\">https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/sp_hd_debug\/bb_bunny.m3u8<\/a><\/p>\n<p><a href =\"https:\/\/res.cloudinary.com\/cloudinary\/video\/upload\/sp_hd_debug\/bb_bunny.m3u8\" target=\"_new\"><img decoding=\"async\" \nalt=\"debug profile\" src=\"https:\/\/res.cloudinary.com\/cloudinary\/image\/upload\/debug_profile_example.jpg\" width=700><\/img><\/a><\/p>\n<p>(If you don\u2019t have a browser that supports HLS, navigate to <a href=\"https:\/\/www.hlsplayer.net\/\">hlsplayer.net<\/a> and paste in the link above.)<\/p>\n<h2>Just Imagine\u2026<\/h2>\n<p>Remember that \u201c<em>moment when<\/em>\u201d moment I described at the start of this post? You\u2019ve been there. I\u2019ve been there. But just imagine that with a couple lines of code to eagerly generate all your adaptive streaming files, your website users won\u2019t have to \u2018<em>be there<\/em>\u2019 anymore.<\/p>\n<p>To learn more, see <a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery#adaptive_bitrate_streaming_hls_and_mpeg_dash\">Adaptive bitrate streaming &#8211; HLS and MPEG-DASH<\/a> and the <a href=\"https:\/\/cloudinary.com\/documentation\/admin_api#manage_adaptive_streaming_profiles\">streaming_profiles method of the Admin API<\/a> in the Cloudinary documentation .<\/p>\n<p><strong>Adaptive bitrate streaming profiles<\/strong> for HLS and MPEG-DASH are supported for all Cloudinary plans, including the <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Free Plan<\/a>. Go ahead, try it out for yourself.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":23386,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[305],"class_list":["post-21438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-video-api"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>HTTP Live Streaming Without the Hard Work<\/title>\n<meta name=\"description\" content=\"Simplify creation of .m3u8 or .mpd files using Cloudinary - automatically generate all of the required video files for HLS and MPEG-DASH video.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTTP Live Streaming Without the Hard Work\" \/>\n<meta property=\"og:description\" content=\"Simplify creation of .m3u8 or .mpd files using Cloudinary - automatically generate all of the required video files for HLS and MPEG-DASH video.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-11-16T17:14:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-02T23:00:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"HTTP Live Streaming Without the Hard Work\",\"datePublished\":\"2016-11-16T17:14:28+00:00\",\"dateModified\":\"2025-03-02T23:00:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA\",\"keywords\":[\"Video API\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2016\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\",\"url\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\",\"name\":\"HTTP Live Streaming Without the Hard Work\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA\",\"datePublished\":\"2016-11-16T17:14:28+00:00\",\"dateModified\":\"2025-03-02T23:00:32+00:00\",\"description\":\"Simplify creation of .m3u8 or .mpd files using Cloudinary - automatically generate all of the required video files for HLS and MPEG-DASH video.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"HTTP Live Streaming Without the Hard Work\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"HTTP Live Streaming Without the Hard Work","description":"Simplify creation of .m3u8 or .mpd files using Cloudinary - automatically generate all of the required video files for HLS and MPEG-DASH video.","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:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash","og_locale":"en_US","og_type":"article","og_title":"HTTP Live Streaming Without the Hard Work","og_description":"Simplify creation of .m3u8 or .mpd files using Cloudinary - automatically generate all of the required video files for HLS and MPEG-DASH video.","og_url":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash","og_site_name":"Cloudinary Blog","article_published_time":"2016-11-16T17:14:28+00:00","article_modified_time":"2025-03-02T23:00:32+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash"},"author":{"name":"","@id":""},"headline":"HTTP Live Streaming Without the Hard Work","datePublished":"2016-11-16T17:14:28+00:00","dateModified":"2025-03-02T23:00:32+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA","keywords":["Video API"],"inLanguage":"en-US","copyrightYear":"2016","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash","url":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash","name":"HTTP Live Streaming Without the Hard Work","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA","datePublished":"2016-11-16T17:14:28+00:00","dateModified":"2025-03-02T23:00:32+00:00","description":"Simplify creation of .m3u8 or .mpd files using Cloudinary - automatically generate all of the required video files for HLS and MPEG-DASH video.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/plug_and_play_adaptive_bitrate_streaming_with_hls_and_mpeg_dash#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"HTTP Live Streaming Without the Hard Work"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1647045707\/50_adaptive_bitrate\/50_adaptive_bitrate.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=21438"}],"version-history":[{"count":15,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21438\/revisions"}],"predecessor-version":[{"id":37097,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21438\/revisions\/37097"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/23386"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=21438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=21438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=21438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}