Javascript loading mp3 file as blob - javascript

I have a javascript function that for various reasons I cant change any of the code inside, the parameter for e that is passed to the function is a file selector mp3 file that the user "uploads"
this is the structure of the function-
let handleFileSelection = function(e) {
fileStore = e.target.files[0];
//go off and do other stuff with fileStore
}
this is the structure of fileStore when the file selector passes an mp3 to the function-
lastModified:1508423505000
lastModifiedDate:Thu Oct 19 2017 15:31:45 GMT+0100 (GMT Daylight Time) {}
name:"audioFile.mp3"
size:5571549
type:"audio/mp3"
webkitRelativePath:""
is it possible to pass a locally stored mp3 file to the function instead in such a way that the fileStore will have the same information ?
To clarify: The function currently accepts an mp3 file from a file selector, I need it to accept a locally stored mp3 file and for the fileStore to have the exact same information as if i was passing a file from the file selector, is this possible without modifying the function ?

Related

Loading a video file without input upload

I am incidently using react but the fact remains: when I put up a simple page with an input to upload a local file, if I console.log the actual file once it has been selected, here is what I get from the console:
File {name: "myfile.mp4", lastModified: 1474084788000, lastModifiedDate: Fri Sep 16 2016 23:59:48 GMT-0400 (EDT), webkitRelativePath: "", size: 27828905…}
lastModified: 1474084788000
lastModifiedDate: Fri Sep 16 2016 23:59:48 GMT-0400 (EDT)
name: "myfile.mp4"
size: 27828905
type: "video/mp4"
webkitRelativePath: ""
__proto__: File
And so the file loads in the video tags and I can watch it. (The code is below...)
Then, if I want to load the same file but from a hardcoded full path instead, like so: "file:///path/to/myfile.mp4", an error pops up This video file format is not supported. and what I get back from the console is the exact same path that I had previously hardcoded.
My question is how should one load a local file by using a hardcoded path instead of selecting a file from an input element?
OR
How to create an objectURL directly from a local path?
I've already tried to Blob the file before passing it on to the URL.createObjectURL function but, unless I did it something wrong, it didn't work out.
Render function code:
render() {
return (
<div>
<input type="file" ref="input" onChange={this.upload} />
<video ref="video" type="video/mp4" controls loop autoPlay width="720"></video>
<div ref="message"></div>
</div>
);
}
Functions:
processs = (file) => {
let fileURL = URL.createObjectURL(file);
this.refs.video.src = fileURL;
}
playFile = (event) => {
let file = event.target.files[0];
console.log(file);
//check if video can be played
if(this.refs.video.canPlayType(file.type) != ""){
this.processs(file);
} else {
this.refs.message.innerHTML = "This video file format is not supported."
}
};
Here is a working demo
Load Image or Video without Upload
Hope it helps
How to create an objectURL directly from a local path?
You can use XMLHttpRequest with responseType set to "blob". File inherits from Blob, you can pass returned Blob to your existing function which expects File object. See also Loading images from file with Javascript
var request = new XMLHttpRequest();
request.responseType = "blob";
request.open("GET", "file:///path/to/myfile.mp4");
request.onload = () => {
// do stuff with `request.response` : `Blob`
}
request.send();

Using Google Chrome extensions to import/export JSON files?

