Convert mp3 to base64 - File Reader - javascript

I am developing an app which needs to record audio, and then have the audio stored as part of an object, and uploaded to a database.
I am trying to alert the base64 of the file first just to ensure it has been found correctly.
I am using the cordova media capture plugin to access the recorder on a device, and am able to record the audio, however once it has been recorded I want to convert into a base64 format before sending to the database. When I use this method it alerts the base64, but it is empty, just "data:audio/mpeg;base64," with nothing after, I do not know why it isn't converting the file correctly.
Plugin: https://github.com/apache/cordova-plugin-media-capture
function captureSuccess(capturedFiles) {
//Convert capturedFiles[0] into var containing file as base64
previewFile(capturedFiles);
alert("Audio Captured");
}
function captureError() {
alert("Audio Not Captured");
}
navigator.device.capture.captureAudio(captureSuccess, captureError, {
limit: 1,
duration: 20
});
});
/***********************************************************************************/
function previewFile(files) {
var preview = document.querySelector('img');
var file = files[0];
var reader = new FileReader();
reader.onload = function () {
alert(reader.result);
};
if (file) {
reader.readAsDataURL(file);
}
}

I was having alot of issues to this, and had looked all over StackOverFlow for an answer but had alot of trouble finding one, so for anyone in the future who has this issue I was able to solve it. The issue was that the file I wanted to convert to base64 had a "start" and an "end" which were both set the 0, so none of the bytes were being accessed. To ensure the bytes are accessed I keep the start byte as 0 (so don't change anything), and set the end byte to the same as the file size. Here is the resolved code below:
$("#btnAudio").click(function () {
function captureSuccess(capturedFiles) {
var path = capturedFiles[0].fullPath;
//Convert capturedFiles[0] into var containing file as base64
previewFile(capturedFiles);
alert("Audio Captured");
}
function captureError() {
alert("Audio Not Captured");
}
navigator.device.capture.captureAudio(captureSuccess, captureError, {
limit: 1,
duration: 20
});
});
/***********************************************************************************/
function previewFile(files) {
var file = files[0];
var reader = new FileReader();
file.end = file.size;
var preview = document.querySelector('audio');
reader.onload = function () {
/*For testing I am just alerting reader.result, but if you want to store the
base64 just create a var and set its value to reader.result*/
alert(reader.result);
};
if (file) {
reader.readAsDataURL(file);
}
}

Related

How to work with the url of a fileReader object?

Hello! I'am trying to make it work a function called loadDocument, who need a url of the loaded files from the user local computer to work. I'm writing an API to load document from local user computer, and show it on a web reader.
This is my upload button :
<input type="file" id="input" onchange="module.onLoadSelection();" alt="Browse" name="upload"/>
This is my function without fileReader :
var onLoadSelection = function () {
var select = document.getElementById('input');
if (select && select.value) {
var id= '';
var url = select.files.item(0).name;
module.loadDocument(url,id);
}
};
This is my function with fileReader :
var loadTest = function (input) {
var file = document.querySelector('input[type=file]').files[0];
console.log("file loaded! ->", file); // i can read the obj of my file
var reader = new FileReader();
var id = ''; // don't need rightnow
var url = reader.readAsDataURL(file);
console.log("url :", url); // show me undefined....
module.loadDocument(url,id);
}
What i am trying is to get the url of the loaded file from user computer to get my function loadDocument working. She need a url parameter to work.
loadDocument is an API function, i assume i can't get the filepath of my user due to security reason.
What do i need to change/update on my loadDocument(); function to work?
Edit : In fact, nothing to change. The correct way to read my file was :
<input type="file" id="input" onchange="module.onLoadSelection(this.files);" alt="Browse" name="upload"/>
var onLoadSelection = function (files) {
if (files && files.length == 1) {
var id = '';
var url = URL.createObjectURL(files[0]);
module.loadDocument(url,id);
}
};
Don't use a FileReader at all.
When you want to display a File (or a Blob) that is in the browser's memory or on user's disk, then all you need is to generate an URL that do point to this memory slot.
That's exactly what URL.createObjectURL(blob) does: it returns a Blob URI (blob://) that points to the data either in memory or on the disk, acting exactly as a simple pointer.
This method has various advantages over the FileReader.readAsDataURL() method. To name a few:
Store the data in memory only once, when FileReader would need it at reading, then generate a copy as an base64 encoded, and an other one at displaying...
Synchronous. Since all it does is to generate a pointer, no need to make it async.
Cleaner code.
const module = {
loadDocument: (url) => {
document.body.append(
Object.assign(
document.createElement('iframe'),
{ src: url }
)
)
}
};
document.querySelector('input[type=file]').addEventListener('input', function (evt) {
var file = this.files[0];
var url = URL.createObjectURL(file);
module.loadDocument(url);
});
<input type="file">
function PreviewFiles(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
//alert(e.target.result);
$('#pclogo').prop('src', e.target.result)
.width(200)
.height(200);
var base64result = e.target.result.split(',')[1];
$('input[name="logo"]').val(base64result);
};
reader.readAsDataURL(input.files[0]);
}
}
File objects have a readAsDataURL method.
Use that.
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
doSomethingWithAUrl(reader.result);
}, false);
if (file) {
reader.readAsDataURL(file);
}

