How to Build Online Video Players
The netStatusHandler method creates a switch over the event.info.code property of the NetStatusEvent object. There are dozens of different events that could be handled in this method, but the two most common are NetConnection.Connect.Success and Netstream.Play.StreamNotFound. The success event indicates that the NetConnection is ready. The StreamNotFound event indicates that a 404 not found error was returned when trying to play the video. In this example, when the success event is received, the connectStream() method should be called.
The connectStream method creates an instance of the NetStream class called stream and has the NetConnection instance passed to it. Next, the client property of the stream object is set to this, which tells the stream where its callback methods are located. In this example, the onMetaData and onPlayStatus methods are the specific methods needed by the client.
Next an instance of the Video class is created. This is the surface on which the actual playback occurs. The stream is attached to the video with the attachNetStream() method. Finally, the play() method of the stream is invoked and the video is attached to the display list.
This particular example shows a progressive download scenario. If this were a file from a media server via one of the Real Time Protocols (RTMP, RTMPE, etc.), the connect method of the NetConnection object would be passed a URL to the server.
HTTP streaming to Flash is more difficult; it involves downloading individual files and handing them to the appendBytes method of the NetStream class. While you can do this on your own, it is much simpler to use a framework such as OSMF (Open Source Media Framework) if you need HTTP Streaming in Flash.
HTML
Unlike Flash, playing a file via progressive download is trivial. Here is a simple sample.
<html>
<head>
<title>Sample HTML5 Progressive download</title>
</head>
<body>
<video src=”http://techslides.com/demos/ sample-videos/small.mp4” controls autoplay></ video>
</body>
</html>
Inside an HTML page, a video tag is created and pointed at a valid MP4 file. Optional attributes of the video tag can indicate that user interface elements should be included (controls) and that the video should start automatically (autostart).
Streaming to HTML varies based on the browser. Safari on MacOS (and iOS) allows for an HLS manifest to be specified as the source of the video tag. The manifest file (.m3u8) can specify several different video sources; the browser itself determines which source to play and when to switch between sources. Many modern browsers (including Chrome, IE11, Safari8, and Opera) support Media Source Extensions (MSE), which allow for individual segments of video to be downloaded and handed to the browser. Before each segment is downloaded, computations can determine which bitrate to use, allowing for adaptive streaming logic to be built into the application. While no production version of Firefox currently supports MSE, some prerelease versions do.
A basic MSE player looks like this (Figure 2). In this example, variables hold mimetype and codec information about the video. An instance of the MediaSource class is created and other variables are declared that will hold data references to the sourceBuffer, current segment number, and maximum segment number. As the page loads (as handled in the window.onload function), the startup() method is called.
In startup(), event listeners are added to the MediaSource instance and a reference is created to the video object that is declared in the HTML. Lastly, the MediaSource is set to be the source of the Video object.
When the sourceopen event (or webkitsourceopen, depending on browser implementation) occurs, the opened() method is called.
In opened(), the mimetype and codecs are concatenated into a variable, which creates a source buffer. An XMLHttpRequest object is created, which will be used to load the individual segments. The first request with the XMLHttpRequest object is used to load the initialization file, which is needed to inform the video tag about the type of video being played. An event handler follows, which is called automatically as the file is done loading. The contents of the response are read into a Uint8Array, which is appended into the sourceBuffer. An eventHandler is added on the sourceBuffer, so it can react to the updateend event.
Lastly, the send() method of the XMLHttpRequest object is called, instantiating the request.
When the sourceBuffer is done accepting the header, the loadSegment method is called.
In loadSegement(), we are checking if the current segment number is still less than the maximum segment number. (In this simple example, there are 65 segments to the video. In a more realistic scenario, the number and location of the segments would be specified in a manifest file.) If the segment is still in range, the getSegment() method is called with the segment number. When that is done, the segment number is incremented.
The getSegment() method creates a new XMLHttpRequest object and specifies the URL of the next segment in the open method. A similar onload method is used to read and append the segment. As each segment is appended into the sourceBuffer, the updateend event fires, which continues the process until all the segments have loaded.
While this simple approach demonstrates the basics of working with Media Source Extensions, there is much more complexity which is routinely needed in modern applications (ABR logic, multichannel audio, seeking, DVR, DRM, advertising, analytics, etc.). Fortunately, open source projects such as dash.js provide a framework that includes these features in an extensible format so they can be customized as needed for each project.
As you can see, there are many different options to consider when deciding to implement a video player. One of the main things to consider is which browsers you need to support. If you can handle supporting just the latest HTML5 browsers, an MSE-based player will probably suit you well. If you also need to support earlier browsers, you should consider a plugin-based approach, such as Flash, or perhaps a hybrid approach which can use Flash for those without MSE capabilities, and HTML5/MSE for those with supporting browsers.
[This article appears in the 2015 Streaming Media Industry Sourcebook.]
Related Articles
Steve Heffernan explains how to build a customized HTML5 player. Watch this for everything you need to know.
21 Sep 2012
Two young but seasoned HTML5 Video experts tell viewers why they should use HTML5 Video and guide them through the required code in this presentation.
03 Jun 2011
Companies and Suppliers Mentioned