前端demo: COS上传图片、视频、文件的一些点

1.选择相同视频未触发change事件




参考:INPUT[type=file]的change事件不触发问题_风神修罗使的博客-CSDN博客

2.监听change事件判断文件类型

    function bindChangeEvent() {
      $(document)
        .off("change")
        .on("change", "#file", function () {
          var fileObj = $(this);
          if (fileObj.val().length < 1) return;

          var file = fileObj[0].files["0"];
          if (!file) return;

          const type = file.type;
          const supportedTypes = ["video", "image", "rar", "zip"];

          if (type && !supportedTypes.some((e) => type.includes(e))) {
            alert("暂不支持上传");
            return;
          }

          // rar文件类型的type为空,此时根据文件名后缀判断
          if (!type && !/\.rar$/.test(file.name)) {
            alert("暂不支持上传");
            return;
          }

          if (type.includes("image/")) {
            uploadPic(file); // todo: 上传图片
          } else {
            uploadFile(file, type); // todo: 上传文件
          }
        });
     }

3.判断文件大小

   function isSopportSize(file, size) {
        if (file.size.toFixed(2) > size * 1024 * 1024) {
          alert(`请选择小于${size}MB的文件`);
          return false;
        }
        return true
      }

4.上传Key为mov格式文件到COS无法播放,特殊处理改为mp4

   if (/\.(mov|MOV)$/.test(file.name)) {
        fileName = file.name.replace(/\.(mov|MOV)$/, '.mp4')
    }

5.cos 实例调用 COS 请求

    // cos 实例调用 COS 请求
    cos.uploadFile(
        {
            Bucket,
            Region,
            Body: file,
            SliceSize: 1024 * 1024 * 5, // 分块上传会多次调用 new COS中传入的getAuthorization
            ContentType: type,  // 添加上传的文件类型,COS会根据该类型设置Content-Type
            Key: fileName,
            ...

        })

6.获取视频时长的3种方法

使用HTML5的File API和Video API:

    

    
  • 使用第三方库如`video.js`进行视频播放和获取时长:
    

    
    

    
  • 使用ffmpeg.js进行视频解码和获取时长(需要将视频文件上传到服务器进行解码):


    

    

 注意:

  • 以上实现方式可能需要使用`http(s)`协议进行访问,因为某些浏览器限制了`file://`协议下的一些操作。另外,第三方库`video.js`和`ffmpeg.js`需要在支持`HTML5`的浏览器中使用。
  • 微信浏览器h5 loadedmetadata 兼容性问题参考微信浏览器h5 loadedmetadata 兼容性问题_weixin_45191052的博客-CSDN博客

