Resumable Downloads with AIR

I`m just developing an AIR project were the client needs to be able to synchronize big loads of data. So I thought it would be cool if the user can pause and resume downloads.
I first thought that this would not be possible but then i looked at the Adobe Media Player and he does it as well (Look into the Download Manager). The trick seems to be easy.
After a quick search through the Http specification i found out that you can write a custom header to use with the URLStream class. With Http specification 1.1 you can define a range of bytes you want to download so you don`t have to start from the beginning.
Here is how a sample Request looks like:
GET /files/richflv/help/ExportOptions.flv HTTP/1.1
Referer: app-resource:/LoadingTest.swf
x-flash-version: 9,0,60,153
Range: bytes=1200000-1300000
User-Agent: Mozilla/5.0 (Windows; U; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0
Host: www.richapps.de
In Actionscript we can write a custom header like this:
var header1:URLRequestHeader = new URLRequestHeader(“range”,”bytes=”+currentBytesPosition+”-“+toRange);
var re:URLRequest = new URLRequest(downLoadURL);
re.requestHeaders.push(header1);
currentBytesPosition = toRange;
urlStream.load(re);

This should work with most servers/files. To make sure it works you can first make a request and analyse the response header. It should include something like this:
Accept-Ranges: bytes

I think you get the idea! This is pretty powerfull especially if you want to synchronize big chunks of binary data and the client closes the client in between.
On the next startup you can simply resume  the download at the position were the client closed your AIR app. There are so many hidden goodies in AIR/AS3.0!

Comments

19 responses to “Resumable Downloads with AIR”

  1. 1 Avatar
    1

    Nice Soft

  2. Mudit Avatar
    Mudit

    This is a really good find.
    I wonder can this be employed to progressively download a FLV(not from the start) into a flash video player.

  3. Jason Nussbaum Avatar

    I was looking into this today, as well. The documentation for the URLRequestHeader class states that there is a list of headers that are not allowed; included in this list was the “range” header. Do you know if this is allowable specifically in AIR, or if the documentation is plain wrong?

    As for using this to progressively load an FLV – this is the tactic Google Video or YouTube uses (can’t remember which, might be both now) to allow seeking within a progressively loaded FLV, even to places in the FLV that haven’t been loaded.

  4. Benjamin (Admin) Avatar
    Benjamin (Admin)

    Progressive download is possible with flv files out of the box you don`t need this header stuff for this. Using my technique for progressive download would not work because currently it`s not possible to pass bytes to the NetStream/Video classes. This is just interesting for downloading stuff.

    @Jason: I`ve not tested if it works in the flash player but i can imagine that it only works in AIR.

  5. Christian Pfeil Avatar

    You are crazy man! Keep on going. Would be nice if you come up with a sample application to show how the whole stuff works.

    regards,

    Christian

  6. Chrisz Avatar
    Chrisz

    Hallo Benjamin,

    da mein English nicht so gut ist, Frage ich einfach mal nach.

    Kann man mit dieser Methode beim laden eines flv files außerhalb des Puffers springen ?? Ich benutze lighttpd. Mit dem JW Flashplayer funktioniert das Wunderbar. Nur in Flex bekomme ich das nicht am laufen. Hast du eine Idee für mich ?

  7. Benjamin (Admin) Avatar
    Benjamin (Admin)

    @Chrisz: Dieser Post hat nichts mit deinem Problem zu tun. lighthttp funktioniert natürlich auch mit flex aber dafür müsstest du einen eigenen Player schreiben. Du solltest dir unbedingt auch mal Red5 anschauen. Damit kannst du dann echtes streaming machen und es ist umsonst.

  8. Erik Avatar
    Erik

    @Jason, @Benjamin: According to the Flex 3 API docs:

    “In the Adobe® Integrated Runtime, content in the application security sandbox (such as content installed with the AIR application) can use any request headers, without error. However, for content running in the Adobe Integrated Runtime that is in a different security sandbox, or for content running in Flash® Player, using following request headers cause a runtime error to be thrown, and the restricted terms are not case-sensitive (for example, Get, get, and GET are each not allowed):

    Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Connection, Content-Length, Content-Location, Content-Range, Date, Delete, ETag, Expect, Get, Host, Keep-Alive, Last-Modified, Location, Max-Forwards, Options, Post, Proxy-Authenticate, Proxy-Authorization, Public, Put, Range, Referer, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version.”

  9. William from Lagos Avatar
    William from Lagos

    Could you please provide any form of sample source files showing how this (resuming downloads) can be done

  10. deus.ex Avatar
    deus.ex

    As i can see the logic is following
    //——————————
    //start download
    var request:URLRequest = new URLRequest(downLoadURL);
    var urlStream:URLStream = new URLStream();
    urlStream.load(request);
    …………..
    //pause?
    urlStream.close();
    ……..
    //resume your code
    var header1:URLRequestHeader = new URLRequestHeader(“range”,”bytes=”+currentBytesPosition+”-“+toRange);
    var re:URLRequest = new URLRequest(downLoadURL);
    re.requestHeaders.push(header1);
    currentBytesPosition = toRange;
    urlStream.load(re);
    //——————————-

    if I’m right – resumed download urlStream will have only part of data (from “currentBytesPosition” to “toRange”) but previously loaded data will be lost.
    Please let me know if I’m doing something wrong.
    Thanx.

  11. Benjamin (Admin) Avatar
    Benjamin (Admin)

    Yeah that`s correct but with AIR you can save the bytes locally and put them together again…

  12. deus.ex Avatar
    deus.ex

    Thanx! Don’t know why but I didn’t think about storing parts of downloaded data on one ByteArray:). Thanx again

  13. Freddy Avatar

    There is a very high chance I will be using this to pause/resume downloads.

    Being able to “pause” downloads is also a way to get around ongoing downloads blocking the connections for an in app browser. Any alternate tip to achieve that? 🙂

  14. vkwave Avatar

    Thanks for sharing this idea. i am working on the same and got new idea to work with my task. If i face any issue in my project growth, can i post it here to get help?

    Thanks

  15. […] flv, etc) and save to the user’s computer. Big Thanks to Benjamin Dobler for his blog post Resumable Downloads with AIR. Tags: AIR, ByteArray, FileStream, Flex 4, URLRequest, URLRequestHeader, […]

  16. Mariush T. Avatar

    Great tutorial!
    I just made a live demo of Resumable File Downloader(AIR app with source code).

  17. Shaffe Avatar
    Shaffe

    Nice tips. Thanks !

  18. Penelope Mccarthy Avatar

    This web site (Resumable Downloads with AIR : Richapps) won’t render correctly on my blackberry – you may want to try and repair that 🙂 Penelope Mccarthy

Leave a Reply

Your email address will not be published. Required fields are marked *