当前位置: 首页 > news >正文

【前端】上传视频,截取第一帧图片

使用input上传视频,获得视频的第一帧
参考:JavaScript获取视频的尺寸信息和第一帧图片 - 掘金 (juejin.cn)

html:

<inputbind:this={uploadRef}on:change={handleUpload}accept="video/*"type="file"/>

视频类型校验:

const VIDEO_REG =/^(?:video\/avi|video\/mpeg|video\/mp4|video\/ogg|video\/webm|video\/x-ms-wmv|video\/x-msvideo)$/i;

handleUpload

  • 校验类型
  • 获得视频第一帧图片:调用getVideoImg方法
const handleUpload=(e)=>{const files = e.target.files[0];if(VIDEO_REG.test(files.type)){const videoImg = await getVideoImg(files);}
}

相关方法:getVideoImg

使用canvas实现:从一个视频文件中提取一帧图像,并将这个图像转换为一个可以在浏览器中使用的URL。

const getVideoImg = async (files: File): Promise<string> => {try {// 使用loadVideo函数加载视频文件,等待加载完成const video: HTMLVideoElement = await loadVideo(files);const canvasElem = document.createElement('canvas');// 设置canvas的宽度和高度与视频的宽度和高度相同canvasElem.width = video.videoWidth;canvasElem.height = video.videoHeight;// 获取canvas的2d渲染上下文,并在canvas上绘制视频的当前帧canvasElem.getContext('2d')?.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);const pngFile = await new Promise<string>((resolve, reject) => {// 将canvas的内容导出成一个blob文件canvasElem.toBlob((blob) => {if (blob) {// 成功创建了blob文件,将其转换为File对象,然后创建一个指向这个File对象的URLresolve(URL.createObjectURL(toThumbFile(blob)));} else {// 创建blob文件失败,拒绝Promisereject('');}}, 'image/png');});// 返回Promise的结果,即指向File对象的URLreturn pngFile;} catch (error) {// 如果在上述过程中发生错误,打印错误信息console.error(error);}
};

其中调用了loadVideo

const loadVideo = (file: File): Promise<HTMLVideoElement> => {return new Promise(function (resolve, reject) {const videoElem = document.createElement('video');const dataUrl = URL.createObjectURL(file);videoElem.onloadeddata = function () {// 当video元素的当前帧的数据可用时,将video元素作为Promise的结果resolve(videoElem);};// 当video元素发生错误时的处理函数videoElem.onerror = function () {reject('video error');};// 设置video元素的preload属性为'auto',这样video元素会预加载数据// 如果不设置这个属性,可能会导致截图为黑色图片的情况videoElem.setAttribute('preload', 'auto');// 设置video元素的src属性为指向File对象的URLvideoElem.src = dataUrl;});
};// 输入的Blob对象,文件名是'video_img.png'
const toThumbFile = (blob) => new File([blob], 'video_img.png');

调用:

videoImg = await getVideoImg(files);

得到的videoImg 可以在<img src={videoImg }/> 中显示。

不用videoImg 后,要使用URL.revokeObjectURL释放:URL.createObjectURL生成的链接以blob:开头。一般来说在 销毁 的生命周期调用。

if (/^blob:/.test(videoImg)) {URL.revokeObjectURL(videoImg);}
http://www.lryc.cn/news/410052.html

相关文章:

  • Redis-GEO数据结构的基本用法
  • 【Linux C | 网络编程】进程池大文件传输的实现详解(三)
  • Mac如何通过SSH连接Github
  • 成就巴西休闲游戏如何借助Google谷歌广告投放优势
  • 利用python检查磁盘空间使用情况
  • 卷积神经网络(五)---图像增强的方法
  • 矩阵常见分解算法及其在SLAM中的应用
  • 【排序】快速排序详解
  • 贪心算法总结(2)
  • 弘景光电:技术实力与创新驱动并进
  • 2024年7月23日~2024年7月29日周报
  • M3U8流视频数据爬虫
  • 保护您的数字财富:模块化沙箱在源代码防泄露中的突破
  • FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析
  • 如何使用 API 查看极狐GitLab 镜像仓库中的镜像?
  • 软件-vscode-plantUML-IDEA
  • ES6语法详解,面试必会,通俗易懂版
  • CTFshow--Web--代码审计
  • Java语言程序设计——篇十(1)
  • Qt对比MFC优势
  • RuntimeError: No CUDA GPUs are available
  • URL参数中携带中文?分享 1 段优质 JS 代码片段!
  • sass的使用
  • 【足球走地软件】走地数据分析预测【大模型篇】走地预测软件实战分享
  • 现在有什么赛道可以干到退休?
  • c程序杂谈系列(职责链模式与if_else)
  • 前端开发技术之CSS(层叠样式表)
  • go语言day20 使用gin框架获取参数 使用自定义的logger记录日志
  • DHCP笔记
  • TCP为什么需要四次挥手?