大视频文件切片上传方法

import Vue from "vue"
import SparkMD5 from "spark-md5"
import { getToken } from '@/utils/auth' 
 
export default function() {
    // 将上传文件的方法挂载到vue的原型链上面
    Vue.prototype.uploadFile = uploadFile

    function uploadFile(file, backtopage,failback) {
        // 得到md5码
        getFileMD5(file, md5 => {
            // 存储文件的md5码
            file.md5 = md5
            console.log('file md5', md5)
            uploadChunk(this, file, 0, backtopage,failback)
        })
    }
 
    // currentChunk为上传文件块的索引
    function uploadChunk(that, file, currentChunk, backtopage,failback ) {

        var fileReader = new FileReader(),
        // 上传文件块的大小,可自定义
        chunkSize = 1024*1000,//10485760/2,       
        // 计算改文件的可分为多少块
        chunks = Math.ceil(file.size / chunkSize)

        // 文件切割后的回调,this.result为切割的文件块
        fileReader.onload = function(e) {
            // 用FormData传输文件对象
            let fd = new FormData()
            // 设置文件上传接口的需要的参数
            fd.append('fileName', file.name)
            fd.append('fileMd5', file.md5)
            fd.append('id', localStorage.getItem('paperId'));
            // fd.append('videoTime', num)
            // fd.append("userID",localStorage.getItem('user_id'))
            // fd.append("userToken", localStorage.getItem('token'))
            fd.append('fileOffset',currentChunk*chunkSize)
            fd.append('fileTotalSize', file.size)
            if(currentChunk+1==chunks){
                fd.append('isEnd', 1)
            }else{
                fd.append('isEnd', 0)
            }
            // 设置上传的当前的文件块
            fd.append('file', new Blob([this.result]))
            let xhr = new XMLHttpRequest()
            
            xhr.open('post', '/dev-api/video/videouserexam/videouploadbyid', true)
            xhr.setRequestHeader('Authorization', getToken());
            xhr.onreadystatechange = function() {
                // 上传成功
                if (xhr.readyState == 4 && xhr.status == 200) {
                    currentChunk++
                    if (currentChunk < chunks) {
                        loadNext() // 继续切割下一块文件
                    } else {
                        let response=JSON.parse(xhr.response)
                        console.log(response)
                        // console.log(response.statusCode)
                        if(response.code==200){
                            backtopage && backtopage(xhr.response)
                            // console.log('上传成功')
                        }else{
                            failback&&failback()
                            // alert('上传失败 错误码'+response.statusCode+ ' '+response.errorMsg)
                        }
                        // 文件上传成功
                    }
                    xhr = null
                    return
                }
                if (xhr.readyState == 4 && xhr.status == 500) {
                    failback&&failback()
                    // alert('上传失败')
                }
            }
            // 文件上传进度条
            xhr.upload.onprogress = function(e) {
                // 计算上传的进度
                const progress = parseInt((e.loaded + currentChunk * chunkSize) / file.size * 100)
                backtopage && backtopage(progress)
                console.log('onprogress', progress)
                // 更新ui
            }
            xhr.onerror = xhr.upload.onerror = function() {
                console.log('on error')
                // 文件上传出错
            }
            //开始发送
            xhr.send(fd)
            fd = null
        }

        //处理单片文件的上传
        function loadNext() {
            var start = currentChunk * chunkSize,
            end = Math.min(start + chunkSize, file.size)
            // 切割文件并触发fileReader.onload
            fileReader.readAsArrayBuffer(file.slice(start, end))
        }
        // 触发文件第一块上传
        loadNext()
    }
 
    // 获得文件md5
    function getFileMD5(file, callback) {
        //声明必要的变量
        var fileReader = new FileReader(),

        //文件每块分割2M,计算分割详情
        chunkSize = 10485760/2,
        chunks = Math.ceil(file.size / chunkSize),
        currentChunk = 0,

        //创建md5对象(基于SparkMD5)
        spark = new SparkMD5()

        //每块文件读取完毕之后的处理
        fileReader.onload = function(e) {
            //每块交由sparkMD5进行计算
            spark.appendBinary(e.target.result)
            currentChunk++

            //如果文件处理完成计算MD5,如果还有分片继续处理
            if (currentChunk < chunks) {
                    loadNext()
            } else {
                    callback(spark.end())
            }
        }

        //处理单片文件的上传
        function loadNext() {
            var start = currentChunk * chunkSize,
            end = start + chunkSize >= file.size ? file.size : start + chunkSize

            fileReader.readAsBinaryString(file.slice(start, end))
        }
        loadNext()
    }
 
} 

 

posted @ 2023-05-04 14:32  SukaLv  阅读(153)  评论(0)    收藏  举报