I'm creating a Google Chrome extension at the moment and I was wondering if it's possible for it to both create JSON files to download (export) and create a button where users can make the extension open and parse JSON files that they have saved in their local file system or on a USB stick (import)?
The parsing of each JSON from the local file system would simply involve reading off each key-value pair and doing something with the data. It would only have to deal with strings, so nothing complicated.
**EDIT: **My question is not a duplicate of this one because I'm not interested in changing the user's download path. All I want is to enable them to, with their consent, download a file to their normal download directory (which Filesaver.js can do). Plus, that post says nothing about importing.
You can fake link to "download" imaginary array MyData or whatever,:
var MyArray = [elem1, elem2, ....];
var _myArray = JSON.stringify(MyArray , null, 4); //indentation in json format, human readable
var vLink = document.createElement('a'),
vBlob = new Blob([_myArray], {type: "octet/stream"}),
vName = 'watever_you_like_to_call_it.json',
vUrl = window.URL.createObjectURL(vBlob);
vLink.setAttribute('href', vUrl);
vLink.setAttribute('download', vName );
vLink.click();
this will export/download your array into json file named as vName variable.
If you wish to import/read file:
create input element (type=file) and make it invisible (here I'm having html element and then adding js listener in script)
<input type="file" id="importOrig" accept=".json" style="display:none"/>
script
importOrig.addEventListener("change", importFun, false);
make button fakeImp (or any element), that you can style as you wish and that will be used as trigger for importing event
fakeImp.onclick = function () {importOrig.click()}
import function (from listener)
function importFun(e) {
var files = e.target.files, reader = new FileReader();
reader.onload = _imp;
reader.readAsText(files[0]);
}
function _imp() {
var _myImportedData = JSON.parse(this.result);
//here is your imported data, and from here you should know what to do with it (save it to some storage, etc.)
......
importOrig.value = ''; //make sure to clear input value after every import
}

File object to image with correct file name instead of src="blob..."

I have a File object myFile that looks like this in console:
File {
name: "myimage.jpg",
lastModified: 1465476925001,
lastModifiedDate: Thu Jun 09 2016 14:55:25 GMT+0200 (CEST),
size: 33002
type: "image/jpeg"
}
But when i create an image out of it with
var image = new Image();
image.src = URL.createObjectURL(myFile);
I get:
<img src="blob:http://myurl.com/6b2b83d8-ac36-40c1-8ab1-c4f07b019ba5">
When i try to save the file with right-click, the file-name is empty or "6b2b83d8-ac36-40c1-8ab1-c4f07b019ba5" instead of "myimage.jpg". The file-name from the file-object is gone. Is there any way to set the image file name?
The Problem
The File object is sort of an extended version of a Blob that allows it to hold metadata such as filename, size etc.
However, while createObjectURL() will reference both File and Blob the data read through the blob: protocol will only consist of the binary file data itself as when loading via other protocols. No metadata (such as filename) will be provided via the protocol.
Other examples where filename is not considered could be when an image is loaded via for example a PHP or ASPX page (/getimage.aspx?id=1). Also here there is no metadata provided and browser would suggest something like "getimage.aspx%3Fid=1" as filename in this case. As expected.
The IMG tag itself never assumes any filename even if one is used at source point; it only holds what is given to it via the src attribute/property as-is, as a connection point to retrieve the needed binary data for decoding.
In this case the source point is blob:*/* which then will be what IMG tag references via src, and is what the browser use when the data is to be saved.
Workarounds
The only way to hold on to a filename from the File object is to keep track of it so you have access to it when needed for download.
But also this is limited as you can only specify a filename using the download attribute in an A tag. And of course, some browsers such as <= IE11 does not support this attribute.
<img ..>
In IE10+ there is the proprietary method msSaveBlob() which can be used instead though:
window.navigator.msSaveBlob(myBlob, 'filename.jpg');
Besides from these there are no common way to specify a default filename from within the client.
Example fiddle

Phonegap 3.5 fetching audio / video files from external sd card Android

Currently I am not able to fetch video (.mp4) and audio (.wav) files from external sd card, basically I want to fetch the files and convert them to base64 and send them to the server.
Here is my code
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
// fileSystem's root is -> file:///storage/emulated/0/
var url = "cdvfile://localhost/root/storage/extSdCard/DCIM/Camera/20141018_143740.mp4";
window.resolveLocalFileSystemURL(url, function(fileObj) {
var fullPath = fileObj.fullPath;
// fullPath -> file:/storage/extSdCard/DCIM/Camera/20141018_143740.mp4
fileSystem.root.getFile(fullPath, null, function(fileEntry) {
fileEntry.file(function(file) {
//.. FileReader function to convert the file to base64 by reader.readAsDataURL(file)
},errorFunc);
},errorFunc);
},errorFunc);
},errorFunc);
Now the problem is I am not able to get the .mp4 file i.e. my fileSystem.root.getFile is giving me the error
Error code 1 i.e. File Not Found
After checking few stack overflow questions and http://rickluna.com/wp/2014/01/accessing-external-storage-in-android-phonegap-3-3/ blog I think my problem lies in "root"
i.e. my fileSystem obj (success callback of requestFileSystem method) looks like this:
filesystem: FileSystem
fullPath: "/"
isDirectory: true
isFile: false
name: ""
nativeURL: "file:///storage/emulated/0/"
__proto__: utils.extend.F
So is it possible to change the root? i.e. from file:///storage/emulated/0/ to file:///storage/ so that I can call getFile and pass the absolute url i.e. /extSdCard/DCIM when( file:///storage/) becomes root
I even tried by changing root i.e.
fileSystem.root.fullPath = 'file:///storage/';
even I tried to change the nativeURL property of fileSystem object but it's not working
ps. solution given in the blog hasn't worked for me
ps ps. The same code is working fine when my absolute url is: file:///storage/emulated/0/MRS/fileName.txt
and I am passing the relative url in function i.e. fileSystem.root.getFile("MRS/fileName.txt",...)

How to check if the file is having the same type as of its extension?

I want to build Javascript code which checks for the file type.In the web application which I am creating allows user to upload document files viz, doc, xls, ppt, docx, xlsx, pptx, txt, rar, zip, pdf, jpg, png, gif, jpeg, odt, but it should not allow other files. I can't check just extension name in file name. As user may change it.
I tried checking content-type but it is also getting changed everytime. Suggestions are appreciated.
In "modern" browsers (IE10+, Firefox 4+, Chrome 7+, Safari 6.0.2+ etc.), you could use the File/FileReader API to read the contents of the file and parse it client-side. E.g. (example, not production code):
var fileInput = /* Your <input type="file"> element */
fileInput.addEventListener("change", function(e) {
var file = e.currentTarget.files[0];
var reader = new FileReader();
reader.onload = fileLoaded;
reader.readAsArrayBuffer(file);
});
function fileLoaded(e)
{
var arrayBuffer = e.currentTarget.result;
// 32 indicates that we just want a look at the first 32 bytes of the buffer.
// If we don't specify a length, we get the entire buffer.
var bytes = new Uint8Array(arrayBuffer, 0, 32);
// Now we can check the content, comparing to whatever file signatures we
// have, e.g.:
if (bytes[0] == 0x50 &&
bytes[1] == 0x4b &&
bytes[2] == 0x03 &&
bytes[3] == 0x04)
{
// This is most likely docx, xlsx, pptx or other zip file.
}
}
http://jsfiddle.net/35XfG/
Note, however, that e.g. a .zip doesn't have to start with 50 4b 03 04. So, unless you spend quite a bit of time looking into different file signatures (or find some library that already did this), you're likely to be rejecting files that might actually be valid. Of course, it's also possible that it will give false positives.
False positives don't matter that much in this case, though - because this is only useful as a user friendly measure to check that the user isn't uploading files that will be rejected by the server anyway. The server should always validate what it ends up getting sent.
Of course, reading the entire file to look at the first few bytes isn't all that efficient either. :-) See Ray Nicholus' comment about that.
Unless you can actually parse the content and by the results tell whether the file is of a certain type, I don't see a good way of doing that with pure JS. You might want to consider to upload the file to the sever temporarily, and then perform the check on the server. The unix file command is a very useful tool for that. It does not rely on file extensions, but uses the file content to analyze the file type.

Categories

Resources