HTML5 is now firmly entrenched in modern day I.T. life. If you’ve not moved on to the new standards by now, you either work for a government institution (in which case, there is help available 🙂 ) or you’re still living under a rock where Netscape Navigator still rules the waves.
One of the nice things about the new HTML5 standards is the built-in native support for audio and video now.
All the major browser now provide full support (even if they don’t agree on the codecs to use) for all media types, meaning you really don’t have to use Flash/Java or anything like that anymore unless you still insist on supporting IE6/7/8.
With ASP.NET MVC, not only does it enable you to get directly at the HTML generated by your app, it’s also easy to provide your own streaming endpoint to play the media, and use the HTML5 full screen API to play it full screen.
To follow along, you’ll need an empty ASP.NET MVC application. I’m using VS2013 and MVC5. I’m not going to go through the whole project creation process, and your app doesn’t have to be empty if you don’t want to be. I will, however, assume that it is an empty app and that there are no extra NuGet packages already loaded.
I’m also not going to style the pages by using Bootstrap or anything like that. You are, however, free to add them to your project should you want to.
Let’s Get Started
Add a new controller to your project and call it “HomeController”. In this controller, create a standard index function that simply just returns a view, as follows:
using System.Web.Mvc; namespace MVC_Scrap.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } } }
Next, add a view to your project for this controller action (usually by right-clicking “View()” and selecting “Add View”. I’m not using any template or layout pages, so I’m just going to add the following HTML code to my view file:
<!DOCTYPE html> <html> <head> <title> .NET Nuts and bolts video example </title> <style> body { font-family: sans-serif; } </style> </head> <body> <div> <h1>.NET Nuts and bolts</h1> <h2>Full screen video example</h2> <!-- The video tag will go here --> </div> </body> </html>
If you’ve done everything right, and all is working, you should be able to press F5 and see the following:
Figure 1: The HTML text from the preceding listing is displayed
You’ll also need a video file to play—the longer the better, so you can see the streaming working.
I’m just going to use a Music Remix I grabbed off YouTube, called “Spacesynth Megamix 2” (https://www.youtube.com/watch?v=srl3AM64ctg) that I have on my hard drive. (Yes, I listen to some strange stuff….)
One other thing to note too, I’m using Chrome, so I’m not going to go to any lengths to encode two sets of video so all the browsers are covered. I’m simply going to use a video I have to hand that’s already encoded to work in the version of Chrome I have.
If you want to support all the browsers, you’ll need to look at which browsers currently support which formats and codecs. There is still a small margin of difference here, so you’ll need to check who your target audience is and target the video files accordingly.
Add the following controller action to your home controller:
public ActionResult GetVideo() { var videoPath = Request.MapPath("~/Content/music.mp4"); FileStream fs = new FileStream(videoPath, FileMode.Open); return new FileStreamResult(fs, "video/mp4"); }
This will be the endpoint that streams the video.
I’m not going to implement range functionality in this example, so this will be a straightforward stream out to the browser, and won’t be searchable or seekable in any way.
You also can see that I simply just choose to put my video in the Content folder in my application folder and then use Request.MapPath to get an actual real file path to it for the stream.
How you handle this is entirely up to you. You might want to stream from another service; in that case, you’ll want to use a web client, and then stream the output into a memory stream. Or, you might want to pull the data from a database blob.
All that matters is that you return it from the MVC action by using some kind of binary stream response, and the correct mime type.
Now that we have a controller action to stream our video, change the HTML in the previous where it says
<!-- The video tag will go here -->
and replace it with the following:
<video controls="controls" id="videoPlayer"> <source src="~/home/getvideo" type="video/mp4"> </video>
This will add an HTML5 video element with controls to your output, which will then, when you click Play, use your MVC endpoint to stream the video to your browser.
With these parts in place, all we now to do need is to make the browser present the video player as a full screen element.
Before we move on, a small warning. The full screen API is still heavily prefixed in all the modern browsers, and although it works and is implemented, most of it needs vendor-specific prefixes and hacks.
As is always the case with anything like this, check the current status at “caniuse.com” before committing to using it.
http://caniuse.com/#feat=fullscreen
I’m going to use raw JavaScript here in my example, but if you want to start using the full screen API heavily, I strongly advise you to use something like “screenfull.js”.
https://github.com/sindresorhus/screenfull.js
It’ll make your task much easier.
The first thing you want to do is to provide a function to check whether the full screen API is supported. This is easy, but messy.
Add a script block to your MVC view, just before your closing body tag for best performance, and add the following function:
function isFullScreenAvailable() { return ( document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled ); }
This will allow you to check if your browser can do a full screen API in a cross-browser way. The function will return false if there’s no support, and true if there is.
The next thing to do is to ask the element in question (in this case, our video element) to request full screen. Things get even messier here, because not only do we have the vendor prefixes to deal with, but some implementations of the API are spelled using a lower case ‘s’ on ‘screen’ and some using an upper case ‘S’. Hopefully, the browser manufacturers will iron all this out among them; until then, we need another rather ugly function to allow us to request full screen in a cross browser compatible way. Here’s the function to enable full screen on an element:
function requestFullScreen(elementToRequest) { if(elementToRequest.requestFullScreen) { elementToRequest.requestFullScreen(); } else if(elementToRequest.webkitRequestFullscreen) { elementToRequest.webkitRequestFullscreen(); } else if(elementToRequest.mozRequestFullScreen) { elementToRequest.mozRequestFullScreen(); } else if(elementToRequest.msRequestFullscreen) { elementToRequest.msRequestFullscreen(); } }
It’s quite a shame we have to do this too because, as you can see, the function is chainable, which means had we not had to wrap things the way we do, we could have easily just used
document.getElementById('videoPlayer').requestFullScreen();
which is both much tidier and much easier to read.
So, now we have a function to activate full screen and to check if it’s available. To finish off the JavaScript, add the following function your script block:
function makeVideoFullScreen() { if (isFullScreenAvailable) { var videoElement = document.getElementById('videoPlayer'); requestFullScreen(videoElement); return; } alert("Sorry full screen is not available in this browser"); }
and we should now be ready to just call ‘makeVideoFullScreen’ in our JavaScript start up, except there’s one small thing stopping us, and that’s….
Browser Security
Unfortunately, the full screen APIs can only be triggered by user interaction. If you try to put a call into an automatically running JS function, you’ll get something like this in your browser debugging console:
Figure 2: Mistakes appear in your debugger
To use this, you’ll need to add an extra button into your HTML to call this and make it full screen:
<div> <h1>.NET Nuts and bolts</h1> <h2>Full screen video example</h2> <button onclick="makeVideoFullScreen()"> Go Full Screen </button><br/><br/> <video controls="controls" id="videoPlayer"> <source src="~/home/getvideo" type="video/mp4"> </video> </div>
In this demo, however, it’s a bit redundant, because as you can see we’ve enabled the controls on our video player, and in the lower right corner, one of those controls is the video full screen button.
If you don’t have the controls enabled, however, the code we have triggered here by the button we’ve added will put the video into full screen mode, suitable for display on web-enabled TV sets and other similar devices.
Before:
Figure 3: The video displays at its original size
After:
Figure 4: The video displays at full screen
There are ways and means to get around the security. You could, for example, have some other JavaScript initiate a click on the button, and the various forums have differing ideas on using an iFrame to get around it.
I’ll leave you to explore those ideas on your own, however.
Heard of a .NET feature you’ve never seen, or want to know if there’s a way to do X in .NET, drop me a comment below, hunt me down on twitter as @shawty_ds, or come and take a look in “Lidnug”, the group I help run on the Linked-in platform. If I like your question, I may even feature it in one of my posts.