Get base64 of audio data from Cordova Capture - javascript

I am using ngCordova Capture to write this code by recording audio and send the base64 somewhere (via REST). I could get the Capture Audio to work but once it returns the audioURI, I cannot get the data from the filesystem as base64. My code is below:
$cordovaCapture.captureAudio(options).then(function(audioURI) {
$scope.post.tracId = $scope.tracId;
$scope.post.type = 'audio';
console.log('audioURI:');
console.log(audioURI);
var path = audioURI[0].localURL;
console.log('path:');
console.log(path);
window.resolveLocalFileSystemURL(path, function(fileObj) {
var reader = new FileReader();
console.log('fileObj:');
console.log(fileObj);
reader.onloadend = function (event) {
console.log('reader.result:');
console.log(reader.result);
console.log('event.result:');
console.log(event.result);
}
reader.onload = function(event2) {
console.log('event2.result:');
console.log(event2.target.result);
};
reader.readAsDataURL(fileObj);
console.log(fileObj.filesystem.root.nativeURL + ' ' + fileObj.name);
$cordovaFile.readAsDataURL(fileObj.filesystem.root.nativeURL, fileObj.name)
.then(function (success) {
console.log('success:');
console.log(success);
}, function (error) {
// error
});
});
Here is the output in console log:
So how do I get the base64 data from the .wav file?
I have been reading these links:
PhoneGap FileReader/readAsDataURL Not Triggering Callbacks
https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
http://jsfiddle.net/eliseosoto/JHQnk/
http://community.phonegap.com/nitobi/topics/filereader_onload_not_working_with_phonegap_build_2_5_0

Had same problem, which I fixed using both the Cordova Capture and Cordova File plugin.
navigator.device.capture.captureAudio(function (audioFiles) {
var audioFile = audioFiles[0],
fileReader = new FileReader(),
file;
fileReader.onload = function (readerEvt) {
var base64 = readerEvt.target.result;
};
//fileReader.reasAsDataURL(audioFile); //This will result in your problem.
file = new window.File(audioFile.name, audioFile.localURL,
audioFile.type, audioFile.lastModifiedDate, audioFile.size);
fileReader.readAsDataURL(file); //This will result in the solution.
});

Related

How would I convert an image to base64 in reactJS

I have this function where I call a function and have a local file as the parameter to convert it to base64.
export const fileToBase64 = (filename, filepath) => {
return new Promise(resolve => {
var file = new File([filename], filepath);
var reader = new FileReader();
// Read file content on file loaded event
reader.onload = function(event) {
resolve(event.target.result);
};
// Convert data to base64
reader.readAsDataURL(file);
});
}
Importing the function
fileToBase64("shield.png", "./form").then(result => {
console.log(result);
console.log("here");
});
gives me an output as
data:application/octet-stream;base64,c2hpZWxkLnBuZw==
here
I want base64 information, but noticing the file the application/octet-stream is wrong? I entered an image so shouldn't it be
data:image/pgn;base64,c2hpZWxkLnBuZw==
https://medium.com/#simmibadhan/converting-file-to-base64-on-javascript-client-side-b2dfdfed75f6
try this I think this should helpfull
let buff = new Buffer(result, 'base64');
let text = buff.toString('ascii');
console.log(text)

How to Convert Uploaded Audio to Blob using Javascript?

I am trying to capture the audio that's uploaded by the user, convert it to Blob then using wavesurfer.js to display the waveform.
I am following this instruction here https://bl.ocks.org/nolanlawson/62e747cea7af01542479
And here is the code
// Convert audio to Blob
$('#audioFileInput').on('change', function () {
var file = $('#audioFileInput')[0].files[0];
var fileName = file.name;
var fileType = file.type;
var fileReader = new FileReader();
fileReader.onloadend = function (e) {
var arrayBuffer = e.target.result;
blobUtil.arrayBufferToBlob(arrayBuffer, fileType).then(function (blob) {
console.log('here is a blob', blob);
console.log('its size is', blob.size);
console.log('its type is', blob.type);
surfTheBlob(blob);
}).catch(console.log.bind(console));
};
fileReader.readAsArrayBuffer(file);
});
But it says
blobUtil.arrayBufferToBlob(...).then is not a function
Another issue is that since the user might upload the audio themselves, the audio type might vary, expected to come from native device audio recorder. Anyone can help please? thanks.
A File object, like the ones you get in the input.files FileList, is already a Blob:
inp.onchange = e =>
console.log(inp.files[0] instanceof Blob) // true
<input type="file" id="inp">
So all you really need is to pass directly this File to your library:
$('#audioFileInput').on('change', function () {
var file = this.files[0];
surfTheBlob(file);
});
Found the answer already.
// Convert audio to Blob
$('#audioFileInput').on('change', function () {
var file = $('#audioFileInput')[0].files[0];
var fileName = file.name;
var fileType = file.type;
var url = URL.createObjectURL(file);
fetch(url).then(function(response) {
if(response.ok) {
return response.blob();
}
throw new Error('Network response was not ok.');
}).then(function(blob) {
surfTheBlob(blob);
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
});
});
Cheers!

sending file to backend angular full stack

I am using yeoman angular fullstack and im trying to do a simple file upload. I read the file from a form and i get it into the front end just fine
this.$scope.add = function() {
var f = document.getElementById('resume').files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
console.log(e.target.result);
Auth.saveResume({
data: e.target.result,
name:theFile.name
});
};
})(f);
reader.readAsArrayBuffer(f);
}
in auth.services.ts i have
saveResume(resume, callback?: Function) {
console.log(User)
return User.saveResume({ id: currentUser._id }, {resume},
function() {
console.log('auth.service in function');
console.log('currentUser._id: ' + currentUser._id);
return safeCb(callback)(null);
},
function(err) {
return safeCb(callback)(err);
}).$promise;
},
it successfully makes it into my back end controller
router.put('/:id/resume', auth.isAuthenticated(), controller.saveResume);
where i have a saveResume function
export function saveResume(req, res){
console.log(typeof req.body.resume.data);
console.log(typeof req.body.resume.name);
}
In the save resume function when i access the "name" parameter it is correct and is of type string. However when i access "data" i just get an object. I would like data to be either a file or buffer so i can upload it to s3.
My only guess for why its an object instead of an ArrayBuffer is that i think node doesnt support javascript ArrayBuffers, blobs, or files. How do i get the file in the backend in some form that s3 will accept? ie file, blob, or buffer
As #bubblez suggest i encoded it to base 64 like so
var fileReader = new FileReader();
var base64;
// Onload of file read the file content
fileReader.onload = function(fileLoadedEvent) {
base64 = fileLoadedEvent.target.result;
// Print data in console
console.log(base64);
Auth.saveResume(f.name, base64);
};
// Convert data to base64
fileReader.readAsDataURL(f);
i also changed auth so that it takes two separate parameters
saveResume(name, data, callback?: Function) {
console.log(User)
return User.saveResume({ id: currentUser._id }, {name, data},
function() {
console.log('auth.service in function');
console.log('currentUser._id: ' + currentUser._id);
return safeCb(callback)(null);
},
function(err) {
return safeCb(callback)(err);
}).$promise;
},
i then decode from base 64
export function saveResume(req, res){
var base64String = req.body.data.split(';base64,').pop();
console.log(base64String);
var buf = Buffer.from(base64String, 'base64').toString('utf');
uploadParams.Body = buf;
}
and this works!