Javascript - Callback

I am new to Javascript and am working on a task to compress and then upload an already uploaded image.
I am trying to:
Retrieve the uploaded image,
Compress it
Convert it to a base64 URL
Convert it into a blob
And then into a file and upload it.
But this code just doesn't work.
When I step through it using a debugging tool it does it's job but otherwise it doesn't.
I think the rest of the code after the loadImage function call doesn't really execute.
Please help me make sense of it! Thanks!
function loadImage(formObj2, fldid2, file, callback) {
var oldImage = document.createElement("img");
var psImageOutput = new Image();
var reader = new FileReader();
reader.onload = function(e) {
/* code to compress image */
callback(psImageOutput);
}
reader.readAsDataURL(file);
}
var inputFile = fileQueue[i].file;
var formObj1 = formObject;
var fldid1 = fldid;
loadImage(formObj1, fldid1, inputFile, function(psImageOutput) {
var newImageDataSRC = psImageOutput.src;
/* Manipulate SRC string and create a blob and an image file from it */
formObj1.append(fldid1, newimgfile);
});
Be careful, on the line :
formObj1.append(fldid1, newimgfile);
You seem to append a dom node called newimgfile but in your code this variable doesn't exist.

How Might I Upload an Image Previously Stored in LocalStorage?

I have an html5 mobile web app (http://app.winetracker.co) and I'm working on feature that remembers user's state when they come back to the app in their browser (which always automatically refreshes in iOS safari). I'm storing the URL and form-field data via local storage. One of the form field data items is an file-input for images. I am successfully converting images to a base64 via canvas and storing it to localStorage.
function storeTheImage() {
var imgCanvas = document.getElementById('canvas-element'),
imgContext = imgCanvas.getContext("2d");
var img = document.getElementById('image-preview');
// Make sure canvas is as big as the picture BUT make it half size to the file size is small enough
imgCanvas.width = (img.width/4);
imgCanvas.height = (img.height/4);
// Draw image into canvas element
imgContext.drawImage(img, 0, 0, (img.width/4), (img.height/4));
// Get canvas contents as a data URL
var imgAsDataURL = imgCanvas.toDataURL("image/png");
// Save image into localStorage
try {
window.localStorage.setItem("imageStore", imgAsDataURL);
$('.localstorage-output').html( window.localStorage.getItem('imageStore') );
}
catch (e) {
console.log("Storage failed: " + e);
}
}
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#image-preview').attr('src', e.target.result);
storeTheImage();
}
reader.readAsDataURL(input.files[0]);
}
}
$('.file-input').on('change', function() {
readURL(this);
});
see this jsFiddle: https://jsfiddle.net/tonejac/ceLwh9qp/19/
How might I convert the localStore image dataURL string back to an image file so I can upload it to my server?
How might I convert the localStore image dataURL string back to an image file
See your fiddle, Javascript pane line 25.
// recompose image :
var imgRecomposed = document.createElement('img');
$('.image-recomposed').append(imgRecomposed);
imgRecomposed.src = window.localStorage.getItem('imageStore');
We create an image element and fill the src attibute with the data of the stored 'dataImage'.
In your Fiddle:
// Save image into localStorage
try {
window.localStorage.setItem("imageStore", imgAsDataURL);
$('.localstorage-output').html( window.localStorage.getItem('imageStore') );
}
catch (e) {
console.log("Storage failed: " + e);
}
Place any of the following in your try/catch:
$('#canvas-element').context.drawImage(imgAsDataURL);
$('#canvas-element').context.drawImage(imgAsDataURL, 0, 0);
$('#canvas-element').replace(imgAsDataURL);
This will place the stored image into the Canvas you have displayed.
It is already an 'image' - you can use it as the src for an element etc. Sending it to your server is depends on the environment you have - basically an Ajax POST or similar sending the base64 string?.
You will first have to convert this dataURL to a blob, then use a FormData object to send this blob as a file.
To convert the dataURL to a blob, I do use the function from this answer.
function upload(dataURI, url){
// convert our dataURI to blob
var blob = dataURItoBlob(dataURI);
// create a new FormData
var form = new FormData();
// append the blob as a file (accessible through e.g $_FILES['your_file'] in php and named "your_filename.extension")
form.append('your_file', blob, 'your_filename.'+blob.type.split('image/')[1]);
// create a new xhr
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
// send our FormData
xhr.send(form);
}
// from https://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata/5100158#5100158
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
var savedIntoLocalStorage = 'data:image/png;base64,...=';
// execute the request
upload(savedIntoLocalStorage, 'http://yourserver.com/upload.php');

