React Native File-Conversion - reactjs

I'm trying to convert an audio file into a Base64String to upload to a server.
For certain reasons, I want to do this on the phone before I upload this. I'm using React Native inside the Expo kit.
My file structure looks like this:
let uriParts = uri.split('.');
let fileType = uriParts[uriParts.length - 1];
let formData = new FormData();
formData.append('file', {
uri,
name: `file.${fileType}`,
type: `audio/${fileType}`,
});
Assume we have the uri and it's a .wav audio file
I was able to do this conversion with a NodeJS server with multer doing the heavy lifting.
It would give a buffer to the route and then I could convert the buffer to a base64 string and then send it to another server to process the buffer.
Any idea how can get this done on React Native or purely on the frontend?
Thanks!

You can use FileReader class.
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
Or you can send as a blob (It is not base64).
Use https://github.com/wkh237/react-native-fetch-blob library

Related

How to upload image or file in react js?

I want to upload image / file in a react project, but dont want to use formdata to post, instead i want to use body for the post method through Axios.
If I can convert my file into base 64, I think i will be able to post the image through body.
Can anyone tell me solution how to achieve this?
Use this code :
function encodeImageFileAsURL(element) {
var file = element.files[0];
var reader = new FileReader();
reader.onloadend = function() {
console.log('RESULT', reader.result)
}
reader.readAsDataURL(file);
}

Using TinyMCE uploading images to a backend

I am trying to use the rich text editor TinyMCE for a blog platform I am currently working on.
I am also using React with a Flask backend. A
User should be able to create a blog entry with the editor and also use/ upload images.
I got everything setup but I don't know how to store the images in my backend so you can save a blog with all it's content.
I got this callback function from their documentation but I do not really understand what's happening there and if it is enough to send the file object to my backend and store it in the database.
file_picker_callback: function (cb, value, meta) {
var input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/png , image/jpg");
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
var id = "blobid" + new Date().getTime();
var blobCache =
window.tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(",")[1];
var blobInfo = blobCache.create(id, file, base64);
blobCache.add(blobInfo);
/* call the callback and populate the Title field with the file name */
cb(blobInfo.blobUri(), { title: file.name });
};
reader.readAsDataURL(file);
console.log(file);
};
This is the console.log(file) output
File {name: "wlogLogo.png", lastModified: 1590578382000, webkitRelativePath: "", size: 4591, type: "image/png", …}

Save Recorded Audio to Local Directory -ReactJS

I am recording an audio through browser and storing it as a blob using react-mic library, I need to change the blob audio file to mp3/ogg/wav file and store it in local directory using ReactJS.
Blob example:
{blob: Blob(5899), startTime: 1518600546820, stopTime: 1518600547833, options: {audioBitsPerSecond :128000, mimeType:"audio/mpeg"},
blobURL: "blob:http://localhost:3000/3ac81ece-237f-4265-8225-6653b2beb0bc"}
Here I am storing a blob in a state,
onStop = (recordedBlob) => {
this.setState({
blobMain: recordedBlob
})
}
instead of a blob I wanted to store a mp3/ogg/wav file. And use the state for api response.
I tried using Filereader() to convert the blob to ArrayBuffer and convert it as a mp3/ogg/wave file.
onStop = (recordedBlob) => {
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function() {
arrayBuffer = this.result;
};
fileReader.readAsArrayBuffer(recordedBlob);
this.setState({
blobMain: fileReader
})
}
But I get an error as:
TypeError: Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.

How to upload audio file to Firebase Storage?