javascript readAsArrayBuffer returns empty Array Buffer

I am trying to read a local file using the FileReader readAsArrayBuffer property.
The read is success and in the "onload" callback, I see the Array Buffer object in reader.result. But the Array Buffer is just empty. The length is set, but not the data. How do I get this data?
Here is my code
<!DOCTYPE html>
<html>
<body>
<input type="file" id="file" />
</body>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
var selFile = files[0];
var reader = new FileReader();
reader.onload = function(e) {
console.log(e.target.result);
};
reader.onerror = function(e) {
console.log(e);
};
reader.readAsArrayBuffer(selFile);
}
document.getElementById('file').addEventListener('change', handleFileSelect, false);
</script>
</html>
the console output for reader.result
e.target.result
ArrayBuffer {}
e.target.result.byteLength
25312
Can anyone tell me how to get this data?
is there some security issue?
There is no error, the onerror is not executed.
From comments: Can you please let me know how to access the buffer contents? I am actually trying to play an audio file using AudioContext... For that I would need the buffer data...
Here is how to read array buffer and convert it into binary string,
function onfilechange(evt) {
var reader = new FileReader();
reader.onload = function(evt) {
var chars = new Uint8Array(evt.target.result);
var CHUNK_SIZE = 0x8000;
var index = 0;
var length = chars.length;
var result = '';
var slice;
while (index < length) {
slice = chars.subarray(index, Math.min(index + CHUNK_SIZE, length));
result += String.fromCharCode.apply(null, slice);
index += CHUNK_SIZE;
}
// Here you have file content as Binary String in result var
};
reader.readAsArrayBuffer(evt.target.files[0]);
}
If you try to print ArrayBuffer via console.log you always get empty object {}
Well, playing a sound using the AudioContext stuff isn't actually that hard.
Set up the context.
Load any data into the buffer (e.g. FileReader for local files, XHR for remote stuff).
Setup a new source, and start it.
All in all, something like this:
var context = new(window.AudioContext || window.webkitAudioContext)();
function playsound(raw) {
console.log("now playing a sound, that starts with", new Uint8Array(raw.slice(0, 10)));
context.decodeAudioData(raw, function (buffer) {
if (!buffer) {
console.error("failed to decode:", "buffer null");
return;
}
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
console.log("started...");
}, function (error) {
console.error("failed to decode:", error);
});
}
function onfilechange(then, evt) {
var reader = new FileReader();
reader.onload = function (e) {
console.log(e);
then(e.target.result);
};
reader.onerror = function (e) {
console.error(e);
};
reader.readAsArrayBuffer(evt.target.files[0]);
}
document.getElementById('file')
.addEventListener('change', onfilechange.bind(null, playsound), false);
See this live in a jsfiddle, which works for me in Firefox and Chrome.
I threw in a console.log(new Uint8Array()) for good measure, as browser will usually log the contents directly (if the buffer isn't huge).
For other stuff that you can do with ArrayBuffers, see e.g. the corresponding MDN documentation.

FileReader.readAsDataURL upload to express.js

I have the following code to upload to my Node.js/Express.js backend.
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
var result = http.post('/files', e.target.result);
result.success(function () {
alert('done'):
});
}
My route looks like:
app.post('/files', function (req, res) {
var cws = fs.createWriteStream(__dirname + '/media/file');
req.pipe(cws);
res.send('success');
});
When I open /media/file with an image app I get a warning that it cannot read it. When I open the image file with a text-editor I see the base64 encoded string inside. Do I need to convert the string first before writing it to desk?
The problem was that a DataURL is prepended by meta data. You first need to remove that part before you create a base64 buffer.
var data_url = req.body.file;
var matches = data_url.match(/^data:.+\/(.+);base64,(.*)$/);
var ext = matches[1];
var base64_data = matches[2];
var buffer = new Buffer(base64_data, 'base64');
fs.writeFile(__dirname + '/media/file', buffer, function (err) {
res.send('success');
});
Got most code from this question.

Categories

Resources