Question #5: What are MSStream and Blob objects in HTML5 and how to they relate to the WinRT classes? (JavaScript only)

Answer: To throw another stream into the river, so to speak, when working with the HTML5 APIs, specifically those in the File API section, we encounter MSStream and Blob types. (See the W3C File API and the Blob section therein for the standards.)

As an overview, the File APIs for Windows Store apps contains a number of key objects:

  • Blob: an piece of immutable binary data that allows access to ranges of bytes as separate blobs. It has size, type, and msRandomAccessStream properties (the latter being an IRandomAccessStream). It has two methods, slice (returning a new blob from a subsection) and msClose (releases a file lock)
  • MSStream is technically an extension of this HTML5 File API that provides interop with WinRT. It lives outside of WinRT, of course, and is thus available to both the local and web contexts an app. The difference between a blob and a stream is that a stream doesn’t have a known size, as it can represent partial data coming from an online request. You can create an MSStreamReader object and pass an MSStream to its readAsBlob method to get the blob once the rest is downloaded.
  • URL: creates and revokes URLs for blobs, MSStream , IRandomAccessStreamWithContentType, IStorageItem, and MediaCapture. It has only two methods: createObjectURL and revokeObjectURL. (Make note that even if you have a oneTimeOnly URL for an image, it’s cached so it can be reused.)
  • File: derived from Blob, has name and lastModifiedDate properties. A File in HTML5 is just a representation of a Blob that is known to be a file. Access to contents is through the FileReader or FileReaderSync objects, with readAs* methods: readAsArrayBuffer, readAsDataURL, readAsText.
  • MSBlobBuilder: used only if you need to append blobs together, with its append method and then the getBlob method to obtain the result.

 

The short of it is that when you get MSStream or Blob objects from some HTML5 API (like an XmlHttpRequest with responseType of “ms-stream,” as you’d use when downloading a file or video, or from the canvas’ msToBlob method), you can pass those results to various WinRT APIs that accept IInputStream or IRandomAccessStream as input. To use the canvas example, the msRandomAccessStream in a blob from msToBlob can be fed into APIs in Windows.Graphics.Imaging for transform or transcoding. A video stream can be similarly worked with using the APIs in Windows.Media.Transcoding. You might also just want to write the contents of a stream to a StorageFile (that isn’t necessarily on the file system) or copy them to a buffer for encryption.

The aforementioned MSStreamReader object, by the way, is where you find methods to read data from an MSStream or blob. Do be aware the these methods are synchronous and will block the UI thread if you’re working with large data sets. But MSStreamReader will work just fine in a web worker.

On the flip side of the WinRT/HTML5 relationship, the MSApp object in JavaScript provides methods to convert from WinRT types to HTML5 types. On such method, createStreamFromInputStream, creates an MSStream from an IInputStream, allowing to take data from a WinRT source and call URL.createObjectURL, assigning the result to something like an img.src property. Similarly, MSApp.createBlobFromRandomAccessStream creates an MSStream from an IRandomAccessStream, and MSApp.createFileFromStorageFile converts a WinRT StorageFile object into an HTML5 File object.

Let me reiterate the URL.createObjectURL, which is essential to create a URI you can assign to properties of various HTML elements, can work with both HTML objects (blobs and MSStream) and WinRT objects (IRandomAccessStreamWithContentType, IStorageItem, and MediaCapture), so in some cases you’ll find that you don’t need to convert a WinRT stream into an MSStream or Blob explicitly–URL.createObjectURL does that automatically. This is what makes it so simple to take a video preview stream and display it in a <video> element. You just set up the MediaCapture object in WinRT, assign the result from URL.createObjectURL on that object to video.src, and then call vide.play() to stream the video preview directly into the element.

 

In Closing

I have to say that when I started looking into this subject, I was just looking to learn a little more about blobs and to finally figure out what one did with a Buffer. But as I don’t like to leave stones unturned, you can see that much more came out of that investigation. I hope it has helped you understand how all these types relate, especially across the HTML5/WinRT boundary


Comments are closed