video 标签获取视频时长、宽高等信息的兼容性问题

2,282 阅读2分钟

我们在做视频上传的视频需要对视频的大小、时长、分辨率、宽高比有要求。但是在视频上传的时候,我们只能获取到文件的名称、大小、格式,并不能获取到时长、分辨率、宽高比信息,那怎么获取视频时长、分辨率和宽高比才比较合理呢?

视频信息获取

<input type="file" />

const url = URL.createObjectURL(file);
const video = document.createElement("video");
video.onloadedmetadata = evt => {
  // 每次调用createObjectURL都会创建一个新的URL,因此需要调用revokeObjectURL释放掉
  URL.revokeObjectURL(url);
  const meta = {
    duration: video.duration,
    width: video.videoWidth,
    height: video.videoHeight
  }
  console.log(meta);
  video.remove();
};
video.src = url;

网上常见的方案是通过video标签获取,但是这种代码基本不能用在线上。video 标签获取视频时长、分辨率、宽高比还是存在非常大兼容性问题的。

视频解码问题

video 标签获取视频地址后进行播放,其基本原理会把视频拉到本地进行解码。video 标签在主流的浏览器上都是支持的,可以查看 video 。但是有很多格式的视频,video 是不支持解码的。例如典型的 H265编码的视频。这类视频其实很常见,iphone手机打开60帧高清拍摄出来的视频,就是H265编码的视频。video 标签就无法播放。

针对以上问题,我们就需要了解有哪些编解码器,分别都支持什么容器格式,哪些浏览器支持?

容器格式编码格式chrome是否支持
mp4h264
mp4h265

以上的例子看到,我们不能通过容器的格式来判断编码格式,通过input控制容器的方式来控制编码是不行的。

<input type="file" accept="wmv,avi,mpg,mpeg,3gp,mov,mp4,flv,m2t,mts,mkv"/>

wmv,avi,mpg,mpeg,3gp,mov,mp4,flv,m2t,mts,mkv是比较常见的视频格式。

当然更多的音视频有这么多格式:wmv,avi,mpg,mpeg,3gp,mov,mp4,flv,f4v,m4v,m2t,mts,rmvb,vob,mkv,mp3,aac,flac,amr,m4a,wav,wma

兼容解码方案

因为video的兼容性问题,我们有3个思路解决。

  1. 直接放过不能播放的视频
  2. 自制播放器,也就是自制解码,但是web侧的软解还是依赖chrome本身的能力,因此类似H265有软解能力,也会非常耗时。
  3. 利用ffmpeg能力,ffmpeg 可以使用 wasm 打到浏览器中,然后读取视频元信息。另一种就是直接把视频进行上传,服务进行元信息返回并且进行转码。在服务侧做当然是最好的,不过逃不了耗时的问题。

方案结合后可以先通过video过滤,然后video无法识别的通过ffmpeg服务进行解决。当然也可以中间加一层,前端ffmpeg进行处理。

graph TD
video --> ffmpeg-wasm
ffmpeg-wasm --> ffmpeg服务

当然也可以用ffmpeg返回信息,不通过video。

graph TD
ffmpeg-wasm --> ffmpeg服务