Open Sunshine168 opened 5 years ago
通过JS在浏览器里获取图片属性和视频属性的主要还是借助img和video标签在已有进行获取,而不是借助wasm等手段对文件进行完整解析。最终我们可以获取到图片的实际尺寸,视频的时长,分辨率(由视频的宽高组成)等属性
为什么会有这样的需要,源自于需求—— 是因为对这类的媒体文件是有限制的,如果上传完再进行解析,这里不仅需要等待而且使用者可能会发现自己辛辛苦苦(不看规则)上传视频和图片无效,然后需要重新上传,这样会有非常不好的体验。
所以为了解决这种问题,所以就有了我们需要在上传的时候做检测,当然这种检测是有局限性的,最好的办法是在服务端支持降级的方案,这里不展开。
需要注意的地方,由于我们是借助img标签和video标签进行解析,那么我们在我们支持的格式上就必须是所在浏览器支持的文件类型。
以视频文件为例子,Avi类型的视频文件就是不被支持的,而mp4和mov文件则是被支持良好的。
以图片文件为例tiff就是不被支持的,在safari上webp就是不被支持的。
我们需要借助的核心API
window.URL.createObjectURL
总体来说兼容性表现非常好 通过引用来介绍一下这个API
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
大体来说就是传入Blob或者Blob的衍生子类,File是继承自Blob的,然后会返回一个url,这个是在当前窗口中可用的该文件的url。简单说来说就可以直接
<img src={url}/>
另外需要注意的是在使用完这个链接后,尽可能的主动通过 URL.revokeObjectURL()对资源进行释放,如果不主动释放的话,会在页面关闭的时候释放掉。
//tool const promiseTimer: promiseTimer = time => { return new Promise(resolve => setTimeout(resolve, time)); };
export const getImagePropertyFormFile = async file => { let url; let image; try { url = window.URL.createObjectURL(file); image = await getImage(url, 2000); } catch (e) { return { err: e }; } // 返回图片的属性 return {image}; }; export const getImage = (url, timeout) => { const loadImagePromise = new Promise(resolve => { const img = new Image(); img.src = url; // onload说明加载完毕 img.onload = () => { resolve(img); }; }); // 超时的时候方便重试和降级 return Promise.race([loadImagePromise, promiseTimer(timeout)]); };
export const getVideo = (url, timeout) => { const loadVideoPromise: Promise<IVideoTagInfo> = new Promise(resolve => { const video = document.createElement('video'); //仅预加载视频的元信息 video.preload = 'metadata'; //onloadedmetadata 说明这个视频元信息加载完毕 video.onloadedmetadata = () => { resolve(video); }; video.src = url; }); return Promise.race([loadVideoPromise, promiseTimer(timeout)]); };
具体业务不一样,就不针对整个获取信息并检验以及支持降级的插件进行说明了
前言
通过JS在浏览器里获取图片属性和视频属性的主要还是借助img和video标签在已有进行获取,而不是借助wasm等手段对文件进行完整解析。最终我们可以获取到图片的实际尺寸,视频的时长,分辨率(由视频的宽高组成)等属性
为什么会有这样的需要,源自于需求—— 是因为对这类的媒体文件是有限制的,如果上传完再进行解析,这里不仅需要等待而且使用者可能会发现自己辛辛苦苦(不看规则)上传视频和图片无效,然后需要重新上传,这样会有非常不好的体验。
所以为了解决这种问题,所以就有了我们需要在上传的时候做检测,当然这种检测是有局限性的,最好的办法是在服务端支持降级的方案,这里不展开。
需要注意的地方,由于我们是借助img标签和video标签进行解析,那么我们在我们支持的格式上就必须是所在浏览器支持的文件类型。
以视频文件为例子,Avi类型的视频文件就是不被支持的,而mp4和mov文件则是被支持良好的。
以图片文件为例tiff就是不被支持的,在safari上webp就是不被支持的。
思路:
我们需要借助的核心API
总体来说兼容性表现非常好 通过引用来介绍一下这个API
大体来说就是传入Blob或者Blob的衍生子类,File是继承自Blob的,然后会返回一个url,这个是在当前窗口中可用的该文件的url。简单说来说就可以直接
另外需要注意的是在使用完这个链接后,尽可能的主动通过 URL.revokeObjectURL()对资源进行释放,如果不主动释放的话,会在页面关闭的时候释放掉。
Code Snippet
具体业务不一样,就不针对整个获取信息并检验以及支持降级的插件进行说明了