Client Pay Portal
 background video using azure media services

Implementing Background Video with Azure Media Services and Media Player

Recently, we had a need to provide very high-quality video as the background of a website homepage. You’ve probably seen this effect around in the last year or so, taking advantage of new technologies like HTML5 and the ready availability of cloud-based video solutions. Some examples are (my personal favorite, being a sailor) Y.CO, Tool, and bienvillecapital.com, among others. Many solutions like this use Amazon Web Services with Cloudfront or Vimeo for Business or another streaming site, or a video platform like Brightcove Video Cloud.  However, the particular site we were working on was already deployed to Azure Web Apps, so it was natural for integration, delivery and billing to consider the Azure Media Services platform.

(*Note to those developers in need of quick answers: skip to the Configuration (anchor) and Implementation (anchor) sections below for the goods!)

The Need

If you’ve looked at the above websites, you can quickly guess the need we were presented. These videos are placed in the website as the background of the above-the-fold section of the homepage, responsively sized to fit your screen and window. That means they are a significant visual component of the first impression of the website for homepage visitors. In this situation, there can’t be any compromises in either quality or load time – good looking video delivered instantly is absolutely required.

Solution Architecture

Like most of Azure, Azure Media Services is a powerful platform with a lot of options and a lot less out-of-the-box turnkey functionality than a more single-purpose tool like Brightcove or Vimeo. For our purposes, an immediate integration with the Azure Web App wasn’t necessary for the MVP launch of the website, but the availability of the API and the tight integration within the Azure platform will allow some pretty cool future features for site managers and visitors alike. That meant that our solution needed to include:

  • A Media Services account as the central hub,
  • A Storage account to hold video assets, both original and encoded,
  • Video assets served to every browser and bitrate that a visitor’s device and connection might require,
  • A streaming endpoint from which to serve the video assets,
  • A CDN account to distribute the assets and give ourselves a speed edge
  • A media player capable of abstracting the browser and bitrate selection process for each visitor.

Fortunately, the Azure management portal allows both configuration of all of these elements and an interface for video asset management tasks when the programming API isn’t being used.

The Media

A video streaming solution isn’t very useful without media! Our video media management approach followed the standard rules of thumb:

  • Start with the highest resolution asset you can. Go broadcast quality, or get an MP4 at 1080p or better with a 20-50Mbps bitrate.
  • Serve assets that can be streamed with the least load time possible – nobody likes to watch a website loading indicator!

There are a lot of media streaming formats out there (as a longtime web developer, I’ve always felt that video formats were needlessly complex). MP4 vs. webm, or streaming through MPEG-DASH, Microsoft’s Smooth Streaming, or HTTP Live Streaming all have strengths, weaknesses and adoption issues. Fortunately, Azure Media Services provides a dynamically packaged, adaptive bitrate MP4 format encoding. This encoding allows the media player to dynamically choose the streaming mechanism from all of the ones listed. Score one for hands-off!

 
standards comic strip

There is a cost tradeoff to the hands-off dynamically-packaged output format. The source file is encoded once to an MP4 output format but is not also stored as each of the available streaming formats listed above. Instead, the video is output at demand time in the streaming format determined by the client player. This just-in-time architecture means that at least one 200Mbps streaming endpoint must be reserved.

The Tech

Azure Media Services combines a number of the above requirements for streaming video serving.

  • The video storage is held on a very cheap Azure Storage account.
  • As mentioned above, Media Services provides reserved streaming bandwidth in 200Mbps increments. Having this capacity on tap is a huge advantage as it helps guarantee visitors have a consistent experience of the site’s video, not one that is laggy sometimes and snappy others based on good ol’ Internet Congestion.
    Friends don’t let friends settle for “best-effort” video delivery.
  • Media Services is also pushing video assets to local nodes through Azure CDN. While Azure CDN is an optional add-on (which requires at least one streaming endpoint first), my opinion is that the small cost of the CDN is far outweighed by the benefit of pushing the video content out to the edges near your users. Low quality or stuttering video on a site is far worse, in my view than forgoing video entirely.

Additionally, Azure provides the Azure Media Player, a highly configurable client-side player which selects the right player for a given browser and device. Don’t write that browser detection code for the video yourself! This player has a really broad compatibility matrix for old and new mobile and desktop devices. Whatever the past may be, Microsoft has gotten on board with interoperability in a big way – and they even go ahead and admin that IE8 and lower aren’t going to be supported.

The Configuration

Ok, let’s burn out some screenshots now. Follow along at home!

1. Create a Media Service and a Storage Account in one swoop (if you don’t have one already). Name it something smart, because it’ll become part of your URLs for certain encoding types.

azure media services start window

2. Wait while the Media Service starts up initially. Go to the Streaming Endpoints pane. The Media Service begins with a default endpoint which has CDN disabled and no streaming endpoints – it would be nice if you could set those up on the first configuration screen too! (cough cough for any Microsoft product owners reading my blog!)

azure media services streaming endpoints window

3. Stop the Streaming Endpoint and wait.

stop azure media services streaming endpoint

4. Choose to enable CDN on the endpoint. This will automatically add one streaming unit (giving the 200Mbps reserved output and the ability to serve dynamically-packaged video streams). Once the CDN addition is successful, start the endpoint again. When Microsoft says this can take up to 90 minutes, they really do mean it. 