jQuery-File-Upload where is the file data when pre processing? http://blueimp.github.io/jQuery-File-Upload/

I've started playing around with the excellent http://blueimp.github.io/jQuery-File-Upload/ file upload project.
From the File Processing Options section of the documentation it seems that jquery.fileupload-process.js will let me parse and even modify the file's binary data (files array - with the result of the process applied and originalFiles with the original uploaded files)
(to parse, or append to it or encrypt it or to do something to it)
but for the life of me I can't seem to figure out where is the actual file data within the array so that I can pre-process it before it uploads.
What part of the data array has the "something.pdf" binary file in it? so that I can parse and transform it before upload?
//FROM: jquery.fileupload-process.js
//The list of processing actions:
processQueue: [
{
action: 'log'
}
],
add: function (e, data) {
var $this = $(this);
data.process(function () {
return $this.fileupload('process', data);
});
originalAdd.call(this, e, data);
}
},
processActions: {
log: function (data, options) {
console.log(data.files[0]); //Is it here?
console.log(data); //Is it here?
console.log(data.files[data.index]); //Is it here?
console.log(data.files[data.index].name); //Is it here?
//where?
Thank you.
The correct way to access the currently processed file is the following:
var file = data.files[data.index];
For browsers which support the File API, this is a File object.
To retrieve the actual File data, we have to use the FileReader interface:
var fileReader = new FileReader();
fileReader.onload = function (event) {
var buffer = event.target.result;
// TODO: Do something with the ArrayBuffer containing the file's data
};
fileReader.readAsArrayBuffer(file);
It may be useful, building on #Sebastian's answer, to explain where to put the FileReader, to work with the fileupload plugin. (I would have made this a comment on #Sebastian's answer, but didn't have space in the comment field).
I have built this in to the process action (using readAsText instead of readAsArrayBuffer) as follows:
alertText: function(data, options) {
var dfd = $.Deferred(),
file = data.files[data.index];
var fileReader = new FileReader();
fileReader.onload = function (event) {
var fileText = event.target.result;
alert('Text of uploaded file: '+ fileText);
};
fileReader.readAsText(file);
return dfd.promise();
}

How should I implement client side encryption in a jQuery file upload plugin?

I am trying to implement client side encryption in the jQuery File Upload Plugin. I have tried to follow some information I found along the lines of...
iterate over the files array,
replace each item with a Blob representing the encrypted file
after the encryption is done, invoke the callback
But am struggling I currently have...
var encryptFiles = function (files, callback) {
var reader = new FileReader();
var file = files[0];
var blob = file.slice(0, file.size);
reader.readAsBinaryString(blob);
reader.onload = fileonload;
function fileonload(event) {
var result = event.target.result;
var encrypted = CryptoJS.AES.encrypt(result, "key");
file.
callback();
}
// iterate over the files array,
// replace each item with a Blob representing the encrypted file
// after the encryption is done, invoke the callback
}
$('#fileupload').fileupload({
add: function (e, data) {
encryptFiles(data.files, function () {
data.submit();
});
}
});
This code successfully reads the file to a blob, then encrypts it but I am unsure how to go about replacing the item with the Blob. Can anyone give me some help.

Categories