Loading music from a HTTP - this should work BUT doesn't. Help!

So I’m trying to load an MP3 from a HTTP and then write it into the documents folder. Everything works, and you can see the asset in the documents folder, and even select it from the music() command (where you can audition it and it plays!?!), but when you run the code it doesn’t play. You can even copy the file from documents to Dropbox and it plays from there ok, but it should just work as is. It would be very useful as then we could distribute just code and then all images and music can be loaded from the Internet.

Here’s the code:

tune="http://www.amigaremix.com/files/2964/daXX_-_Stardust_Memories_-_daXX_Remix.mp3"

function writeFile(fileName, data)
    local file = os.getenv("HOME") .. "/Documents/" .. fileName
    wFd, err = io.open(file, "w")
   if wFd == nil then
        error("\


Error creating/editing file " … fileName … "

Error: " … err)
end
wFd:write(data)
wFd:close()
print(“File " … fileName … " installed!”)
end

function loadMusic()
    http.request(tune,didLoadMusic)
end

function didLoadMusic(data,status,headers)
    writeFile("test.mp3",data)
    music("Documents:test")
end

@Jon I had a similar problem with this in creating one of my games, and to be honest, I found no way of it working. I eventually had to use a different link for the mp3, try finding a different file, that’s what I would tell you. And also, I tried running your program and I wouldn’t get anything.

@CamelCoder If you look in your documents assets, is there now a test.mp3 file?

@Jon no I didn’t get anything, I called loadMusic in the setup, and it should work, I don’t know why it isn’t though.

@Jon @CamelCoder Here’s the code I used and it worked. After the mp3 file loaded, it started playing the music. I stopped the program and looked in the Documents folder and the mp3 file was there. It took 39 seconds for the file to load.

function setup()
    tune="http://www.amigaremix.com/files/2964/daXX_-_Stardust_Memories_-_daXX_Remix.mp3"
    loadMusic()
end

function draw()
    background(40, 40, 50)
end

function writeFile(fileName, data)
    print("function writeFile")
    local file = os.getenv("HOME") .. "/Documents/" .. fileName
    wFd, err = io.open(file, "w")
   if wFd == nil then
        error("\
\
Error creating/editing file " .. fileName .. "\
\
Error: " .. err)
    end
    wFd:write(data)
    wFd:close()
    print("File " .. fileName .. " installed!")
end

function loadMusic()
    print("function loadMusic")
    http.request(tune,didLoadMusic)
end

function didLoadMusic(data,status,headers)
    print("function didLoadMusic")
    writeFile("test.mp3",data)
    music("Documents:test")
end

@dave1707 yeah, it worked for me, nice catch, the only difference between mine and yours was you assigned the tune variable in your setup, I guess that’s what screwed it up

@dave1707 great, thanks! Good spot. Works fine now.

@dave1707 @Simeon @TokOut dave thanks so much. the code is very useful for me, not only that it can help to download my files to codea, but also I used in my app. in my app, people can download files which are necessory (others are useless for them right now) . so they can press the button to download.

as I asked on top, it will be better that one button is a meaning of one zip file. then only one file will be downed. but zip cannot be used in codea.
so I can only make one button match many files.
I am doing this in the afternoon. meaning will be as following briefly. :

button func is : 
for i= 1, 10 do 
   address =  address[i]   -- this will be a file address on net. there are 10 different address/ files on net. 

   loadmusic(address)  -- 
 end

then I found it can work to :

function loadMusic()
    print("function loadMusic")

then print next same as above. finally only the 10th file is downed.

I think the reason is : maybe , the request command should be only one in a time. the first is stopped by the second, the second is stopped by the third… and the 10th stopped the 9th. and only the 10th worked to the end.

so I am trying to solve, maybe I should rewrite the loadmusic func .

I appriciate if you can give some better and easy method to solve.

thanks so much.

@dave1707 by the way, boss. when I am using code above to download now, during the prcess of downloading, how can I stop download ?

another thing is that is it possible to add lua’s lfs libery / LuaFileSystem to codea ? then we can do more about files manager.

@totorofat I don’t know if there’s a way to send a stop request. There might be, but I don’t use the http function enough to know a lot about it. You might do a google search on it or wait for someone else to answer. As for the lfs, that was mentioned a few releases ago and I thought it was going in, but I haven’t seen it yet. The current IO does a lot but that’s also something I don’t use much anymore either. I always put files in the Codea Dropbox folder so if I need to delete them, I sync them with the Dropbox app and delete them there and resync with Codea to delete them.

@totorofat, @dave1707 - simple way to get the file size but not programmatically. Just use @Jon’s link to the database and the file size is given. So you can eliminate huge files. Also any you have downloaded by syncing from Dropbox can be found with the file app, the trial test.mp3 is 5.7 meg.

mark for “download file and write to local folder”
cannot use search function. so,
I checked so many posts and finally find this. thanks so much.

@dave1707 thanks so much for your code again. it is very good to put files in documents folder. then I need not login dropbox which cannot be login well in my place.

by the way , as the search function here is also has problem. I can only asked directly for 2 questions(I checked 18 pages and did not find result):

  1. is it possible to get the size of file which is in process of downloading?
    then I can draw a process round / or a process bar . or other way to draw ?

  2. I want to put all mp3 file and other files , like txt, in a zip file , after downloaded in app , I can unzip all files (in the zip) to the documents folder . is it possible ?

need your help and codes . appreciate so much to you.

@totorofat As far as I know there isn’t any way to get the size of the file. I don’t know if there’s anything at the beginning of the mp3 file that says what the size of the file is. The only zipping that Codea does is when it exports projects as backups and then that zips everything into one zip file.

@Jon - got the same as @dave1707 on my pad. Using his code I downloaded in 15 secs on my system. File save OK in Documents. Played around with your code, tried the call for loadMusic() after the tune definition to initialise download but no joy. Placed tune and loadMusic() call inside setup and it ran fine.

Didn’t realise you were an old Amiga fan !!!

@totorofat Here’s a version I threw together that lets you have a button for multiple mp3 files. You can tap all the buttons for what you want to download. It shows the names that are waiting to downloaded and also the file that is being downloaded. I don’t know if you’re after something like this or not so I didn’t put a lot of time into it. I just picked 5 small mp3 files to test.

EDIT: Itsaves the mo3 Files in the Dropbox folder with the names you setup in the nameTable.

supportedOrientations(LANDSCAPE_ANY)

function setup()
    rectMode(CENTER)  
    -- table of mp3 files  
    tuneTable={
        "http://www.amigaremix.com/files/2894/laki_-_Shadow_of_the_Beast_-_Death_Scene.mp3",
        "http://www.amigaremix.com/files/2910/EXON_-_Lotus_III_Theme_.mp3",
        "http://www.amigaremix.com/files/2869/Darkman007_-_Dazzler_Cover.mp3",
        "http://www.amigaremix.com/files/2212/Cisskey_-_Turrican_2_-_In_the_water.mp3",
        "http://www.amigaremix.com/files/2010/Sven_Storm_-_Firehawk_Loader.mp3" }
    -- table of names that will be saved for the mp3 files
    nameTable={"Death_Scene","Lotus_III_Theme","Dazzler_Cover","In_the_water","Firehawk_Loader" }
    
    queTable={} -- table of mp3 files waiting to download
end

function draw()
    background(40, 40, 50)
    if #queTable>0 then
        if not downloading then            
            pos=queTable[1]
            tune=tuneTable[pos]
            loadMusic()
        end
    end
    fill(255)
    text("Selection",100,HEIGHT-20)
    for a,b in pairs(nameTable) do
        fill(255)
        rect(100,HEIGHT-60*a,200,50)
        fill(255,0,0)
        text(b,100,HEIGHT-60*a)
    end
    fill(255)
    text("To download",400,HEIGHT-20)
    for a,b in pairs(queTable) do
        text(nameTable[b],400,HEIGHT-50*a)
    end
    if #queTable>0 then
        text("Downloading --  "..nameTable[pos],WIDTH/2,200)
    end
end

function touched(t)
    if t.state==BEGAN then
        for z=1,#tuneTable do
            if t.x>0 and t.x<200 and 
                    t.y>HEIGHT-60*z-25 and t.y<HEIGHT-60*z+25 then
                table.insert(queTable,z)               
            end
        end
    end
end

function loadMusic()
    downloading=true
    http.request(tune,didLoadMusic)
end

function didLoadMusic(data,status,headers)
    writeFile(nameTable[pos]..".mp3",data)
    downloading=false
    table.remove(queTable,1)
end

function writeFile(fileName, data)
    local file = os.getenv("HOME").."/Documents/Dropbox.assets/"..fileName    --ok
    wFd, err = io.open(file, "w")
    if wFd == nil then
        error("\
\
Error creating file " .. fileName .. "\
\
Error: " .. err)
    end
    wFd:write(data)
    wFd:close()
end

@dave1707 I should say many many thanks for your help. I way trying the “for–do” to solve this at first but didnot get a good way yet. when I checked here and find your quick reply. this idea is so good. also let me jump out of the “for” recycle in brain. in same time, your code do more help. I used “downloading=false/true” to update the state of other buttons. the proccess is going faster in these days. millions of thanks again to you !!!