azure media services cdn option

5. While you’re waiting, go add an encoding reserved unit on the Encoding tab as well. This will speed the encoding process significantly.

azure media services encoding tab

The Implementation

Ok, now we’re in the homestretch. Below is the Azure Media Player code snippets you’ll need, all configured for background video. For those who came here looking for the codez, you’ve found the right place!

First you need to call the player in the <head> of the document.

<link href="//amp.azure.net/libs/amp/latest/skins/amp-default/azuremediaplayer.min.css" rel="stylesheet">
<script src="//amp.azure.net/libs/amp/latest/azuremediaplayer.min.js"></script>

Second, here’s a little CSS magic to help cover the transition from a background image to the video, should your viewers experience any load time delays. Tip: use a still of the first video frame to make this transition look like the picture just came alive. This will be activated through an event listener on within the player itself, below:


            <style type="text/css">
                  #video-viewport {
                        opacity: 0;
                        transition: opacity ease 0.5s;
                        -o-transition: opacity ease 0.5s;
                        -ms-transition: opacity ease 0.5s;
                        -moz-transition: opacity ease 0.5s;
                        -webkit-transition: opacity ease 0.5s;
                  }
            </style>

Next, here is the player call, which goes inside a containing div.


    <div id="video-viewport">
        <video id="azuremediaplayer" class="azuremediaplayer amp-default-skin" width="100%" height="100%"> </video>
            <script>
                  var myOptions = {
                        heuristicProfile: "HighQuality",
                        techOrder: ["azureHtml5JS", "html5", "flashSS", "silverlightSS", ],
                        "nativeControlsForTouch": false,
                        autoplay: true,
                        controls: false,
                        poster: “yourPoster.jpg",
                        logo: { enabled: false }
                  };
 
 
                var myPlayer = amp("azuremediaplayer", myOptions, function () {
                        //resize-to-fit handler code goes here if you’re doing full screen background video
                  });
 
                  //Register for events after initialization not in Ready function to ensure all event are captured
                  myPlayer.addEventListener(amp.eventName.play, _ampEventHandler);
                  myPlayer.addEventListener(amp.eventName.ended, _ampEventHandler);
           
                  myPlayer.src([
                        { src: "http://yourMediaServicesName.streaming.mediaservices.windows.net/CDN-GUID-HERE/videoFileEncodedName.ism/Manifest" },
                  ]);
 
                  function _ampEventHandler(evt) {
                        if ("play" == evt.type) {
                              $('#video-viewport').css("opacity", "1");
                        }
                        if ("ended" == evt.type) {
                              myPlayer.play();
                        }
                  }
            </script>
      </div>

Some notes on the various elements to help explain the choices we made and why you might want to make different ones:

  • The heuristicProfile is explicitly set to high quality. This could add to the load time but will ensure there’s no fuzzy beginning to the video play. Again, erring on showing the static image as long as needed before quality video can begin playing with stutter.
  • The techOrder is key. The azureHtml5JS version of the player is what you want for best performance on the latest Windows and Mac OS’s when using the latest Chrome, Edge or IE browsers. For the fallbacks, we’ve actually altered this from the Azure Media Player suggestion, because we found that Safari 9 on OS X El Capitan plays better with the html5 player than with the flashSS (Microsoft Smooth Streaming video served in a Flash player). Shout out to Erich of MergeWorld who did a ton of legwork to diagnose an issue where Safari would load the Flash player and Azure Media Services thought the video was playing, but instead the Flash player failed to display the content served to it!
  • Autoplay true and controls false help set up our background video scenario. Please for the love of His Noodliness the flying spaghetti monster and any and all other deities, DO NOT PUT SOUND IN THIS BACKGROUND VIDEO! It’s meant for a subtle visual effect so let’s keep it that way!
  • Poster is optional, and actually not used because the auto play setting overrides it.
  • The setting to make the logo go away seems deliberately obtuse. Really really, I don’t want a player watermark please and thank you!
  • The player instantiation call can contain some additional setup Javascript. This is hugely helpful if you need to scale the video to fit the viewport.
  • The ‘play’ action event listener lets us make the smooth transition from the div’s background image to the playing video, once it’s begun.
  • The ‘ended’ action event listener lets us start over looping the video. Make sure your video has a good built-in looping effect!

Note that you should replace the source URL, designated through the src variable, with the dynamically-packaged video asset’s Publish URL. The Publish URL is obtained in the Content tab of the Media Services management console after you’ve created the encoded video asset using the Azure Media Encoder. Follow the Publish Content workflow for the Portal method within the official content management documentation. Just be aware, if the streaming endpoint hasn’t completed starting yet, you won’t be able to Publish the asset and obtain the manifest URL – and, if you’ve just completed the Encoding step from a new source (mezzanine) video file, it will take a while before the Publish option is available for that encoded asset – up to 15 minutes in my experience.

The Outcome

As of this writing, you can view this solution in place on http://www.windcreekmontgomery.com.

Incidentally, if you’re in the area, the Wind Creek resorts are top notch – I’d recommend them even if they weren’t a client! 

Author

Wiz E. Wig, Mascot & Director of Magic
Wiz E. Wig

Director of Magic