Creating Files through BlobBuilder
As Web sites transition more and more into Web applications, working with files in meaningful ways is becoming increasingly important. Starting with Platform Preview 2, IE10 includes support for the File API, enabling developers to read and slice files on the client. Platform Preview 4 adds support for BlobBuilder, a way for developers to create new files. IE10 also has two new methods that allow the user to save blobs to their computer, enabling great end-to-end experiences when working with client-resident data.
Over on the IE Test Drive, we have a fun piano demo showing off BlobBuilder and File API capabilities. When you press notes on the piano, the site constructs two files: an mp3 music file and an SVG file of the musical score. You can see how the size of both files change each time you press a note. Press the play button to listen to your song, or download either the music file or the SVG score file by pressing the links just above the piano keys. In the rest of this blog post I’ll go through how the demo works, focusing on the capabilities of BlobBuilder and File API.
BlobBuilder Capabilities
BlobBuilder, like the name implies, is a way to build blobs on the client. The main method to do this is append
. The append
function accepts three data types:
- Blob objects
- Plain text
- Array Buffers
The piano demo creates the mp3 file by appending blobs together, using one blob for each note. The demo creates the SVG file of the musical score by appending text that contains the SVG source.
getBlob
is another method available on the BlobBuilder object which returns a blob object containing all the items previously appended. Here is a very simple example that uses BlobBuilder to create a text file:
// The BlobBuilder constructor is prefixed in all browsers.
// Use MSBlobBuilder in IE, MozBlobBuilder in Firefox, and WebKitBlobBuilder in WebKit-based browsers.
var bb = new MSBlobBuilder();
bb.append("Hello World!");
var blob1 = bb.getBlob("text/plain");
One thing to note about the getBlob
method is that when you call getBlob
in IE10 and Firefox, it will clear out the contents of the BlobBuilder object, so the next time you call append it will be as if you were appending into a new BlobBuilder object. WebKit does not currently clear out the contents of the BlobBuilder after calling getBlob
. Consider this example:
var bb = new MSBlobBuilder();
bb.append("Hello World!");
var blob1 = bb.getBlob("text/plain");
bb.append("BlobBuilder is great");
var blob2 = bb.getBlob("text/plain");
In all browsers, blob1 will contain the text “Hello World!
”. However, blob2 will be different. In IE10 and Firefox, blob2 will contain the text “BlobBuilder is great
” while in WebKit-based browsers it will contain the text “Hello World!BlobBuilder is great
”. This discrepancy is still under discussion in the Web Applications working group.
Getting Blobs via XHR
The File API makes it easy to access files selected by the user, something I demonstrated in the Magnetic Poetry demo. This is great when you want to incorporate the users own data into your site. However, in the piano demo, I needed the note files to be built into the demo. When you want to work with blobs but you want to supply the data, you can use XHR.
New to IE10 is the XHR responseType
property. The responseType
property supports four values: blob
, array buffer
, text
, and document
. In the piano demo’s initialization method - getBlobs()
- you’ll see the following:
var req = new XMLHttpRequest();
var url = 'PianoNotes/AllNotes2.mp3';
req.open('GET', url, false);
req.responseType = "blob";
req.onload = function () { /* ... */ };
req.send(null);
One thing you may notice is that the demo only makes a single XHR request. It only downloads one file which contains all the notes used in the demo. However, when you press a key in the demo, only a single note plays and the site appends only a single note to the mp3 file. To make that work, after downloading the file containing all the notes, the site slices the file using the File API slice
method and extracts 24 individual notes. This is a great performance savings versus having to download 24 individual files.
Creating the Music File
Once I have a blob for each note in the demo, creating the mp3 file is easy. Each time you press a key I call:
musicBlobBuilder.append(noteBlob);
In order to update the file size, I get the blob and then get the file size.
var musicBlob = musicBlobBuilder.getBlob("audio/mp3");
// display musicBlob.size
Lastly because I know that the BlobBuilder object was cleared out when I called getBlob
I just append the blob back in:
musicBlobBuilder.append(musicBlob);
Creating the SVG File
Each time you press a key in the demo, you see a note added to the musical score. The musical score is drawn by a single SVG element contained within a div with an id of “scoreContainer.” Each time you press a key, script runs which adds a note to the SVG element and then the SVG file is created by appending the source:
svgBlobBuilder.append(document.getElementById("scoreContainer").innerHTML);
var svgBlob = svgBlobBuilder.getBlob("image/svg+xml");
// display svgBlob.size
In this case, I don’t refill the svgBlobBuilder because I want to start with a clean slate the next time the user presses a key.
Saving Files to Disk
The last part of the demo is saving the files to disk. When you press the “Music File” and “Musical Score File” links on top of the piano keys you will be able to save the file though an experience that feels just like downloading a file:
Note that the notification bar is not available in the Platform Previews. Instead, a save dialog is presented.
Each link calls either saveSong()
or saveSheetMusic()
. Looking into each of these methods will reveal that they use the msSaveOrOpenBlob
function:
window.navigator.msSaveOrOpenBlob(svgBlob, "MusicScore.svg");
msSaveOrOpenBlob
and msSaveBlob
are two methods available in IE10 which let sites ask the user to save a blob to their computer.
Calling msSaveOrOpenBlob
will provide an option on the notification bar to open the file in addition to saving or canceling. Calling msSaveBlob
only provides the option to save the file or cancel. Though these functions are not yet included in any standard, we believe they are extremely useful for writing end to end scenarios with blob data and hope that they might become a standard at some point.
Creating the Piano demo was a fun experience and I’m excited to see how you will use BlobBuilder. Let us know what you think!
—Sharon Newman, Program Manager, Internet Explorer
Comments
Anonymous
January 27, 2012
"In IE10 and Firefox, blob2 will contain the text “BlobBuilder is great” while in WebKit-based browsers it will contain the text “Hello World!BlobBuilder is great”. This discrepancy is still under discussion in the Web Applications working group. " Perhaps a peekBlob method is warranted, if getBlob must clear the blob too. "When you press the “Music File” and “Musical Score File” links on top of the piano keys you will be able to save the file though an experience that feels just like downloading a file: " It's ok, except I'm not sure Joe Internet User will know what "about:blob" means in the notibar (with all the cross-site scripting stuff the IE team has mentioned, he might even think it's an external attack!). Better to just say "Do you want to open or save FileName.ext (123 KB) generated by piano.example.org?" in that case, I think...unless Joe can type about:blob to go there later?Anonymous
January 27, 2012
I think "getBlob" should be called "detatchBlob" if it has transfer of ownership semantics.Anonymous
January 27, 2012
The comment has been removedAnonymous
January 27, 2012
The file API makes me think of XMLHttpRequest 2 which has also been added to IE 10. Unfortunately without AJAX based file uploads the only way to prevent the page from redirecting and thus interrupting what the user is doing is to use an iframe unfortunately so a good article that could be shared here is how to do AJAX based file uploads.Anonymous
January 27, 2012
I think this is a delightful article, Sharon. Don't pay any mind to comments from the asdf crowd (although his comment was cute... I am a little more concerned about John Bilicki III's comment... I don't know enough, nor am I using IE at the moment, to validate it). This is the sort of engaging thing that I like to read about. Thank you!Anonymous
January 27, 2012
Will IE 10 support FileWriter API ?Anonymous
January 28, 2012
The comment has been removedAnonymous
January 29, 2012
Does this mean that if Microsoft has time to play with a new Blob API that it has already finished fixing the bugs and missing API support for stuff that matters? e.g. what is the status on classList? caniuse.com This would be very handy to use across all browsers but in IE we still have to use a polyfill because IE hasn't published a browser that supports it yet!Anonymous
January 30, 2012
Guys it clearly has to be called popBlob! No really, I don't care, js standarts apis always looked weird =)Anonymous
January 30, 2012
@Carter, sorry, I don't think they have finished fixing everything that matters. Even basic Javascript like "prompt" is fundamentally broken (and has been for many years), yet Microsoft have said they don't intend to fix it ( connect.microsoft.com/.../javascript-prompt-doesnt-work-properly ).Anonymous
February 04, 2012
Carter, thanks SO much for including that URL for caniuse in your comment blogs.msdn.com/.../creating-files-through-blobbuilder.aspx It is an excellent website! I've used Modernizer and similar services for checking HTML well HTML5/CSS3 etc support, but never saw an independently maintained summary of browser capabilities by version, in tabular form for easy release version/ date comparisons.