21

I've made an upload using JavaScript, PHP and Cordova. Everything works fine. But when I try to open the uploaded mp3 in browser or a desktop player like Windows Media Player, it says the file is corrupt. Any idea why this is happening?

I also have to say that when I inspect the corrupted file in browser it has video tags instead of audio tags.

My code:

//method to upload the audio
function uploadAudio(recordedSrc) {
  var win = function(r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
  }

  var fail = function(error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
  }

  var options = new FileUploadOptions();
  options.fileKey = "file";
  options.fileName = "recordupload.mp3";
  options.mimeType = "audio/mpeg";
  console.log(options);

  var ft = new FileTransfer();
  console.log(ft);
  console.log(recordedSrc);
  ft.upload(recordedSrc, encodeURI(app_url + "json/upload.php"), win, fail, options);
}
$('.upload').on('click', function(e) {
  e.preventDefault();
  //Method to upload Audio file to server
  uploadAudio(mediaRecSrc);
});

Server side handling script in PHP:

<?php
// Where the file is going to be placed
$target_path = dirname(__FILE__) . "/uploaded_records/";
if (!file_exists($target_path)) {
    mkdir ($target_path, 0777);
}
/* Add the original filename to our target path.
Result is "uploads/filename.extension" */
$target_path = $target_path . basename( $_FILES['file']['name']);
$path = $_FILES['file']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
var_dump("ext is: " . $ext);

if(move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['file']['name']).
    " has been uploaded";
} else{
    echo "There was an error uploading the file, please try again!";
    echo "filename: " .  basename( $_FILES['file']['name']);
    echo "target_path: " .$target_path;
}
?>

UPDATE:

It seems that the problem lies within the file(which on android works playing). I copied the file through usb device and tried playing it and there is the same problem, the file won't play. I have to say that the file is recorded using the media plugin from cordova. Maybe this is the problem, right?

SECOND UPDATE:

I recorded and uploaded a file as an .amr format and converted it to .mp3 online here and the sound works. Any idea on how to resolve this problem?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Ionut Necula
  • 11,107
  • 4
  • 45
  • 69
  • What is **ft.upload()** actually doing? – Todor Kostov Sep 14 '16 at 09:12
  • @TodorKostov, it's handling the upload, making use of AJAX. It's sending the file infos to the upload.php script. – Ionut Necula Sep 14 '16 at 09:33
  • obviously it is doing that. The question is how? Is that something you have written yourself (it means possible bugs and errors) OR is it a third party functionality (that also means possible errors, but on a lower degree)? If it comes from a library which is used by hundrests of developers or something like that, then probably the problem is not in the way you are uploading the file. This will help us to figure out the problem. – Todor Kostov Sep 14 '16 at 09:37
  • Ok. I make use of the in built cordova file tranfer plugin. So it's a third party who is handling the requests. – Ionut Necula Sep 14 '16 at 09:39
  • @TodorKostov, also the plugin documentation can be found here: https://github.com/apache/cordova-plugin-file-transfer. Maybe it will help you help me :) – Ionut Necula Sep 14 '16 at 10:42
  • Would you be able to provide the original file that would not play? – Renari Sep 19 '16 at 03:09
  • Could you open in an hex editor any uploaded "mp3" file and take a screenshot of the beginning of the dump ? We could see what is the exact format. The media plugin from Cordova may not making an mp3 and forcing the extension in your script will only confuse players. I strongly suspect mpg, mpa or mp2 following your comments. – Proger_Cbsk Sep 20 '16 at 16:54
  • It's not making an .mp3 it's making an .amr, we verified this days ago, just because you set the src file extension to .xxx does NOT make the file encoded .xxx. – Jon Goodwin Sep 22 '16 at 02:34
  • The android SDK does NOT have a mp3 codec, how on earth do you expect it to encode one ? – Jon Goodwin Sep 22 '16 at 02:55

2 Answers2

7

It might be mp3 is encoded in a way the mp3 player doesn't understand. Some mp3 players only support audio encoded in a certain manner and won't support certain methods of encoding like variable bit rate, high bit rates (320kbps+) , or mp3's with DRM.
As an application developer, you are free to make use of any media codec that is available on any Android-powered device, including those provided by the Android platform and those that are device-specific. However, it is a best practice to use media encoding profiles that are device-agnostic, Android media formats.

