【问题标题】:Get content type of 'File' object using javascript使用 javascript 获取“文件”对象的内容类型
【发布时间】:2015-07-25 18:15:18
【问题描述】:

我有两个具有相同扩展名的文件,如下所示:

1) test_audio_file.mp4(仅包含音频内容)

2) test_video_file.mp4(由音视频内容组成)

上传文件后,我正在创建上传文件的File对象。

我想检查File 对象的内容类型。即audio/mp4 用于第一个文件,video/mp4 用于第二个文件。

当我使用file_object.type 方法打印文件类型时,在这两种情况下我都会得到video/mp4

我的假设是我将获得audio/mp4 用于第一个文件,video/mp4 用于第二个文件。

我这里放一行代码:

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

是否有任何方法或方法可以为第一个文件获取内容类型 audio,为第二个文件获取 video

任何想法都会很棒。谢谢!

【问题讨论】:

  • 我刚刚创建了我从浏览器中选择的文件的文件对象的实例,并检查了文件实例的“类型”属性。它在两种文件情况下都打印video/mp4
  • 贴一些代码老兄!!这样我们就可以解决这个问题了!!
  • @GuruprasadRao:已发布!我想你会得到更好的主意。
  • 你在使用任何插件吗??你在哪里写这个loadFile??
  • 我只是在一个js文件中编写了这个方法,当你浏览任何文件并且文件已经在浏览器中加载后,该方法将被调用。然后我只是打印出file 实例的类型。对于仅包含音频内容的文件,这给了我video/mp4。我相信如果文件仅包含音频内容,它应该返回“audio/mp4”。

标签: javascript jquery file object content-type


【解决方案1】:

浏览器通常会通过文件扩展名假设 mime 类型,在这两种情况下都是 mp4。

可以肯定的是,您可以检查文件的二进制内容。

示例

假设您已将文件加载到 ArrayBuffer 中,您可以首先为其创建一个灵活的视图(Uint32Array 不能用作缓冲区的长度必须是 4 字节对齐的,文件并非总是如此,并且 DataView 会为你做 big-endian 到 little-endian 的交换):

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

更新:删除了“不需要的”第一次检查/用于我建议在任何情况下都使用的框大小。添加了更多详细信息。)

然后,检查 atomMP4 file-format 使用“atoms”和“boxes”而不是像许多其他类似格式中的“chunks”)“ftyp”(0x66747970)以字节 4-8(大端)为单位:

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

现在检查 什么这是 MP4 类型:

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

我们现在可以为音频创建一个具有正确 mime 类型集的对象 URL:

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

注意,您需要考虑许多其他类型(使用十六进制编辑器检查您期望的文件的实际值),您可能会想要使用带有indexOf() 的数组来检查多个可能的值:

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

作为后备,您可以假设 video/mp4 用于未知的标头和类型,创建一个带有 video/mp4 作为 mime-type 的 blob 并让浏览器从那里处理文件。

有关偏移量和盒子长度的详细信息,请参见上面的链接。

工作演示

以下演示仅限于检查给定示例文件的类型。您当然需要扩展其他 MP4 类型(类型字段)以检查实际应用程序,例如使用一个用于音频类型的数组、一个用于视频等的数组。

加载其中一个文件以对其进行分析。

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">

【讨论】:

    【解决方案2】:

    你可以试试

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

    这里有详细描述https://stackoverflow.com/a/7412549/3327294

    【讨论】:

    • 如果我不是想要的类型,我该如何匹配这些东西。我的意思是我的第一个文件得到video/mp4,第二个文件得到video/mp4。我相信它应该为第一个文件返回audio/mp4。有意义吗?
    猜你喜欢
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    相关资源
    最近更新 更多