I'm trying to upload audio file to Firebase Storage in my Ionic2 project.
First I recorded a audio file using Media plugin (Cordova plugin), and this file is playing well. From the Android storage and from the media plugin method (this.media.play()...;).
Second I need to push the recorded file to Firebase Storage.
this is my code:
let storageRef = firebase.storage().ref();
let metadata = {
contentType: 'audio/mp3',
};
let filePath = `${this.file.externalDataDirectory}`+`${this.fileName}`;
const voiceRef = storageRef.child(`voices/${this.fileName}`);
var blob = new Blob([filePath], {type: 'audio/mp3'});
voiceRef.put(blob);
After reading the Firebase doc, I can push blob to Firebase.
The file is successfully pushed to Firebase Storage with empty data (95 Byte).
this is screenshot:
The problem isn't a Firebase issue
My problem is solved by using the File cordova plugin method (readAsDataURL()) and the putString(fileBase64,firebase.storage.StringFormat.DATA_URL) method.
First, I create a file reference:
let filePath = "this.file.externalDataDirectory" + "this.fileName";
Then I transform the file to a base64 string by using the readAsDataURL method that returns a promise containing the file as a string base64. Also, I push the file to Firebase using the putString method that has two parameters the File that returned by the readAsDataURL and the second is firebase.storage.StringFormat.DATA_URL.
My Final code:
let storageRef = firebase.storage().ref();
let metadata = {
contentType: 'audio/mp3',
};
let filePath = `${this.file.externalDataDirectory}` + `${this.fileName}`;
this.file.readAsDataURL(this.file.externalDataDirectory, this.fileName).then((file) => {
let voiceRef = storageRef.child(`voices/${this.fileName}`).putString(file, firebase.storage.StringFormat.DATA_URL);
voiceRef.on(firebase.storage.TaskEvent.STATE_CHANGED, (snapshot) => {
console.log("uploading");
}, (e) => {
reject(e);
console.log(JSON.stringify(e, null, 2));
}, () => {
var downloadURL = voiceRef.snapshot.downloadURL;
resolve(downloadURL);
});
});
That's working fine for me.
Thanks.

How to save WAV Blob to MongoDB, retrieve and serve correctly with Node?

I've found many posts dealing with saving binary files using the Mongoose Buffer SchemaType. However, most of them deal with image files, and I haven't been able to get them to work with a WAV audio file.
I'm using Recorder.js to save audio recordings from the built-in microphone. I use Recorder.js' exportWAV function to get a BLOB from the finished recording, then read the blob with FileReader and send it to the Node/Express backend where it is then saved to the DB. I've checked using the Mongo CLI and there is data being saved to the relevant field (starting with BinData(0,"UklGR.lotsofdatahere..="). When I try to get the recording by sentence id, the server responds with an appropriately-MIME-typed .wav file that is unplayable.
It seems that I'm missing something in the way that the files are encoded and decoded for storage in MongoDB. When reading the blob spit out by Recorder.js, it looks like it's already base64 encoded. So that's why I tried loading it as a base64 Buffer before saving to Mongo, and then decoding from a base64 buffer on output. What am I missing here? How can I fix these encoding issues? Thanks!
Note: I don't necessarily need GridFS because these files are well under 16MB. Although, if it's a lot faster to stream files from GridFS, maybe I should switch to that solution. However, I'd like to figure out what's wrong with this approach first.
Here's the relevant code from the Angular frontend:
$scope.start = function() {
$scope.rec.record();
}
$scope.export = function() {
$scope.rec.stop();
$scope.rec.exportWAV(function blobCallback(blob) {
$scope.rec.clear();
var reader = new FileReader();
reader.onload = function(event) {
$.ajax({
type: 'POST',
url: '/saveRecording',
data: {
audio: event.target.result,
text: $scope.text,
timestamp: new Date()
}
}).done(function(data) {
console.log(data);
});
}
reader.readAsDataURL(blob);
});
}
The Express routes:
router.post('/saveRecording', function(request, response, next) {
var sentence = new Sentence();
sentence.audio = new Buffer(request.body.audio, 'base64');
sentence.timestamp = request.body.timestamp;
sentence.text = request.body.text;
// Save sentence to DB with Mongoose
sentence.save(function(error, sentence) {
if (error) {
return next(error);
}
// If no error, send added sentence back to the client.
response.json(sentence);
});
});
router.get('/getRecording/:sentenceId', function(request, response, next) {
Sentence.findById(request.params.sentenceId,
function dbCallback (error, sentence) {
if (error) {
return next(error);
}
if (!sentence) {
return next(new Error('Can\'t find sentence'));
}
var base64Audio = new Buffer(sentence.audio, 'base64');
response.writeHead(200, {
'Content-Type': 'audio/x-wav',
'Content-Length': base64Audio.length
});
response.write(base64Audio);
response.end();
});
});
The Mongoose Schema for Sentences:
var SentenceSchema = new mongoose.Schema({
text: String,
audio: Buffer,
timestamp: Date
});
You can try using GridFs for storing your audio files
check that link

Resources