美文网首页
vue 过滤掉在移动端无法播放的视频

vue 过滤掉在移动端无法播放的视频

作者: 八妹sss | 来源:发表于2022-09-06 16:03 被阅读0次
    <template>
      <div class='mat-video-wrapper' v-loading='loading'>
        <!-- 编辑区域 -->
        <section class='edit-body'>
          <!-- 添加图文 -->
          <div v-show="!videoFile" class="add-video">
            <div class='add-icon'>添加视频</div>
            <input
              class="video-uploader"
              type="file"
              @change="subVideo"
              ref="fileInput"
              accept="video/mp4">
          </div>
          <!-- 图文预览区域 -->
          <div
            class='prev-box'
            v-show="videoFile">
            <div class='prev-main'
              v-loading="loadingVideo"
              element-loading-spinner="el-icon-loading"
              element-loading-text="上传中"
              element-loading-background="rgba(0, 0, 0, 0.8)"
              :style="{backgroundImage:`url('${picUrl}')`}">
              <video class="video-dom" ref='videoDOM' :src="fileSrc"></video>
              <span class='prev-icon' @click='startPreview()'></span>
            </div>
            <div class='prev-title'>{{videoFile ? videoFile.name || '标题' : '标题'}}</div>
            <div class="del" @click="delVideo()">删除</div>
          </div>
        </section>
        <div class='video-tip'>
          提示: 视频素材大小控制在{{wechatAccord ? '10M' : '5G'}}以内,支持MP4(H264编码格式)
        </div>
        <!-- 按钮区域 -->
        <section class='edit-btn'>
          <el-button size="small" type="primary" @click="saveEdit">保 存</el-button>
          <el-button size="small" @click="cancelEdit">取 消</el-button>
        </section>
        <!-- 视频的预览 -->
        <previewVideo
          v-show="showVideoPreview"
          :videoSrc="fileSrc"
          @handleClose="closePreviewVideo()"/>
        <!-- 图片上传 -->
        <shardUploader ref='upload1' :showSuccMsg='false'/>
      </div>
    </template>
    
    <script>
    import shardUploader from '@/public/shardUploader'
    import previewVideo from '@/public/preview/previewVideo'
    export default {
      name: 'matVideo',
      props: {
        mode: {
          type: String,
          default: 'create'
        },
        mat: {
          type: Object,
          default () {
            return {}
          }
        },
        // 是否按照威微信标准过滤素材列表
        wechatAccord: {
          type: Boolean,
          default: false
        }
      },
      components: {
        shardUploader,
        previewVideo
      },
      data () {
        return {
          loading: false,
          videoFile: null,
          fileSrc: '', // 视频本地播放地址
          loadingVideo: false, // 获取封面的loading
          picUrl: null, // 视频封面图
          videoDuration: null, // 视频播放时长
          videoDOM: null,
          showVideoPreview: false
        }
      },
      methods: {
        delVideo () {
          this.$refs.fileInput.value = ''
          this.videoFile = null
          this.picUrl = null
          this.videoDuration = null
        },
        subVideo () {
          let video = this.$refs.fileInput.files[0]
          if (video) {
            // 文件格式验证
            if (!/^video\//.test(video.type) || !/\.mp4$/.test(video.name)) {
              this.showWarning('视频文件只支持mp4格式')
              this.$refs.fileInput.value = ''
              return
            }
            // 大小验证, 用于微信消息则限制是10M,否则限制为5G
            let maxSize = this.wechatAccord ? 1024 * 1024 * 10 : 1024 * 1024 * 1024 * 5
            if (video.size > maxSize) {
              this.showWarning(`视频文件大小不能超过${this.wechatAccord ? '10M' : '5G'}`)
              this.$refs.fileInput.value = ''
              return
            }
            this.loading = true
            this.fileSrc = URL.createObjectURL(video)
            this.videoFile = video
            // this.loadingVideo = true
            // 截取视频的第一帧
            if (!this.videoDOM) {
              this.videoDOM = this.$refs.videoDOM
            }
            this.videoDOM.addEventListener('loadeddata', this.getVideoFirstImg(video))
          }
        },
        // 获取视频第一帧
        getVideoFirstImg (video) {
          this.videoDOM.removeEventListener('loadeddata', this.getVideoFirstImg)
          // 获取第一帧
          setTimeout(() => {
            // 获取视频时长
            this.videoDuration = this.videoDOM.duration
            if (!this.videoDuration) {
              this.loading = false
              return this.showWarning('视频格式或mp4编码格式不支持')
            }
            let canvas = document.createElement('canvas') // 创建一个画布
            canvas.width = this.videoDOM.videoWidth
            canvas.height = this.videoDOM.videoHeight
            canvas.getContext('2d').drawImage(this.videoDOM, 0, 0, canvas.width, canvas.height) // getContext:设置画布环境;drawImage:画画
            let imgDataUrl = canvas.toDataURL('image/png') // 获取图片的url
            // console.log('imgDataUrl: ', imgDataUrl)
            // 判断生成的base64是否符合格式
            if (!/;base64/.test(imgDataUrl)) {
              this.showWarning('视频格式或mp4编码格式不支持')
              this.loading = false
            } else {
              // 转换为图片file文件,并上传到服务器
              let imgFile = this.dataURLtoFile(imgDataUrl, new Date().getTime())
              this.$refs.upload1.uploadFile(imgFile, result => {
                this.loadingVideo = false
                this.picUrl = result.url
                this.loading = false
              })
            }
          }, 1000)
        },
        startPreview () {
          this.showVideoPreview = true
        },
        closePreviewVideo () {
          this.showVideoPreview = false
        },
        saveEdit () {
          // 验证视频的标题不能为空
          if (!this.videoFile) {
            this.loading = false
            return this.$message({ message: '请先上传视频素材', type: 'warning' })
          }
          if (!this.videoDuration) {
            this.loading = false
            return this.showWarning('获取视频长度失败, 请检查视频格式')
          }
          if (this.loading) {
            return false
          }
          // this.loading = true
          // 首先上传图片到服务器,获取图片链接
          this.$refs.upload1.uploadFile(this.videoFile, result => {
            setTimeout(() => {
              let formData = new FormData()
              formData.append('fileUrl', result.url)
              formData.append('fileName', result.name)
              formData.append('fileSize', result.size)
              formData.append('picUrl', this.picUrl)
              formData.append('duration', parseInt(this.videoDuration * 1000))
              let appid = sessionStorage.getItem('appid')
              let url = `${this.SERVICE_WECHAT}/upgrade/media/${appid}/video/upload`
              this.posts(url, formData).then(res => {
                if (res.data.code === 200) {
                  this.showSucc(res.data.message)
                  let data = res.data.data
                  let info = {
                    picUrl: this.picUrl,
                    mediaName: this.videoFile.name
                  }
                  if (data) {
                    info.id = data
                  }
                  this.$emit('success', info)
                }
                this.loading = false
              }).catch(e => {
                this.loading = false
                this.handleError(e)
              })
            }, 1000)
          })
        },
        cancelEdit () {
          this.$emit('cancel')
        }
      },
      created () {
        // console.log('wechatAccord: ', this.wechatAccord)
      }
    }
    </script>
    
    <style lang="stylus" scoped>
    .mat-video-wrapper
      min-height calc(100% - 70px)
      padding-bottom 70px
      position relative
      .edit-body
        padded_box(border-box,0 10px)
        display flex
        align-items center
        .add-video
          width 275px
          height 160px
          background #f2f2f6
          position relative
          .add-icon
            position absolute
            left 0
            right 0
            top 0
            bottom 0
            margin auto
            width 64px
            height: 21px;
            font-size: 14px;
            color: #5E5E66;
            line-height: 21px;
            padding-top 24px
            text-align center
            &:before, &:after
              content ''
              display block
              width 20px
              height 2px
              background: #ACAEBC;
              position absolute
              left 0
              right 0
              top 0
              margin auto
            &:after
              transform rotate(90deg)
          .video-uploader
            position absolute
            z-index 1
            left 0
            top 0
            width 100%
            height 100%
            opacity 0
            cursor pointer
          .video-box
            width 0
            height 0
            opacity 0
        .prev-box
          width 275px
          position relative
          .del
            line-height 18px
            font-size 14px
            color #4c84ff
            cursor pointer
            position absolute
            right -44px
            bottom 0px
          .prev-main
            position relative
            width 100%
            height 108px
            background-color #F7F7F7;
            background-position center
            background-repeat no-repeat
            background-size cover
            cursor pointer
            .video-dom
              object-fit cover
              width 100%
              height 100%
              position absolute
              top 0
              left 0
              visibility hidden
            .prev-icon
              position absolute
              left 0
              right 0
              top 0
              bottom 0
              background url('~assets/img/enterprise/video_ic_play@2x.png') no-repeat center / 30px
              z-index 4
          .prev-title
            height 50px
            line-height 50px
            border 1px solid #ddd
            padding 0 9px
            font-size 14px
            color #333
            no-wrap()
      .video-tip
        padding 15px 10px
        color #666
      .edit-btn
        position absolute
        left 0
        right 0
        bottom 0
        padding 20px 0
        text-align center
    </style>
    

    相关文章

      网友评论

          本文标题:vue 过滤掉在移动端无法播放的视频

          本文链接:https://www.haomeiwen.com/subject/vxmgnrtx.html