7.时长和文件单位工具函数

  // 文件单位转换
    filesizeConvert(size) {
        var data = ''
        if (size < 0.1 * 1024) {
            data = size.toFixed(2) + 'B'
        } else if (size < 0.1 * 1024 * 1024) {
            data = (size / 1024).toFixed(2) + 'KB'
        } else if (size < 0.1 * 1024 * 1024 * 1024) {
            data = (size / (1024 * 1024)).toFixed(2) + 'MB'
        } else {
            data = (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
        }
        var sizestr = data + ''
        var len = sizestr.indexOf('.')
        var dec = sizestr.substr(len + 1, 2)
        if (dec == '00') {
            return sizestr.substring(0, len) + sizestr.substr(len + 3, 2)
        }
        return sizestr
    },
    // 视频格式化
    formatDuraton(time) {
        if (time > -1) {
            var hour = Math.floor(time / 3600)
            var min = Math.floor(time / 60) % 60
            var sec = time % 60
            if (hour < 10) {
                time = '0' + hour + ':'
            } else {
                time = hour + ':'
            }

            if (min < 10) {
                time += '0'
            }
            time += min + ':'

            if (sec < 10) {
                time += '0'
            }
            time += sec
        }
        return time
    },

8.视频和进度条模板




9.绘制上传进度的进度条 

// 绘制进度条
function loadingCanvas(taskId) {
    var c1 = document.getElementById(`ccb-${taskId}`) // 进度条
    var ctx1 = c1.getContext('2d')
    ctx1.strokeStyle = 'rgb(123,165,236)'
    ctx1.lineWidth = 4

    var c = document.getElementById(`ccc-${taskId}`) // 进度条背景
    var ctx = c.getContext('2d')
    ctx.beginPath()
    ctx.lineWidth = 4
    ctx.strokeStyle = 'rgba(182,197,223,.5)'
    ctx.arc(23, 23, 20, 0, 2 * Math.PI)
    ctx.stroke()
    return ctx1
}
// 进度条加载中
function loadingPercent(percent, ctx1, data_taskId) {
    ctx1.beginPath() // 开始画图
    ctx1.clearRect(0, 0, 210, 210) // 清除画布
    $(`${data_taskId} #number`).text(percent.toFixed(0) + '%')
    ctx1.arc(23, 23, 20, -0.5 * Math.PI, (1.5 * Math.PI * percent) / 100)
    ctx1.stroke()
}

10.全屏播放

    function bindVideo (data_taskId) {
        $(`${data_taskId} .play`).show()
        $(`${data_taskId} video`).attr({ controls: false })
        const elvideo = $(`${data_taskId} video`)[0]

        $(`${data_taskId} .play`)
            .off('click')
            .on('click', (e) => {
                $(`${data_taskId} video`).attr({ controls: true })
                $(`${data_taskId} .play`).hide()
                $(`${data_taskId} span`).hide()

                if (isAndroid()) {
                    requestFullScreen() // 安卓视频播放不自动全屏,特殊处理
                }

                if (isMinigram()) {
                    elvideo.muted = true // 设置静音
                    $(`${data_taskId} video`).attr('autoplay', true)
                    $(`${data_taskId} video`).load()
                } else {
                    elvideo.play()
                }
            })

        // 视频全屏按钮点击事件
        elvideo.addEventListener('fullscreenchange', () => {
            var fullScreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement
            // var orientation = window.orientation

            if (fullScreenElement) {
                // 全屏时的处理逻辑
                // console.log('进入全屏')
                // console.log('全屏元素:', fullScreenElement)
                //要获取全屏横竖屏方向,您可以使用window.orientation属性。该属性返回显示屏幕方向的数值,其中0表示竖屏,90表示逆时针旋转90度,-90表示顺时针旋转90度。
                // console.log('屏幕方向:', orientation)
            } else {
                // 退出全屏时的处理逻辑
                // console.log('退出全屏')
                elvideo.pause()
                $(`${data_taskId} video`).attr({ controls: false })
                $(`${data_taskId} video`).attr('autoplay', false)
                $(`${data_taskId} .play`).show()
                $(`${data_taskId} span`).show()
            }
        })

        // 调用requestFullscreen方法实现全屏
        function requestFullScreen() {
            if (elvideo.requestFullscreen) {
                elvideo.requestFullscreen()
            } else if (elvideo.mozRequestFullScreen) {
                elvideo.mozRequestFullScreen() //FireFox
            } else if (elvideo.webkitRequestFullscreen) {
                elvideo.webkitRequestFullscreen() //Chrome等
            } else if (elvideo.msRequestFullscreen) {
                elvideo.msRequestFullscreen() //IE11
            }
        }
    
    },

11获取视频第一帧

// 获取video元素
var video = document.getElementById('video');
// 创建canvas元素
var canvas = document.createElement('canvas');
// 设置canvas的宽度和高度
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// 获取canvas的上下文
var ctx = canvas.getContext('2d');
// 将video的第一帧画到canvas上
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// 获取第一帧的图像数据
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

12强制禁用全屏按钮

在H5的video标签中,可以通过设置x5-video-player-fullscreen属性为false来禁用全屏按钮,避免出现方向冲突问题

你可能感兴趣的:(前端demo,前端,音视频)