我们在做视频上传的视频需要对视频的大小、时长、分辨率、宽高比有要求。但是在视频上传的时候,我们只能获取到文件的名称、大小、格式,并不能获取到时长、分辨率、宽高比信息,那怎么获取视频时长、分辨率和宽高比才比较合理呢?
视频信息获取
<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是否支持 |
|---|---|---|
| mp4 | h264 | 是 |
| mp4 | h265 | 否 |
以上的例子看到,我们不能通过容器的格式来判断编码格式,通过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个思路解决。
- 直接放过不能播放的视频
- 自制播放器,也就是自制解码,但是web侧的软解还是依赖chrome本身的能力,因此类似H265有软解能力,也会非常耗时。
- 利用ffmpeg能力,ffmpeg 可以使用 wasm 打到浏览器中,然后读取视频元信息。另一种就是直接把视频进行上传,服务进行元信息返回并且进行转码。在服务侧做当然是最好的,不过逃不了耗时的问题。
方案结合后可以先通过video过滤,然后video无法识别的通过ffmpeg服务进行解决。当然也可以中间加一层,前端ffmpeg进行处理。
graph TD
video --> ffmpeg-wasm
ffmpeg-wasm --> ffmpeg服务
当然也可以用ffmpeg返回信息,不通过video。
graph TD
ffmpeg-wasm --> ffmpeg服务