Recently I’ve been working on a system to playback HTTP Dynamic Streaming (HDS) content locally, from a single file. If you have seen my previous post on HTTP Dynamic Streaming (HDS) or are already familiar with it, you know that the media item is packaged in such a way that there are multiple segments and fragments that make up an entire media item. Similar to the image below:
A sample segment and its fragments
The system involves a client, an AIR application, requesting some remote HDS content (basically an F4M file). The client downloads the fragment data for the media item and writes it to disk. Instead of writing each fragment to a separate file, the fragment data is written to a single file. This part alone is pretty straight forward. The tricky part is when you want to play the content back.
A few problems needed to be overcome to get playback to work. First, to get the local fragments to playback, I needed to fix an issue in the OSMF framework that only accounts for requests for remote HDS fragments. This was accomplished by overriding the HTTPStreamingIndexHandler class and removing some code that only accounted for “HTTP” being part of the request. Second, and more importantly, I needed to intercept the request for the HDS fragment that is generated when OSMF is playing back HDS content, use the request to determine where the fragment’s byte data exists in local file that was created when the client downloaded the content. Then return this byte data to the rest of the OSMF code that parses it into FLV data to pass onto the appendBytes() method on the NetStream.
On top of that, we wanted to allow for playback while the fragments were still downloading. On OS X this wasn’t a huge deal because AIR on OS X can have multiple FileStreams open the same file. On Windows the file is locked when it is opened by the first FileStream that open the file. This is a problem because I want to write the downloaded fragment data to the file and I want to read fragment data for playback at the same time. This issue was solved with a little utility library that uses only 1 FileStream instance and manages read and write requests by queuing up requests and only allowing the requests to happen 1 at a time.
It was a huge headache and lots of time was spent in the OSMF rabbit hole but, I now have a great File IO library for AIR and I’m able to download and playback HDS content locally.