How are you making the mp3 file in the first place ? I make 3gp audio files on android and they play fine in VLC Media Player.

Cordova on Android devices record audio in Adaptive Multi-Rate format. The specified file should end with a .amr extension. (this is NOT a choice, it is a fact).

// Record audio
// 
function recordAudio() {
    var src = "myrecording.amr";
    var mediaRec = new Media(src, onSuccess, onError);

    // Record audio
    mediaRec.startRecord();

    // Stop recording after 10 sec
    var recTime = 0;
    var recInterval = setInterval(function() {
        recTime = recTime + 1;
        setAudioPosition(recTime + " sec");
        if (recTime >= 10) {
            clearInterval(recInterval);
            mediaRec.stopRecord();
        }
    }, 1000);
}

AMR file is not one of the supported audio files that html5 audio tag supports. Please see this list for supported audio formats: html5 supported audio formats

File conversion see: convert

If you don't know what Cordova is, see my stackoverflow quick install guide:
Cordova quick install with links to a tutorial.

If you want android .wav output here is something interesting (android does not have a .wav codec !) (untested by me, but I know this kind of code, seems good).

Jon Goodwin
  • 9,053
  • 5
  • 35
  • 54
  • Hello. Thank you for your answer. On android the audio plays fine. On desktop/laptop says it's corrupt. To create the mp3 file I use the cordova [media plugin](http://docs.phonegap.com/en/edge/cordova_media_media.md.html#media.startRecord) which records and saves the file. – Ionut Necula Sep 17 '16 at 18:45
  • I will check what configuration options Cordova has, and cross check what desktop apps accept as valid. I record my own audio on android, I will check my files work on desktop also. – Jon Goodwin Sep 17 '16 at 18:48
  • Ok. Thank you for taking the time to help me out. I will expect your answer. – Ionut Necula Sep 17 '16 at 19:11
  • Also, I forgot to tell that I need to be able to play the audios using HTML 5 audio, thing that will amr won't work and with mp3 does not work now. – Ionut Necula Sep 17 '16 at 19:29
  • If you copy the file to your pc, then copy it straight back to your phone, and it runs ok, then we know it is about the file format, not the download/upload process. – Jon Goodwin Sep 17 '16 at 19:30
  • Yes. I thought the same thing and it was the first update of my question from some days ago. What solution do I have here? How do I create a non-corrupt mp3 file compatible with the browser? – Ionut Necula Sep 17 '16 at 19:47
  • Sorry, but there is nothing new in your answer that I didn't already knew. I already said I recorded .amr, .mp3, even .wav, but the problem is the same. In browser does not work, on desktop using VLC or GOM player with some good codecs works. What I try to do is to record an mp3 compatible with audio HTML5 tags to play the audio in browser. – Ionut Necula Sep 18 '16 at 11:43
  • I think the file is not corrupt, I think it contains amr data, not mp3, see my updated answer – Jon Goodwin Sep 18 '16 at 11:43
  • As I have said you cannot record audio in mp3 format with Cordova on Android (you MUST use amr), so what you need is a file converter from amr to mp3., right ? – Jon Goodwin Sep 18 '16 at 11:48
  • False, there is clearly possible from the documentation that you can record an mp3. It's even showed in their [example](http://docs.phonegap.com/en/3.3.0/cordova_media_media.md.html#media.startRecord). – Ionut Necula Sep 18 '16 at 11:53
  • Scroll down a little in the document and read "Android Quirks" – Jon Goodwin Sep 18 '16 at 11:57
  • Then, why they use .mp3 in their examples? Isn't that misleading? – Ionut Necula Sep 18 '16 at 12:03
  • Cordova is SUPPOSED to be corss-platform, here you see, in the detail it is NOT. ;O) – Jon Goodwin Sep 18 '16 at 12:04
  • Anyway, I think I'm going to try and converting the .amr to .mp3 using an web service API converter from [here](https://cloudconvert.com/api/conversions) and see what happens. – Ionut Necula Sep 18 '16 at 12:04
1

It's likely you are uploading your files in ASCII instead of binary? I'm not great with PHP but to me it seems fairly likely you need to tell something it's a binary file rather than text. Probably something you can specify in your options.

Ryan
  • 86
  • 8