martes, 22 de noviembre de 2016

PreloadJS. Get the URL from Blob Object

The past days I was working in a project where we needed to preload many assets (images and videos).

Quickly I found the PreloadJS library, and to be honest this has the most complete features for the mission.

First implementation (Typescript code):

blobUrls: [];
preloader: createjs.LoadQueue;

preloadAssets() {
  this.preloader = new createjs.LoadQueue();
  this.preloader.on("fileload", this.handleFileLoaded, this);

  let video = {id: "video", src: "http://some-place/video.mp4"};
  let image = {id: "image", src: "http://some-place/image.png"};

  this.preloader.loadFile(video);
  this.preloader.loadFile(image);
}

handleFileLoaded(event: Event) {
  let item = event.item;
  this.blobUrls.push(this.preloader.getResult(item.id).src);
}

After that my blobUrls was filled with 2 blob locations ( example: blob:http://some-place/b36ab694-23c7-4026-82e1-0096609445ee)
Then I used the urls to put in my html dom elements video and img. But surprise, this approach just works for videos!!

I spent around 2 days in order to get the same behavior for images, but without fortune. Apparently the src provided for getResult is volatile after the first use (this is just my guess).

The I decided to get my own blob url using URL object (javascript), then finally I fixed the problem with the next code.

handleFileLoaded(event: Event) {
  let item = event.item;
  let blob = this.preloader.getResult(item.id, true);
  let blobUrl = URL.createObjectURL(blob);

  this.blobUrls.push(blobUrl);
}

Now the blob urls are working fine for both images and videos.

The difference between getResult(id, true) and getResult(id), the first one returns a Blob Object, and the last one returns a HTML Dom Object.

That's all for the moment, but I hope to go back here some day to improve this blog entry.