0

I'm trying to save an audio file on my server. I record the audio on a iPhone in PCM format and send the data encoded as a Base64 string. I have tried 3 different approaches to saving the file, all 3 create an empty wav file:

Attempt 1:

$file = fopen($filePath, 'w');
fwrite($file, base64_decode($this->data['Voicenote']['audio_data']));
fclose($file);

Attempt 2:

file_put_contents($filePath, base64_decode($this->data['Voicenote']['audio_data']));

Attempt 3:

$audioFile = new File($filePath, true);
$audioFile->write(base64_decode($this->data['Voicenote']['audio_data']));
$audioFile->close();
8vius
  • 5,786
  • 14
  • 74
  • 136
  • 1
    How large is the file? Could it be that PHP simply runs out of memory? You're loading the file into the memory several times: in the `$this->data` and in the temporary return value held by `base64_decode`. You should really try streaming the data instead of buffering it. It might also be wise to use multipart file uploads rather than a POST with form data. – Tom van der Woerdt Apr 24 '12 at 21:49
  • The file is about 1MB, and I tried streaming it from the site using Red5 media server, couldn't get it to work. The multipart form might work, but I also have to make a DB entry when the file is loaded. Any resources you could suggest? – 8vius Apr 24 '12 at 21:56
  • If you're simply writing to a file and storing a link to that file in the DB, you don't have to worry about memory requirements, as long as you're using multipart file uploads. You definitely don't want to use base64 for file uploads, and especially not with PHP, as it means you have to load the entire file in the server's memory. Avoid using functions like `file_get_contents` on a file that's potentially large (let's say >500KB). PHP is horribly inefficient and a simple `base64_decode` on a 1.3MB "string" can take 16MB of memory. – Tom van der Woerdt Apr 24 '12 at 22:01
  • I use base64 because it's the only way I've been able to upload the file to the server appropriately, do you have any tutorials you know of that I can follow? – 8vius Apr 24 '12 at 22:04
  • [ASIHTTPRequest](http://allseeing-i.com/ASIHTTPRequest/How-to-use), one of the most popular iOS libraries that's out there, makes this extremely easy for you. It's even (optionally) asynchronous. – Tom van der Woerdt Apr 24 '12 at 22:14
  • I know about that, it hasn't been updated in over a year, so I'd rather avoid it. And the deal isn't just on the client side, how do I handle it on the server side? – 8vius Apr 24 '12 at 22:22
  • multipart file uploads are what your webbrowser would use when you give it a file input. [PHP.net has some docs about this](http://www.php.net/manual/en/features.file-upload.post-method.php) (Example #2 is pretty much what you need. `move_uploaded_file` also really helps). – Tom van der Woerdt Apr 24 '12 at 22:31
  • Also, ASIHTTPRequest has its latest commit some 2 months ago. https://github.com/pokeb/asi-http-request – Tom van der Woerdt Apr 24 '12 at 22:32
  • Thank you, Tom. I'll look into it, and yes, but the commit was a simple name change, the author said he won't be supporting it anymore on his site a long time ago. Also using the library involves a slight overhaul of my code, since all my requests are done using CFNetwork API, and also I'd have to deal with the reference counting, since my project is under ARC. Still, very much appreciate the suggestion. – 8vius Apr 25 '12 at 03:52

1 Answers1

0

I managed to solve this issue following the code in this question

And in my PHP code I did the following:

move_uploaded_file($_FILES['audio_file']['tmp_name'], $filePath);

Doing this I was able to save my audio file on the server properly.

Community
  • 1
  • 1
8vius
  • 5,786
  • 14
  • 74
  • 136