0

I have been trying to send the recorded audio to the a controller method like shown below:

JS

$scope.convertBlobToArrayBuffer = function (audioBlob) {
    var fileReader = new FileReader();
    fileReader.onload = function() {
            $scope.saveRecordingToServer( this.result );
    };
    fileReader.readAsArrayBuffer(audioBlob);
}

$scope.saveRecordingToServer = function (audioArrayBuffer) {
    var bytes = new Uint8Array(audioArrayBuffer);
    $http({
        method: 'POST',
        url: '/upload',
        data: { data: bytes }
    }).then(function (data) {
            console.log(data);
        }, function (error) {
            console.log('Call failed with error: ', error);
        }
    );
}

Java:

@PostMapping("/upload")
@ResponseBody
public void upload(@RequestBody byte[] bytearray) throws UnsupportedAudioFileException {
    String fileName ="test"+new Date().getTime()+".wav";
    String filePath = rootLocation + fileName;

    try {
        InputStream b_in = new ByteArrayInputStream(bytearray);
        AudioFormat format = new AudioFormat(48000, 16, 1, true, false);
        AudioInputStream stream = new AudioInputStream(b_in, format,
                bytearray.length);
        File file = new File(filePath);
        AudioSystem.write(stream,javax.sound.sampled.AudioFileFormat.Type.WAVE, file);
        System.out.println("File saved: " + file.getName() + ", bytes: "
                + bytearray.length);

    } catch (IOException ex) {
        System.err.println(ex);
    }
}

Initially I tried sending arraybuffer, which result in a blank wav file. I then changed it to Uint8Array. With this I get a wav file with some noise. Moreover my recording was some 10 seconds audio and the wav file is more than 2 minutes long.

mamta
  • 35
  • 1
  • 7

1 Answers1

0

Try using Base64 encoded string for sending the byte[] to server. I haven't worked with Spring MVC so can't say how it handles this, but with Jersey, and Jackson a Base64 encoded format is default for communicating byte[] to and from REST API.

Gautam
  • 564
  • 2
  • 12
  • If you could send me code references that would be helpful. How have you done it and what was your java method signature? – mamta Aug 23 '17 at 12:04
  • I do not know a lot of angular so won't go into that. This link will help you with client side code [link](https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string)
    For server side code, change your method to take `"application/json"` as content type and method like
    `public void upload(@RequestBody Data data) throws UnsupportedAudioFileException`
    where the Data is a simple POJO with one field `byte[] bytes`.
    – Gautam Aug 24 '17 at 03:59
  • The js link doesn't have any accepted answer, which approach do you suggest? – mamta Aug 24 '17 at 06:11
  • I suggest doing this `function _arrayBufferToBase64( buffer ){ var binary = ''; var bytes = new Uint8Array( buffer ); var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode( bytes[ i ] ); } return window.btoa( binary ); }` You are already doing `var bytes = new Uint8Array(audioArrayBuffer);`, just take those `bytes` and implement above code after that to get base64 representation of your bytes. – Gautam Aug 24 '17 at 06:30