【问题标题】:How to get duration of video when I am using filereader to read the video file?使用文件阅读器读取视频文件时如何获取视频时长?
【发布时间】:2015-05-06 09:38:42
【问题描述】:

我正在尝试将视频上传到服务器和客户端。我正在使用 FileReader 的 readAsBinaryString() 阅读它。

现在,我的问题是,我不知道如何读取这个视频文件的时长。

如果我尝试读取文件,并将读取器的数据分配给视频标签的源,则不会触发与视频标签相关的任何事件。我需要找到在客户端上传文件的持续时间。

有人可以给我一些建议吗?

【问题讨论】:

  • 视频是什么类型的文件?

标签: javascript html5-video filereader


【解决方案1】:

您可以这样做:

  • 将文件作为 ArrayBuffer 读取(以后可以作为二进制流直接发布到服务器)
  • 将其包装在 Blob 对象中
  • 为 blob 创建一个对象 URL
  • 最后将url设置为视频源。

当视频对象触发loadedmetadata 事件时,您应该能够读取持续时间。

您也可以使用 data-uri,但请注意,浏览器可能会为它们应用 size limits (as well as other disadvantages),这对于视频文件来说是必不可少的,并且由于 Base-64 进程存在大量的编码/解码开销。

示例

选择一个你知道浏览器可以处理的视频文件(在生产中你当然应该根据video.canPlayType()过滤接受的文件类型)。

执行上述步骤后将显示持续时间(示例中不包含错误处理,根据需要进行调整)。

var fileEl = document.querySelector("input");
fileEl.onchange = function(e) {

  var file = e.target.files[0],                               // selected file
      mime = file.type,                                       // store mime for later
      rd = new FileReader();                                  // create a FileReader
  
  rd.onload = function(e) {                                   // when file has read:
    
    var blob = new Blob([e.target.result], {type: mime}),     // create a blob of buffer
        url = (URL || webkitURL).createObjectURL(blob),       // create o-URL of blob
        video = document.createElement("video");              // create video element

    video.preload = "metadata";                               // preload setting
    video.addEventListener("loadedmetadata", function() {     // when enough data loads
      document.querySelector("div")
          .innerHTML = "Duration: " + video.duration + "s";   // show duration
      (URL || webkitURL).revokeObjectURL(url);                // clean up

      // ... continue from here ...

    });
    video.src = url;                                          // start video load
  };
  rd.readAsArrayBuffer(file);                                 // read file object
};
<input type="file"><br><div></div>

【讨论】:

  • 同样值得注意的是:非常大 (~250 mb+) 的视频文件不适合这样做。对于那些,直接上传到服务器,从服务器加载视频文件作为视频元素的源,让浏览器缓存它(元数据),提取持续时间并发送回时间以随时间更新服务器/数据库(或使用 ffmpeg 或类似的东西在服务器端直接从文件中读取时间)。可以选择手动解析文件头,但这超出了 SO 的范围。
  • @K3N +1 救生员。这是我能找到的唯一可行的解​​决方案,而无需将整个视频加载到内存中。使用类似的解决方案从视频中提取图像有多容易?
  • @GFoley83 这很简单。只需使用currentTime 设置您想要抓取帧的时间。当timeupdate 事件触发时,只需使用视频元素作为图像源绘制到画布元素。
  • @K3N @Shivi 我已经运行了一些测试来从视频开头读取字节以获取元数据。如果您在rd.readAsArrayBuffer(file); 之前添加file = file.slice(0, 500000); // .5MB,您甚至可以从大文件中解析元数据(它应该始终位于视频文件的开头),例如在我的测试中 > 12GB,因为你只加载了一小块。此处示例:jsfiddle.net/gavinfoley/9saxaoak
  • URL.createObjectURL 可以直接在file 上使用,至少在 2018 年使用现代浏览器。
【解决方案2】:

您可以执行以下操作,诀窍是使用readAsDataURL

var reader = new FileReader();
reader.onload = function() {
    var media = new Audio(reader.result);
    media.onloadedmetadata = function(){
         media.duration; // this would give duration of the video/audio file
    };    
};
reader.readAsDataURL(file); 

Fiddle Demo

【讨论】:

  • 请注意,data-uri 有大小限制(取决于浏览器),这对于视频文件可能是必不可少的,并且具有明显的编码/解码(base-64)开销。
猜你喜欢
  • 2015-05-30
  • 2011-04-25
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 2020-06-22
相关资源
最近更新 更多