1. --!movie
  2. --!encoding=utf-8
  3.  
  4. global $
  5.  
  6. global gFile
  7. global gConnections
  8.  
  9. ----------------------------------------
  10. -- Accelerated download using multiple concurrent http connections (asynchronous/non-blocking mode)
  11. ----------------------------------------
  12. on startMovie
  13.     _player.debugPlaybackEnabled = 1
  14.  
  15.     -- libs
  16.     $.import("curl")
  17.     $.import("file")
  18.  
  19.     -- config
  20.     tUrl = "http://valentin.dasdeck.com/xtras/curl_xtra/.test/test.mp3"
  21.     tFilename = $.PATH & "download_accelerated.mp3"
  22.     sectionCnt = 4 -- number of concurrent connections to use
  23.  
  24.     -- load section downloader class
  25.     SectionDownloadClass = $.include($.PATH & "section_download.ls")
  26.  
  27.     -- do a quick http head request (sync)
  28.     ch = $.curl.init()
  29.     ch.setOption($.curl.CURLOPT.URL, tUrl)
  30.     ch.setOption($.curl.CURLOPT.HEADER, 1)
  31.     ch.setOption($.curl.CURLOPT.NOBODY, 1)
  32.     res = ch.exec(1)
  33.     ch = VOID
  34.  
  35.     -- parse headers, extract size
  36.     headers = $.curl.parseHeaders(res.readRawString(res.length))
  37.     tSize = integer(headers["Content-Length"])
  38.     if voidP(tSize) then
  39.         put "ERROR: Could't determine download size! Aborting."
  40.         exit -- or switch to single standard GET download?
  41.     end if
  42.  
  43.     if headers["Accept-Ranges"]<>"bytes" then
  44.         put "ERROR: Server doesn't seem to support multiple connections!"
  45.         sectionCnt = 1
  46.     end if
  47.  
  48.     -- create empyt file
  49.     gFile = $.file.fopen(tFilename, "wb")
  50.  
  51.     -- initialize/resize empty file to destination size
  52.     $.file.fseek(gFile, tSize-1)
  53.     $.file.fwritebytes(gFile, bytearray(1))
  54.     $.file.fseek(gFile, 0)
  55.  
  56.     -- if previous initialization didn't work, initialize manually
  57.     --  if $.file.fsize(gFile)<>tSize then
  58.     --      bufSize = 1024*1024 -- 1 MB
  59.     --      buf = bytearray(bufSize)
  60.     --      cnt = tSize/bufSize
  61.     --      repeat with i = 1 to cnt
  62.     --          $.file.fwrite(gFile, buf)
  63.     --      end repeat
  64.     --      restSize = tSize mod bufSize
  65.     --      if restSize then $.file.fwrite(gFile, bytearray(restSize))
  66.     --      $.file.fseek(gFile, 0)
  67.     --  end if
  68.  
  69.     -- download using <sectionCnt> connections
  70.     gConnections = []
  71.     sectionSize = tSize / sectionCnt
  72.     startByte = 0
  73.     repeat with i = 1 to sectionCnt
  74.         if i=sectionCnt then numBytes=sectionSize+(tSize mod sectionCnt)
  75.         else numBytes=sectionSize
  76.         conn = SectionDownloadClass.new(tUrl, gFile, startByte, numBytes, #slotSectionFinished)
  77.         gConnections.add(conn)
  78.         startByte = startByte + numBytes
  79.     end repeat
  80.  
  81. end
  82.  
  83. ----------------------------------------
  84. -- @callback
  85. ----------------------------------------
  86. on slotSectionFinished (section, ok)
  87.     if voidP(gFile) then return -- file already closed
  88.     put "SECTION DOWNLOAD FINISHED:" && section.range && "SUCCESS="&ok
  89.     if not ok then
  90.         put "ERROR: Partial download failed! Aborting."
  91.         $.file.fdelete(gFile)
  92.         $.file.fclose(gFile)
  93.         $.file.gFile = VOID
  94.         gConnections = VOID
  95.         exit
  96.     end if
  97.     gConnections.deleteOne(section)
  98.     if gConnections.count=0 then
  99.         put "TOTAL DOWNLOAD FINISHED, FILE SUCCESFULLY DOWNLOADED!"
  100.         $.file.fclose(gFile)
  101.         gFile = VOID
  102.     end if
  103. end
  104.  
[raw code]