简体   繁体   English

使用JavaScript获取“文件”对象的内容类型

[英]Get content type of 'File' object using javascript

I have two files with same extensions as follows: 我有两个具有相同扩展名的文件,如下所示:

1) test_audio_file.mp4 (Consist of only audio content) 1) test_audio_file.mp4 (仅包含音频内容)

2) test_video_file.mp4 (Consist of audio and video content) 2) test_video_file.mp4 (由音频和视频内容组成)

After uploading a file, I am creating File object of uploaded file. 上传文件后,我正在创建上传文件的File对象。

I want to check content type of the File object. 我想检查File对象的内容类型。 ie audio/mp4 for first file and video/mp4 for second file. 例如, audio/mp4用于第一个文件, video/mp4用于第二个文件。

When I print the file type using file_object.type method, I am getting video/mp4 in both the cases. 当我使用file_object.type方法打印文件类型时,在两种情况下都得到video/mp4

My assumption was I will get audio/mp4 for first file and video/mp4 for the second file. 我的假设是,第一个文件将获得audio/mp4 ,第二个文件将获得video/mp4

I am putting a line of code here: 我在这里放一行代码:

loadFile: function(file) {
   console.log(file.type);
};

Is there any method or way to get a content type audio for first file and video for second file. 是否有任何方法或方法来获取第一个文件的内容类型audio和第二个文件的video类型。

Any ideas would be great. 任何想法都很棒。 Thanks! 谢谢!

you can try 你可以试试

input.file.type.match('video.*')

It is described in detail here https://stackoverflow.com/a/7412549/3327294 在这里详细描述https://stackoverflow.com/a/7412549/3327294

The browser will assume a mime-type often by the file extension which in both cases here are mp4. 浏览器通常会通过文件扩展名来假定为mime类型,在两种情况下均为mp4。

To be sure, you can check the binary content of the file. 可以肯定的是,您可以检查文件的二进制内容。

Example

Assuming you have loaded the file in an ArrayBuffer you could first create a flexible view for it (Uint32Array cannot be used as the length of the buffer must be 4-bytes aligned which is not always the case for the file, and DataView will do big-endian to little-endian swapping for you): 假设您已将文件加载到ArrayBuffer ,则可以首先为其创建一个灵活的视图(Uint32Array不能使用,因为缓冲区的长度必须对齐4字节,这并不总是文件的情况,DataView会做得很大-endian到little-endian交换):

var view = new DataView(buffer);              // buffer = ArrayBuffer

( Update : removed "unneeded" first check/used for box size which I recommend to use in any case. More details added.) 更新 :我建议在任何情况下都使用“不需要”的第一个检查/检查框的大小。建议添加更多详细信息。)

Then, check for the atom (the MP4 file-format operates with "atoms" and "boxes" instead of "chunks" as in many other similar formats) " ftyp " (0x66747970) in bytes 4-8 (big-endian): 然后,检查原子MP4文件格式使用“ atoms”和“ boxes”而不是“ chunks”,就像许多其他类似格式一样)“ ftyp ”(0x66747970),字节4-8(大端):

if (view.getUint32(4) === 0x66747970) {       // = "ftyp"
    // ok, so far so good..
}

Now check what type of MP4 this is: 现在检查这是什么类型的MP4:

if (view.getUint32(8) === 0x64617368) {       // = "dash"
    // audio
}
else if (view.getUint32(8) === 0x6D703432) {  // = "mp42"
    // audio + video
}

We can now create an object-URL with the proper mime-type set, for audio: 现在,我们可以为音频创建带有正确的mime-type设置的object-URL:

var blob = new Blob([buffer], {type: "audio/mp4"});
var url = URL.createObjectURL(blob);  // src for video/audio element

Note that there are many other types that you need to consider (use a hex editor to inspect the actual values of the files you expect) and you will probably want to use arrays with indexOf() to check for multiple possible values: 请注意 ,还需要考虑许多其他类型 (使用十六进制编辑器检查所需文件的实际值),并且可能要使用带有indexOf()数组来检查多个可能的值:

var videoTypes = [0x6D703432, 0x69736F6D, ...];   // mp42, isom, ...
...
var type = view.getUint32(8);
if (videoTypes.indexOf(type) > -1) { /* ok! */ }

As a fallback you can assume video/mp4 for unknown headers and types, create a blob with video/mp4 as mime-type and let the browser deal with the file from there. 作为后备,您可以假定video/mp4了未知的标头和类型,创建了一个video/mp4作为mime-type的blob,然后让浏览器从那里处理文件。

Also see link above for details on offsets and box lengths. 另请参阅上面的链接,以获取有关偏移量和框长度的详细信息。

Working demo 工作演示

The following demo is limited to check for the types of the given example files. 以下演示仅限于检查给定示例文件的类型。 You will of course need to extend for other MP4 types (type field) to check in the real-world application using for example one array for audio types, one for video etc. 当然,您将需要扩展其他MP4类型(类型字段)以使用诸如音频类型的一种数组,视频类型的一种数组等在实际应用中进行检入。

Load one of the files to have it analyzed. 加载其中一个文件进行分析。

 var inp = document.querySelector("input"); inp.onchange = function(e) { var reader = new FileReader(); reader.onload = analyze; reader.readAsArrayBuffer(e.target.files[0]); }; function analyze(e) { var buffer = e.target.result, view = new DataView(buffer), blob, url; // check file type if (view.getUint32(4) !== 0x66747970) { // = "ftyp" alert("Not MP4 file!"); return } // check if audio or audio+video if (view.getUint32(8) === 0x64617368) { // = "dash" alert("Audio\\n(See console for example url)"); blob = new Blob([buffer], {type: "audio/mp4"}); } else if (view.getUint32(8) === 0x6D703432 || // = "mp42" view.getUint32(8) === 0x69736F6D) { // = "isom" alert("Video+Audio\\n(See console for example url)"); blob = new Blob([buffer], {type: "video/mp4"}); } else { // assume video/mp4 alert("Unsupported:\\n0x" + (view.getUint32(8)).toString(16)); blob = new Blob([buffer], {type: "video/mp4"}); } // convert blob to an URL that can be used with a video/audio element url = (URL || webkitURL).createObjectURL(blob); console.log("Copy and paste this into a tab, wo/quotes:", url); } 
 Pick a MP4 file: <input type="file"> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM