3
votes

I'm desperately trying to find a solution to my problem.

CONTEXT: web application managing audio through WebAudio API; JavaScript+jQuery client side; PHP5 server side. (Sorry I had to chop off part of the code below to keep this post short and readable)

1) I have an arraybuffer object read locally with a filereader obj, and stored locally in a vis.js dataset (that's what does essnetially) as follow...

var reader = new FileReader();
reader.onload = function(ev) { 
            //this store the content into an "audiodata" property of an item part of a vis.js dataset whose name is "clips"
            songModule.createNewClip({  arrayBufferObj:ev.target.result }) 
        };
reader.readAsArrayBuffer(file); 

IMPORTANT: At this stage this object is also passed to a audioContext.decodeAudioData (arrayBufferObj, function (buffer) {..} THAt WORKS Correctly AND GIVE THE RIGHT OUTPUT .. So far so good..

2) I upload the object to the server as follow:

var formData  = new FormData(document.getElementById("temporaryForm"))
...
formData.append('audiodata', clips.get(localClipId).audiodata) 

        $.ajax({                                      
            type: 'POST',
            url: 'addUpdateClip.php',                  
            data:  formData ,                                     
            //dataType: 'json',    
            processData: false, //It’s imperative that you set the contentType option to false, forcing jQuery not to add a Content-Type header for you
            contentType: false,
            cache: false, 
            ...
)}

3) PHP page addUpdateClip.php retrieve and store to a file on the server data:

... $myfile = fopen($uniqueFileName, "w");
if (!fwrite($myfile, getValueFromPostOrGet('audiodata')))  //=$_POST["audiodata"]
fclose($myfile);    

File seems to be correctly written on server

4)..But... Retreiving later directly the generated file on server and passing to the audioContext.decodeAudioData function cause an error "Uncaught SyntaxError: Failed to execute 'decodeAudioData' on 'AudioContext': invalid ArrayBuffer for audioData.". Below the last version of my experiments.

var xhr = new XMLHttpRequest();
                xhr.open('GET', Args.filename , true);
                xhr.responseType = 'arraybuffer';   
                xhr.onload = function(e) {
                  if (this.status == 200) {
                    var responseArrayBuffer=xhr.response
                    if (responseArrayBuffer){                           
                        var binary_string = ''
                        bytes = new Uint8Array(xhr.response);
                        for (var i = 0; i < bytes.byteLength; i++) {
                            binary_string += String.fromCharCode(bytes[i]);
                        }
                        base64_string = window.btoa(binary_string);
                        console.log(base64_string)

                        //var blob = new Blob([responseArrayBuffer], {type: "audio/wav"});

                        songModule.clipAudioDataReceived(newId, blob, Args.waveformDataURL )
                    }
                  }
                xhr.onreadystatechange=function(){console.log(xhr.readyState,xhr.status, xhr.responseText )}
                };
                xhr.send();         

Any clue?

___________To reply to noththeup:___________________

Request URL:http://XXXXXXX/addUpdateClip.php
Request Method:POST
Status Code:200 OK


Accept:`*/*`

Accept-Encoding:gzip,deflate
Accept-Language:it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4,en-GB;q=0.2,fr;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Length:43324
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryaWagMNKe8hprn1pI
Cookie:PHPSESSID=m3okfanf1isbstueih9qq3k6r3
Host:onlinedaw
Origin:http://xxxxxxxxx
Pragma:no-cache
Referer:http://xxxxxxxxx/editSong.php?song_id=9
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payload
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="mode"

add
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="id"

7961f2b6-92cd-be59-f7a7-5c59f1c69fc5
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="song_id"

9
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="group"

13
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="start"

2010-01-01 00:02:58
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="startMs"

748
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="clipDurationMs"

8617
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="audiodata"

[object ArrayBuffer]
------WebKitFormBoundaryaWagMNKe8hprn1pI
Content-Disposition: form-data; name="extension"

wav

Do you see anything strange?
1
Since you're uploading the file directly to your server (without decoding it). Can you check on your server that the file is not corrupted. Can you download the file again and play it outside the browser? I am guessing it is passed back using x-www-form-urlencoded content type. Not sure if it's a good idea to send so much data in the URL. - notthetup
hi, thanks. pls check my edit to this post. - Janko
nottheup, thanks again. Your comment was not the solution, but you pointed me in the right direction. i kept on using the same wave to test, hence file on the server were always the same size.. so I didn't realized that all the time the client was NOt sending the data meant to be cast, but the string "aray buffer". - Janko
I can't find a way to private message you. I am working on a project shares some features with how it looks like you're doing things. Were you accurately matching the arraybuffer to the corresponding file on the client side? were the arraybuffers unique? If so that could be a major breakthrough for me. Thanks! - Z2VvZ3Vp

1 Answers

0
votes

Answer posted by the OP in the question:

I kept on using the same wave file to test, hence file on the server were always the same size(11 bytes). This way I didn't realized that the client NEVER sent the data meant to be cast, but the string "aray buffer". After further digging I noticed that any time I tried to store the array buffer into the dataset form vis.js it was turned into its description: the string "array buffer", which is indeed 11 bytes !

Solution: simply, according to me, the vis.js dataset is not suitable to contain array buffer. I used a parallel JavaScript array instead, and it worked.