基于element-ui的upload 实现视频文件的第一帧显示

 htlm

    <el-upload
      
      :action="uploadFileUrl"
      class="hide_box"
      :on-preview="handlePreview"
      :before-upload="handleBeforeUpload"
      :disabled="true"
      multiple
      :file-list="fileList"
      :data="params"
      :on-success="addFile"
      :on-error="miss"
      :on-change="fileChange"
      list-type="picture-card"
      v-else
    >
    </el-upload>

触发上传成功后的事件

    addFile(response, file, fileList) {
      let _self = this;
            _self.fileList = fileList;
            if (file.status != 'success') {
                _self.$message({
                    message: '附件上传失败',
                    type: 'error'
                })
                _self.fileList.splice(_self.fileList.indexOf(file, 1))
            } else {
                if (this.VideoTypes.indexOf(response.fileExtension) >= 0) {   // 为我本地自定义判断是否是视频方法,可自己修改
                    //视频附件,获取第一帧画面作为 封面展示
                    _self.getVideoCover(file);
                }
            }
      this.$message({
        showClose: true,
        message: '文件上传成功',
        type: 'success'
      })
      this.fileData.url = response.url
      console.log(response)
      console.log(`上传的文件id为${response.id},下载地址为为${response.url}, 文件后缀为${response.fileExtension}`)
      file.fileExtension= response.fileExtension
    },

 获取第一帧的图片并且加上水印

        /**
         * 获取视频第一帧作为回显封面
         * @param file 至少应包含url信息,即 {url: ""}
         */
         getVideoCover(file) {
          console.log("回显封面");
            let _self = this;
            // _self.$set(file, 'videoUrl', _self.$utils.deepClone(file.url)); //备份视频源路径,用于后续预览展示
            
            const video = document.createElement("video") // 也可以自己创建video
            video.src = file.url // url地址 url跟 视频流是一样的
            // file.url = videoDefCover;   //设置默认封面,videoDefCover 为预制的默认封面,不需要可去除或替换成自己的
            let canvas = document.createElement('canvas') // 获取 canvas 对象
            const ctx = canvas.getContext('2d'); // 绘制2d
            video.crossOrigin = 'anonymous' // 解决跨域问题,也就是提示污染资源无法转换视频
            video.currentTime = 1 // 第一帧
            const watermarkImg = new Image();
            watermarkImg.src = "/image/video.jpg"; //水印
            watermarkImg.onload = () => {
            video.oncanplay = () => {
                console.log(video.clientWidth, video.clientHeight);
                canvas.width = video.clientWidth ? video.clientWidth : 320; // 获取视频宽度
                canvas.height = video.clientHeight ? video.clientHeight : 320; //获取视频高度
                // 利用canvas对象方法绘图
                ctx.drawImage(video, 0, 0, canvas.width,canvas.height)

                // 计算最大水印尺寸,不超过视频帧的一半
              const maxWatermarkSize = Math.min(canvas.width, canvas.height) / 2;
              const watermarkWidth = watermarkImg.naturalWidth * (maxWatermarkSize / watermarkImg.naturalHeight);
              const watermarkHeight = watermarkImg.naturalHeight * (maxWatermarkSize / watermarkImg.naturalWidth);

              // 绘制半透明居中水印
              ctx.globalAlpha = 0.9;
              const x = (canvas.width - watermarkWidth) / 2;
              const y = (canvas.height - watermarkHeight) / 2;
              ctx.drawImage(watermarkImg, 0, 0, watermarkImg.naturalWidth, watermarkImg.naturalHeight, x, y, watermarkWidth, watermarkHeight);

                // 转换成base64形式
                let _videoFirstimgsrc = canvas.toDataURL ("image/png"); // 截取后的视频封面
                _self.$set(file, 'url', _videoFirstimgsrc);   //重置文件的url为当前截取的封面,用于 el-upload展示
                video.remove();
                canvas.remove();
            }
          }
        },

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Element-UI 的 el-upload 组件本身并不支持分片上传,但是我们可以通过使用第三方库来实现分片上传的功能。 一种常见的方案是使用 axios 库来进行文件上传,并在上传时使用 axios 的分片上传功能。axios 库已经内置了分片上传的支持,我们可以使用 axios 的 `axios.post` 方法来上传文件,并使用 `onUploadProgress` 方法来监听上传进度。 首先,我们需要在项目中安装 axios 和 element-ui: ``` npm install axios element-ui --save ``` 然后,我们可以在组件中使用 el-upload 组件来上传文件,如下所示: ```html <template> <el-upload class="upload-demo" ref="upload" :action="uploadUrl" :headers="headers" :on-success="handleSuccess" :on-error="handleError" :on-progress="handleProgress" :file-list="fileList" :limit="limit" :multiple="multiple" :data="formData" :auto-upload="autoUpload" :show-file-list="showFileList" > <el-button size="small" type="primary">点击上传</el-button> </el-upload> </template> ``` 其中,我们需要设置 `action` 属性为文件上传的接口地址,同时需要设置 `on-success`、`on-error` 和 `on-progress` 等事件来处理上传成功、上传失败和上传进度。 接下来,我们可以在组件的 `mounted` 钩子函数中初始化 axios 并设置分片大小: ```js import axios from 'axios'; export default { name: 'UploadDemo', data() { return { fileList: [], uploadUrl: 'http://example.com/upload', limit: 3, multiple: true, formData: {}, autoUpload: true, showFileList: true, headers: {}, chunkSize: 5 * 1024 * 1024 // 5MB }; }, mounted() { axios.defaults.headers.post['Content-Type'] = 'multipart/form-data'; axios.defaults.timeout = 60000; // 超时时间 axios.defaults.retry = 3; // 重试次数 axios.defaults.retryDelay = 1000; // 重试间隔 // 设置分片大小 axios.defaults.maxContentLength = this.chunkSize; axios.defaults.maxBodyLength = this.chunkSize; }, methods: { // 上传文件 handleUpload(file) { const formData = new FormData(); formData.append('file', file); return axios.post(this.uploadUrl, formData, { headers: this.headers, onUploadProgress: progressEvent => { const percentCompleted = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); console.log(percentCompleted); } }); }, // 上传成功回调 handleSuccess(response, file, fileList) { console.log('上传成功:', response); }, // 上传失败回调 handleError(error, file, fileList) { console.log('上传失败:', error); }, // 上传进度回调 handleProgress(event, file, fileList) { console.log('上传进度:', event.percent); } } }; ``` 在 `handleUpload` 方法中,我们使用 axios 的 `post` 方法来上传文件,并设置了 `onUploadProgress` 方法来监听上传进度。在 `mounted` 钩子函数中,我们设置了 axios 的默认参数,包括超时时间、重试次数、重试间隔和分片大小等。 需要注意的是,由于 el-upload 组件不支持分片上传,因此我们需要手动控制上传的文件数量,以避免同时上传过多的文件导致服务器崩溃。我们可以通过设置 `limit` 属性来控制上传的文件数量,例如设置为 3 表示一次最多只能上传 3 个文件。 另外,如果需要支持断点续传,我们需要在上传文件时记录已上传的文件块数量和位置,并在下次上传时从上次的位置继续上传。这部分内容比较复杂,需要根据具体的需求来实现,这里不再赘述。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值