{"id":22342,"date":"2021-06-01T14:16:28","date_gmt":"2021-06-01T14:16:28","guid":{"rendered":"http:\/\/cloudinary_video_player_drinking_our_own_champagne"},"modified":"2026-03-11T16:49:56","modified_gmt":"2026-03-11T23:49:56","slug":"cloudinary_video_player_drinking_our_own_champagne","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne","title":{"rendered":"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Using a company\u2019s software in-house was made famous by Microsoft\u2019s adoption of the term \u201c<a href=\"https:\/\/en.wikipedia.org\/wiki\/Eating_your_own_dog_food\">eating our own dog food<\/a>\u201d to refer to the request to employees to use the alpha and beta versions of their products. This story, \u201c<a href=\"https:\/\/en.wikipedia.org\/w\/index.php?title=Drinking_your_own_champagne&amp;redirect=no\"><em>Drinking Our Own Champagne<\/em><\/a>\u201d refers to our serving videos created by our Customer Training team with the Cloudinary Video Player to implement a business initiative and enhance site performance.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--info'><strong class='c-callout__title'>Important:<\/strong> <ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/podcasts\">Podcast Webpage<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/github.com\/cloudinary-training\/podcasts\">Code Repo<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary-training.github.io\/podcasts\/\">Demo Webpage<\/a>\n<\/li>\n<\/ul><\/div>\n<h2>The Project: Cloudinary Podcasts<\/h2>\n<p>A Cloudinary cross-functional team with employees from Customer Training and Marketing are working on the initiative of releasing video podcasts biweekly. The subject matter is split between two podcast brands:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/podcasts\"><strong>Dev Jams<\/strong><\/a>,  which showcases projects created by our customers in an effort to get to know them better.<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/podcasts\"><strong>MX Matters<\/strong><\/a>, which serves as a platform for our product team to share information about our evolving product line.<\/li>\n<\/ul>\n<p>The video podcasts are about an hour in length, access to which (both video and audio) are through <a href=\"https:\/\/www.youtube.com\/channel\/UCyRx2h4HjOlcUTSilLqmN1w\">YouTube<\/a>, <a href=\"https:\/\/www.spotify.com\/\">Spotify<\/a>, <a href=\"https:\/\/podcasts.apple.com\/\">Apple Podcasts<\/a>, <a href=\"https:\/\/podcasts.google.com\/search\/cloudinary\">Google Podcasts<\/a>, <a href=\"https:\/\/overcast.fm\/\">Overcast<\/a>, and <a href=\"https:\/\/www.stitcher.com\/\">Stitcher<\/a>. In addition, you can view the videos on a cloudinary.com webpage.<\/p>\n<p>For a superior user experience, we did the following:<\/p>\n<ol>\n<li>Offered smooth-playing, no-buffering streaming with minimal configuration through Adaptive Bitrate Streaming (ABR).<\/li>\n<li>Presented the video collections as a grid with modal popups for easy full-screen viewing.<\/li>\n<\/ol>\n<h2>Definition of ABR<\/h2>\n<p>ABR is a video-streaming technique that can be run in the application layer of the internet: HTTP. Essentially, the video server chunks up the video and the client browser reads them in with HTTP <code>GET<\/code> requests. ABR works by detecting the user\u2019s bandwidth on the client side and adjusting the streaming quality accordingly.  If the client\u2019s network supports a heavier load, the video\u2019s quality is higher. For clients with a lower bandwidth network, ABR lowers the quality of the chunks, resulting in smaller file sizes. The net result is a smooth playback and less or no buffering. Not only does the Cloudinary Video Player help with ABR, but it can also process the various <a href=\"https:\/\/cloudinary.com\/glossary\/video-rendition\">renditions<\/a>, segmenting them into chunks and creating manifests that describe the chunks.<\/p>\n<p>ABR contains two protocols: <strong>Dynamic Adaptive Streaming Over HTTP (MPEG-DASH)<\/strong> and Apple\u2019s <strong>HTTP Live Streaming (HLS)<\/strong>, both of which are operationally and functionally equivalent. The differences lie in device support, e.g., HLS is natively supported in Safari but not in Chrome.<\/p>\n<p>A strength of Cloudinary is its ability to create multi-codec ABR, which means that you can use the Cloudinary Video Player with HLS in all major browsers, e.g., you can build profiles for HLS\/h.264, HLS\/h.265, and DASH\/VP9. Each player would then choose the best codec based on the browser or device it\u2019s running on. Cloudinary\u2019s podcast webpage runs HLS\/h.264.<\/p>\n<p>It\u2019s a good idea to become familiar with both MPEG-DASH and HLS, which offer different browser and video codec compatibilities. Browsers support specific video formats and codecs, which are different algorithms for compression. Also, some advanced codecs require specific formats. Here are the <a href=\"https:\/\/cloudinary.com\/documentation\/video_player_hls_dash\">details<\/a>.<\/p>\n<p>Both MPEG-DASH and HLS define a manifest that lists all the chunks to be requested.<\/p>\n<p>The HLS manifest, which has an extension of <code>m3u8<\/code>, contains two levels of manifest data:<\/p>\n<ul>\n<li>The <strong>master manifest<\/strong> (see the image below for an example), which lists the secondary manifests with the details of the bitrate and video size for the various bitrates.\n<img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/master_manifest.png\" alt=\"master manifest\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"321\"\/>\n<\/li>\n<li>The secondary manifests, which detail the chunks for a given bitrate. The example below shows two <code>climbing.ts<\/code> chunks.\n<img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_600,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/secondary_manifest.png\" alt=\"secondary manifests\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1200\" height=\"743\"\/>\n<\/li>\n<\/ul>\n<p>Your browser\u2019s network tab shows the <code>.ts<\/code> files being loaded and even <a href=\"https:\/\/cloudinary.com\/glossary\/video-preload\">preloaded<\/a>. Mousing over one of those files displays a transformation for both resizing and bitrate, as in this example:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/f_auto,q_auto\/Web_Assets\/blog\/network_tab.png\" alt=\"Network tab\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1600\" height=\"95\"\/>\n<em>Network tab .ts files<\/em><\/p>\n<p>The height and width might vary with the bandwidth based on the ABR algorithm. The transformations shown above were derived from the original MP4 format of the file uploaded to Cloudinary.<\/p>\n<h2>Workflow<\/h2>\n<p>Workflows hinge on the organization\u2019s people and their skill sets. In the case of our podcast videos, the workflow contains two major steps:<\/p>\n<ol>\n<li>The Customer Training team creates, edits, uploads, and transforms the videos, and then hands them off to Marketing.<\/li>\n<li>Marketing works with an agency to code and build the webpages for publication.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/podcast_flow.png\" alt=\"Podcast Production and Delivery Workflow\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"204\"\/>\n<em>Podcast Production and Delivery Workflow<\/em><\/p>\n<p>Cloudinary has the tools for the various workflows. Modularizing the above workflow enables different people to work on different aspects of the product, as in the six-step process below:<\/p>\n<ol>\n<li>Record the video with Zoom.<\/li>\n<li>Process the video with <a href=\"https:\/\/www.descript.com\/\">Descript<\/a>, a tool that cleans up and transcribes the language. Cloudinary\u2019s add-ons from <a href=\"https:\/\/cloudinary.com\/documentation\/google_ai_video_transcription_addon\">Google<\/a> and <a href=\"https:\/\/cloudinary.com\/documentation\/microsoft_azure_video_indexer_addon\">Microsoft<\/a> can create <a href=\"https:\/\/cloudinary.com\/tools\/video-transcription\">video transcription<\/a> files for closed captioning during video upload.<\/li>\n<li>Annotate and enhance the video with visuals.<\/li>\n<li>Upload the video as an MP4 file to Cloudinary.<\/li>\n<li>Execute a script to create the transformations (chunking) that prepare the video for ABR in the Cloudinary Video Player. If feasible in the workflow, you can turn the script into an upload preset for use during upload.<\/li>\n<li>Hand off the public ID of the derived video to Marketing for publication on the website.<\/li>\n<\/ol>\n<h2>Code Development for ABR and Cloudinary Video Player<\/h2>\n<p>This section delves into the back-end and front-end code that creates the derived video chunks and the code for rendering the Cloudinary Video Player.<\/p>\n<h3>Back End: Script for Creating the Derived Video for ABR<\/h3>\n<p>The script below creates the derived videos that can be requested by the Cloudinary Video Player to enable ABR:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>require(&quot;dotenv&quot;).config();\nconst cloudinary = require(&quot;cloudinary&quot;).v2;\n\n\/\/ use explicit because upload takes place at a different\n\/\/ time and is performed by a different person\nfunction explictHDProfile(publicId) {\n  const options = {\n    resource_type: &quot;video&quot;,\n    eager: [\n      { streaming_profile: &quot;hd&quot;, format: &quot;m3u8&quot; },\n      {\n        format: &quot;mp4&quot;,\n        transformation: [{ quality: &quot;auto&quot; }],\n      },\n    ],\n    eager_async: true,\n    eager_notification_url:\n      &quot;https:\/\/webhook.site&quot;,\n    type: &quot;upload&quot;,\n    invalidate: true,\n  };\n  cloudinary.uploader.explicit(publicId, options, function (error, result) {\n    if (error) console.log(&quot;error&quot;, error);\n    else console.log(result);\n  });\n}\n<\/code><\/pre>\n<p>The code is set up as a function that accepts the Cloudinary public ID for the original, uploaded video. By way of explanation:<\/p>\n<ul>\n<li>The function specifies an <code>explicit<\/code> transformation, a Cloudinary term that mandates a transformation to be applied to an uploaded asset as opposed to an on-the-fly transformation that is applied to the original asset during upload. Creating ABR is CPU intensive and done in an asynchronous mode, called <code>eager<\/code> in Cloudinary lingo.<\/li>\n<li>In order for us to be notified that the entire process is complete, we set the <code>eager_notification_url<\/code> key with a website that can capture and report such notifications, in this case <a href=\"https:\/\/webhook.site\/\">webhook.site<\/a>, which is free to use. The site accords users a unique URL for notifications.<\/li>\n<li>A built-in streaming profile created by Cloudinary and a named <a href=\"https:\/\/cloudinary.com\/documentation\/adaptive_bitrate_streaming#representations_generated_for_each_profile\"><code>hd<\/code><\/a> profile specify the transformations. A <a href=\"https:\/\/cloudinary.com\/documentation\/adaptive_bitrate_streaming#predefined_streaming_profiles\">streaming profile<\/a> defines the transformations.<\/li>\n<li>This code leverages Cloudinary\u2019s Node.js SDK. The function <code>cloudinary.uploader.explicit<\/code> calls upon the Upload API\u2019s  <code>explicit<\/code> method to act on a previously uploaded video with the public ID, a unique identifier assigned to an asset as a parameter for the <code>explictHDProfile<\/code> function.<\/li>\n<li>The options, highlighted in the code above, specify that the asset is a video. The <code>eager<\/code> key lists an array of transformations, including a streaming profile that results in multiple transformations. Another transformation is a fallback to MP4, which enables browsers and devices to choose the optimal codec. As mentioned above, the Cloudinary Video Player can accept multiple codecs for ABR. By creating multiple streaming profiles based on different codecs, you can let the device choose the optimal profile. Here, an optimized MP4 is specified as a fallback. In addition:\n<ul>\n<li>You must set <code>resource_type<\/code> to <code>video<\/code> for transformations that are video specific.<\/li>\n<li>Because the workflow dictates that this script be run after the upload, the  <code>eager<\/code> key defines the streaming profile and transformations.<\/li>\n<li>\n<code>eager_notification_url<\/code> monitors the progress of the derived videos.<\/li>\n<li>The type option upload is the default that renders the derived videos public.<\/li>\n<li>The <code>invalidate<\/code> option, set to <code>true<\/code>, invalidates previously cached versions of the derived files, if any, so that they can be replaced.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>Front End: fancyBox for the Webpage<\/h3>\n<p>The cloudinary.com website offers Lightbox features with  a jQuery library called fancyBox. Sean Massa, our front-end developer who implemented this capability, characterized the requirements and solution like this:<\/p>\n<p>\u201cThe challenge for this project was to build a single modal and video player in which the content would dynamically change based on the thumbnail clicked. There were many approaches that seemed to work when we were dealing with just a single video implementation, but when it came to reloading the player with a new video on the fly, we ran into a few walls along the way and had to step back and rethink our approach. The result was to set up an instance of the player, including all the parameters and transformations, explicitly through JavaScript, because adding a mix of JS and inline to the player created issues. We then used data attributes to set the poster and source on click of the desired item. We also had to set the poster before the video source or it would not work.\u201d<\/p>\n<p>As shown in the final code for the front end, we created multiple modal video players on a single page by rendering a single <code>&lt;video&gt;<\/code> tag in the fancyBox popup and then attaching the Cloudinary Video Player code and options to that tag when the user clicks a video link.<\/p>\n<p>For the stripped-down implementation, see the <a href=\"https:\/\/cloudinary-training.github.io\/podcasts\/\">demo<\/a>.<\/p>\n<h3>HTML<\/h3>\n<p>The Cloudinary Video Player interprets the classes that we added to the <code>&lt;video&gt;<\/code> tag, such as <code>cld-fluid<\/code>, which enable the player to fill its container. Located in a single <code>&lt;div&gt;<\/code>, which is rendered but not displayed, the <code>&lt;video&gt;<\/code> tag is specified by <code>sample-video-id<\/code> with which the Cloudinary Video Player locates the tag. You\u2019ll find the tag rendered in your inspector tool but not on the webpage until a fancyBox link has been clicked.<\/p>\n<pre class=\"js-syntax-highlighted\"><code> &lt;div id=&quot;video-wrapper&quot; style=&quot;display: none&quot;&gt;\n      &lt;video\n        id=&quot;sample-video-id&quot;\n        class=&quot;cloudinary-video cld-video-player cld-video-player-skin-dark cld-fluid&quot;\n        controls\n      &gt;&lt;\/video&gt;\n &lt;\/div&gt;\n<\/code><\/pre>\n<h3>Supporting Libraries<\/h3>\n<p>You can access the Cloudinary Video Player code with <a href=\"https:\/\/www.npmjs.com\/package\/cloudinary-video-player\">NPM<\/a> and incorporate it into JavaScript frameworks. For the podcast webpage, we leverage jQuery, fetching all external libraries through a content delivery network (CDN). To use the Cloudinary Video Player, you must import <code>cloudinary-core-shrinkwrap<\/code>, <code>cloudinary-video-player<\/code>, JavaScript, and CSS. For the fancyBox modal, we imported both jQuery and fancyBox JavaScript and CSS.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;script\n      src=&quot;https:\/\/code.jquery.com\/jquery-3.6.0.slim.min.js&quot;\n      integrity=&quot;sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=&quot;\n      crossorigin=&quot;anonymous&quot;\n    &gt;&lt;\/script&gt;\n    &lt;script src=&quot;https:\/\/cdn.jsdelivr.net\/npm\/jquery@3.5.1\/dist\/jquery.min.js&quot;&gt;&lt;\/script&gt;\n    &lt;link\n      rel=&quot;stylesheet&quot;\n      href=&quot;https:\/\/cdn.jsdelivr.net\/gh\/fancyapps\/fancybox@3.5.7\/dist\/jquery.fancybox.min.css&quot;\n    \/&gt;\n    &lt;script src=&quot;https:\/\/cdn.jsdelivr.net\/gh\/fancyapps\/fancybox@3.5.7\/dist\/jquery.fancybox.min.js&quot;&gt;&lt;\/script&gt;\n    &lt;link\n      href=&quot;https:\/\/unpkg.com\/cloudinary-video-player@1.5.1\/dist\/cld-video-player.min.css&quot;\n      rel=&quot;stylesheet&quot;\n    \/&gt;\n    &lt;script\n      src=&quot;https:\/\/unpkg.com\/cloudinary-core@latest\/cloudinary-core-shrinkwrap.min.js&quot;\n      type=&quot;text\/javascript&quot;\n    &gt;&lt;\/script&gt;\n    &lt;script\n      src=&quot;https:\/\/unpkg.com\/cloudinary-video-player@1.5.1\/dist\/cld-video-player.min.js&quot;\n      type=&quot;text\/javascript&quot;\n    &gt;&lt;\/script&gt;\n<\/code><\/pre>\n<h3>JavaScript: Clickable Link for Each and Every Video<\/h3>\n<p>Each video that we want to open with the Cloudinary Video Player in the modal is set up with data that contains the Cloudinary <strong>public ID<\/strong> and <strong>poster link<\/strong>. Even though the Cloudinary Video Player can create a poster from a midpoint frame of the video itself, we elected to link to an image on the podcast webpage. The public ID and poster link are the only data handed off to the JavaScript that opens the Cloudinary Video Player. See the code below.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;div&gt;\n  &lt;a\n    class=&quot;fancybox video-trigger&quot;\n    href=&quot;#video-wrapper&quot;\n    data-video-id=&quot;climbing&quot;\ndata-video-poster=&quot;https:\/\/cloudinary-res.cloudinary.com\/images\/f_auto,q_auto\/v1614262961\/Featured_Podcast\/Featured_Podcast.png&quot;\n  &gt;\n    Watch climbing here\n  &lt;\/a&gt;\n&lt;\/div&gt;\n<\/code><\/pre>\n<p>Note the following:<\/p>\n<ul>\n<li>The  <code>video-trigger<\/code> class attaches a click event.<\/li>\n<li>\n<code>data-video-id<\/code> contains the Cloudinary public ID.<\/li>\n<li>\n<code>data-video-poster<\/code> contains a link to an optimized image on Cloudinary.<\/li>\n<li>\n<code>href<\/code> links to the hidden <code> &lt;video&gt;<\/code> tag.<\/li>\n<li>Clicking the anchor tag below hands off the data to the Cloudinary Video Player.<\/li>\n<\/ul>\n<p>The JavaScript shown below calls the <code>fancybox()<\/code> function, which takes as input all the HTML, JavaScript, and CSS that the <code>videoPlayer<\/code> function attaches to the <code>&lt;video&gt;<\/code> tag. Also note the following:<\/p>\n<ul>\n<li>To call <code>videoPlayer<\/code>, we added the <code>&lt;video&gt;<\/code> tag selector <code>sample-video-id**<\/code>.<\/li>\n<li>We added options to instruct the Cloudinary Video Player to use the <code>hd<\/code> streaming profile or the <code>mp4<\/code> fallback.<\/li>\n<li>Users can control the speeds at which they stream the video with <code>playbackRates<\/code>.<\/li>\n<li>We added a <code>click<\/code> event handler with jQuery. On a user click, we pull <code>data-video-id<\/code> and <code>data-video-poster<\/code> out of the anchor tag.<\/li>\n<li>Finally, we call the Cloudinary Video Player\u2019s <code>source<\/code> function to activate the Video Player.<\/li>\n<\/ul>\n<pre class=\"js-syntax-highlighted\"><code>jQuery(document).ready(function () {\n  jQuery(&quot;.fancybox&quot;).fancybox();\n  \/\/ Initialize player\n  var cloudinaryCld = cloudinary.Cloudinary.new({\n    cloud_name: &quot;cloudinary-training&quot;,\n  });\n  var options = {\n    sourceTypes: [&quot;hls&quot;, &quot;mp4&quot;],\n    bigPlayButton: &quot;init&quot;,\n    muted: false,\n    sourceTransformation: {\n      &quot;hls&quot;: [{ streaming_profile: &quot;hd&quot; }],\n      &quot;mp4&quot;: [{ quality: &quot;auto&quot; }],\n    },\n    playbackRates: [0.5, 1, 1.5, 2],\n  };\n  var media = cloudinaryCld.videoPlayer(&quot;sample-video-id&quot;, options);\n  jQuery(document).on(&quot;click&quot;, &quot;.fancybox.video-trigger&quot;, function () {\n    var videoID = jQuery(this).data(&quot;video-id&quot;);\n    var videoPoster = jQuery(this).data(&quot;video-poster&quot;);\n    media.posterOptions({ publicId: videoPoster });\n    media.source({ publicId: videoID });\n  });\n});  \n<\/code><\/pre>\n<p>The options on the front end depend on the uploaded and derived assets on the backend.  If you are specifying <code>hls<\/code>, ensure that you\u2019ve created the derived <code>m3u8<\/code> and <code>ts<\/code> files in Cloudinary.<\/p>\n<p>If you are implementing this code for your own videos, replace the <code>cloud_name<\/code> variable with your Cloudinary account\u2019s cloud name.<\/p>\n<h3>CSS max-width Property<\/h3>\n<p>Page styling is very important for the setup of this multi-video player webpage. The sample code in the shared GitHub repo is not styled to the extent that the Cloudinary podcast webpage is. In particular, be careful while setting the CSS <code>max-width<\/code> property on the <code>&lt;video&gt;<\/code> tag because that configuration can interfere with full-screen display.<\/p>\n<h2>Conclusion<\/h2>\n<p>There is always a next step in webpage development, but it\u2019s nice to reach a milestone where you feel confident about a workflow and can then focus on the content. As more websites embrace video content, we look forward to learning and sharing with you techniques that enhance the developer experience.<\/p>\n<\/div>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":22343,"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-22342","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>How Cloudinary Set Up Its Podcast Webpage for ABR With the Cloudinary Video Player<\/title>\n<meta name=\"description\" content=\"How Cloudinary created its podcast webpage for Adaptive Bitrate Streaming with the Cloudinary Video Player: the protocols, the workflow, the code.\" \/>\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\/cloudinary_video_player_drinking_our_own_champagne\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d\" \/>\n<meta property=\"og:description\" content=\"How Cloudinary created its podcast webpage for Adaptive Bitrate Streaming with the Cloudinary Video Player: the protocols, the workflow, the code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-01T14:16:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-11T23:49:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\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\/cloudinary_video_player_drinking_our_own_champagne#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d\",\"datePublished\":\"2021-06-01T14:16:28+00:00\",\"dateModified\":\"2026-03-11T23:49:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA\",\"keywords\":[\"Video API\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\",\"url\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\",\"name\":\"How Cloudinary Set Up Its Podcast Webpage for ABR With the Cloudinary Video Player\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA\",\"datePublished\":\"2021-06-01T14:16:28+00:00\",\"dateModified\":\"2026-03-11T23:49:56+00:00\",\"description\":\"How Cloudinary created its podcast webpage for Adaptive Bitrate Streaming with the Cloudinary Video Player: the protocols, the workflow, the code.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d\"}]},{\"@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":"How Cloudinary Set Up Its Podcast Webpage for ABR With the Cloudinary Video Player","description":"How Cloudinary created its podcast webpage for Adaptive Bitrate Streaming with the Cloudinary Video Player: the protocols, the workflow, the code.","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\/cloudinary_video_player_drinking_our_own_champagne","og_locale":"en_US","og_type":"article","og_title":"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d","og_description":"How Cloudinary created its podcast webpage for Adaptive Bitrate Streaming with the Cloudinary Video Player: the protocols, the workflow, the code.","og_url":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne","og_site_name":"Cloudinary Blog","article_published_time":"2021-06-01T14:16:28+00:00","article_modified_time":"2026-03-11T23:49:56+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne"},"author":{"name":"","@id":""},"headline":"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d","datePublished":"2021-06-01T14:16:28+00:00","dateModified":"2026-03-11T23:49:56+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA","keywords":["Video API"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne","url":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne","name":"How Cloudinary Set Up Its Podcast Webpage for ABR With the Cloudinary Video Player","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA","datePublished":"2021-06-01T14:16:28+00:00","dateModified":"2026-03-11T23:49:56+00:00","description":"How Cloudinary created its podcast webpage for Adaptive Bitrate Streaming with the Cloudinary Video Player: the protocols, the workflow, the code.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/cloudinary_video_player_drinking_our_own_champagne#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Cloudinary Video Player: \u201cDrinking Our Own Champagne\u201d"}]},{"@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\/v1649719149\/Web_Assets\/blog\/CldVideoPlayerChampers_22343e8fa8\/CldVideoPlayerChampers_22343e8fa8.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22342","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=22342"}],"version-history":[{"count":8,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22342\/revisions"}],"predecessor-version":[{"id":39863,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22342\/revisions\/39863"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/22343"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=22342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=22342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=22342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}