Fork me on GitHub

视频分片上传,断点续传

样式

      <div class="body-inner">
        <div class="input_contant" style="display: block;margin-bottom: 10px;">
          <label id="realBtn" class="btn btn-info">
            <input name="file" id="videos" type="file" accept="video/*" @change="selectOtherVideo(this)"
              style="left:-9999px;position:absolute;">
            <span style="width: 100%;display: inline-block;"><i class="el-icon-video-camera"></i> 视频上传( ≤1GB )</span>
          </label>
        </div>
        <div class="upload-content-span">
          // 进度条
          <div id="upload-progress">
            <el-progress :percentage="percent" color="#67c23a" id='progress'></el-progress>
          </div>
          //  上传成功后显示内容
          <div id="preview_course_video_text"></div>
          <div id="upload-video-status">上传成功</div>
          <div id="upload-progress-text">
            上传速度取决于您的网速,请耐心等待...
            <!--<span class="upload-progress-cancel">取消上传</span> -->
          </div>
        </div>
      </div>

js上传

selectOtherVideo() {
      var c = document.getElementById('upload-video-status')
      var d = document.getElementById('upload-progress-text')
      var e = document.getElementById('upload-progress')
      var f = document.getElementById('preview_course_video_text')

      c.style.display = 'none'
      d.style.display = 'none'
      f.style.display = 'none'
      this.beginUploadVideo()
    },
    // 分片上传
    beginUploadVideo() {
      this.submFlag = true;
      var fileName = ""
      var videoUrl = ""
      if (!document.all) {  // IE11,Chrome,FF
        var files = document.getElementById('videos').files;
        // console.log(files, 'files');
        if (files.length == 0) {
          alert("请先上传视频!")
          return false;
        } else if (files[0].size > (1024 * 1024 * 1024)) {
          alert('视频大小不能大于1GB')
          return false;
        }
        fileName = files[0].name
        videoUrl = files[0]
      } else {
        // IE10
        if (!isIE9()) {
          if (!FileReader.prototype.readAsBinaryString) {
            var files = document.getElementById('videos').files[0];
            fileName = files.name
            videoUrl = files
            if (files.size > (1024 * 1024 * 1024)) {
              alert('视频大小不能大于1GB')
              return false;
            }
          }
        }
      }
      document.getElementById('videos').disabled = true
      document.getElementById('upload-progress').style.display = 'block'
      var blockSize = 8 * 1024 * 1024;//每块的大小
      // console.log(videoUrl, blockSize)
      // console.log(Math.ceil(videoUrl.size / blockSize))
      var count = Math.ceil(videoUrl.size / blockSize) // 总块数
      this.readChunk(videoUrl, count, blockSize)
    },
    getChunkInfo(file, currentChunk, chunkSize) {
      let start = currentChunk * chunkSize
      let end = Math.min(file.size, start + chunkSize)
      let chunk = file.slice(start, end)
      // console.log(start, end, chunk)
      return { start, end, chunk }
    },
    // 针对每个文件进行chunk处理
    readChunk(file, chunkCount, chunkSize) {
      // 针对单个文件进行chunk上传
      // console.log(file, chunkCount, chunkSize)
      let i = 0
      let uuid = ''
      let offset = 0
      let complete = false
      this.uploadChunk({ file, uuid, offset, complete, chunkCount, currentChunk: i, chunkSize })
      // }
    },
    uploadChunk(chunkInfo) {
      // console.log(chunkInfo)
      var data = {
        uuid: chunkInfo.uuid,
        offset: chunkInfo.offset,
        complete: chunkInfo.chunkCount == 1 ? true : chunkInfo.complete
      }
      // console.log("总片数" + chunkInfo.chunkCount)
      // console.log("第" + chunkInfo.currentChunk + '分片')
      var { chunk, start, end } = this.getChunkInfo(chunkInfo.file, chunkInfo.currentChunk, chunkInfo.chunkSize)
      var fileData = new window.File([chunkInfo.file.slice(start, end)], chunkInfo.file.name, { type: chunkInfo.file.type })
      // console.log(fileData, start, end, '截取。。。。。。。。。。。。。。。。。')
      this.percent = Math.floor((chunkInfo.currentChunk / chunkInfo.chunkCount) * 100)
      document.getElementById('progress').style.width = '190px'
      getFragmentationUploadUrl(data).then(res => {
        if (res.code == 200) {
          sessionStorage.setItem('uuid', res.data.uuid)
          var formData = new FormData();//初始化一个FormData对象
          formData.append("file", fileData);//将 部分文件 塞入FormData
          document.getElementById('upload-progress-text').style.display = 'block'
          document.getElementById('upload-progress').style.display = 'block'
          axios.request({
            url: res.data.url, /*设置post提交到的页面*/
            method: "post", /*设置表单以post方法提交*/
            data: formData,
            headers: {
              token: getToken()
            },
            // responseType: "blob",
            //使用XMLHttpRequest.upload监听上传过程,注册progress事件,打印回调函数中的event事件
            onDownloadProgress(progress) {
              // console.log(progress, '++++++++++++++++++++++++++')
              // var progressRate = (chunkInfo.currentChunk / chunkInfo.chunkCount) * 100
              document.getElementById('progress').style.width = '190px'
              this.percent = Math.floor((progress.loaded / progress.total) / chunkInfo.chunkCount * 100 + (chunkInfo.currentChunk / chunkInfo.chunkCount) * 100)
            }
          }).then(res => {
            // console.log(res);
            let data = res.data
            if (data.code == 1) {
              // console.log(101010);
              let list = chunkInfo
              list.currentChunk += 1
              // console.log("第" + list.currentChunk + '张上传成功+++++++++++++')
              if (list.currentChunk == list.chunkCount) {
                this.percent = 100
                document.getElementById('progress').style.width = '100%'
                // console.log('停+++++++++++++')
                document.getElementById('videos').disabled = false
                document.getElementById("preview_course_video_text").innerHTML = '视频ID:' + data.resultObject.archiveId
                document.getElementById("preview_course_video_text").style.display = 'block'
                document.getElementById('upload-progress-text').style.display = 'none'
                document.getElementById('upload-video-status').style.color = '#1ea725'
                document.getElementById('upload-video-status').style.display = 'none'
                this.$message({ type: "success", message: "上传成功!" });
                this.ruleForm.archiveId = data.resultObject.archiveId;
                this.ruleForm.duration = data.resultObject.duration;
                this.ruleForm.fileSize = parseInt(data.resultObject.fileSize);
                this.submFlag = false;
                document.getElementById('videos').value = ''
                return false
              }
             // created 定义stop:0 
             // 取消时  stop=1  中断上传
              if (this.stop == 1) {
                this.$message({ type: "warning", message: "已取消上传!" })
                document.getElementById('videos').value = ''
                document.getElementById('videos').disabled = false
                return false
              }
              // console.log("不停--------------")
              list.offset = data.resultObject.offset
              list.uuid = sessionStorage.getItem('uuid')
              if (list.currentChunk == list.chunkCount - 1) {
                list.complete = true
              } else {
                list.complete = false
              }
              this.uploadChunk(list)
            } else {
              document.getElementById('videos').disabled = false
              document.getElementById('videos').value = ''
              document.getElementById('upload-video-status').innerHTML = "上传失败"
              document.getElementById('upload-video-status').style.color = '#ff0000'
              document.getElementById('upload-video-status').style.display = 'block'
              document.getElementById('upload-progress-text').style.display = 'none'
              this.submFlag = false;
              let list = chunkInfo
              list.offset = start
              // console.log(list, '继续上传')
              sessionStorage.setItem('chunkList', JSON.stringify(list))
            }
          }).catch(error => {
            document.getElementById('videos').disabled = false
            document.getElementById('videos').value = ''
            document.getElementById('upload-progress-text').style.display = 'none'
            document.getElementById('upload-video-status').innerHTML = "上传失败"
            document.getElementById('upload-video-status').style.color = '#ff0000'
            document.getElementById('upload-video-status').style.display = 'block'
            this.submFlag = false;
            let list = chunkInfo
            list.offset = start
            // console.log(list, '继续上传')
            sessionStorage.setItem('chunkList', JSON.stringify(list))
          })
        } else {
          console.log(res.msg);
        }
      }).catch(err => {
        console.log(err);
      })
    },
 //  继续上传失败的部分
   goOnUploadVideo() {
     var files = document.getElementById('videos').files[0];
     var list = JSON.parse(sessionStorage.getItem('chunkList'))
      console.log(files, list, '继续');
      list.uuid = sessionStorage.getItem('uuid')
      list.file = files
       this.uploadChunk(list)
     },

jQuery上传

// 分片上传
// 开始上传视频
function beginUploadVideo() {
    var fileName = ""
    var videoUrl = ""
    if (!document.all) {  // IE11,Chrome,FF
        var files = document.getElementById('videos').files;
        if (files.length == 0) {
            alert("请先上传视频!")
            return false;
        } else if (files[0].size > (1024 * 1024 * 1024)) {
            alert('视频大小不能大于1GB')
            return false;
        }
        fileName = files[0].name
        videoUrl = files[0]
    } else {
        // IE10
        if (!isIE9()) {
            if (!FileReader.prototype.readAsBinaryString) {
                var files = document.getElementById('videos').files[0];
                fileName = files.name
                videoUrl = files
                if (files.size > (1024 * 1024 * 1024)) {
                    alert('视频大小不能大于1GB')
                    return false;
                }
            }
        }
    }
    var blockSize = 8 * 1024 * 1024;//每块的大小
    // console.log(videoUrl, blockSize)
    // console.log(Math.ceil(videoUrl.size / blockSize))
    var count = Math.ceil(videoUrl.size / blockSize) // 总块数
    readChunk(videoUrl, count, blockSize)
}
function getChunkInfo(file, currentChunk, chunkSize) {
    // console.log('2222222222--------------')
    let start = currentChunk * chunkSize
    let end = Math.min(file.size, start + chunkSize)
    let chunk = file.slice(start, end)
    // console.log(start, end, chunk)
    return { start, end, chunk }
}
// 针对每个文件进行chunk处理
function readChunk(file, chunkCount, chunkSize) {
    // console.log('11111111--------------')
    // 针对单个文件进行chunk上传
    // console.log(file, chunkCount, chunkSize)
    let i = 0
    let uuid = ''
    let offset = 0
    let complete = false
    uploadChunk({ file, uuid, offset, complete, chunkCount, currentChunk: i, chunkSize })
    // }
}

// 获取建学唐上传视频地址
function uploadChunk(chunkInfo) {
    // console.log('3333333--------------')
    // console.log(chunkInfo)
    var data = {
        uuid: chunkInfo.uuid,
        offset: chunkInfo.offset,
        complete: chunkInfo.chunkCount == 1 ? true : chunkInfo.complete
    }
    // console.log("总片数" + chunkInfo.chunkCount)
    // console.log("第" + chunkInfo.currentChunk + '分片')
    var { chunk, start, end } = getChunkInfo(chunkInfo.file, chunkInfo.currentChunk, chunkInfo.chunkSize)
    var fileData = new window.File([chunkInfo.file.slice(start, end)], chunkInfo.file.name, { type: chunkInfo.file.type })
    // console.log(fileData, start, end, '截取。。。。。。。。。。。。。。。。。')
    var percent = (chunkInfo.currentChunk / chunkInfo.chunkCount) * 100
    $('.upload-progress-inner').css('width', percent + '%');
    $.ajax({
        // 接口,
        url: 接口,
        type: "POST",
        cache: false,
        data: JSON.stringify(data),
        headers: {
            token: sessionStorage.getItem("HXKToken")
        },
        processData: false,
        contentType: "application/json",
        dataType: "json",
        success: function (res) {
            // console.log("分片上传返回信息:")
            // console.log(res.data.url, res.data.uuid, chunkInfo.offset)
            if (res.code == 200) {
                // sessionStorage.setItem('VideoUploadUrl', res.data.url)
                sessionStorage.setItem('uuid', res.data.uuid)
                $("#submitVideoButton").removeAttr("disabled")
                // var apiUrl = sessionStorage.getItem('VideoUploadUrl')
                // var uuid = sessionStorage.getItem('uuid')
                var formData = new FormData();//初始化一个FormData对象
                formData.append("file", fileData);//将 部分文件 塞入FormData
                // formData.append("uuid", res.data.uuid);//保存文件名字
                // formData.append("offset", chunkInfo.offset);//保存文件名字
                // formData.append("complete", chunkInfo.complete);//保存文件名字
                // console.log(formData)
                $(".upload-video-status").text("视频上传中...").css({
                    "display": "block",
                    "color": "#069af0",
                })
                $(".upload-progress-text").css({ "display": "block" });
                $(".upload-progress").css({ "display": "block" });
                $("#submitVideoButton").attr("disabled", 'disabled'); // 禁掉提交按钮
                $.ajax({
                    url: res.data.url, /*设置post提交到的页面*/
                    type: "post", /*设置表单以post方法提交*/
                    cache: false,
                    data: formData,
                    dataType: "json", /*设置返回值类型为文本*/
                    headers: {
                        token: sessionStorage.getItem("HXKToken")
                    },
                    processData: false,
                    contentType: false,  // 告诉jQuery不要去设置Content-Type请求头
                    xhr: function () { // 增加 progress 事件绑定
                        $("#videos").attr("disabled", "disabled")   // 禁掉选择视频按钮
                        $(".upload-progress-inner").css("background", "#07c160"); // 把上传条调转为绿色
                        var xhr = new XMLHttpRequest();
                        //使用XMLHttpRequest.upload监听上传过程,注册progress事件,打印回调函数中的event事件
                        xhr.upload.addEventListener('progress', function (e) {
                            // console.log(e, '++++++++++++++++++++++++++')
                            // var progressRate = (chunkInfo.currentChunk / chunkInfo.chunkCount) * 100
                            var progressRate = (e.loaded / e.total) / chunkInfo.chunkCount * 100 + (chunkInfo.currentChunk / chunkInfo.chunkCount) * 100
                            // var realProgress = progressRate == 100 ? 98 : progressRate;
                            //通过设置进度条的宽度达到效果
                            $('.upload-progress-inner').css('width', progressRate + '%');
                        })
                        return xhr;
                    },
                    success: function (data) {
                        if (data.code == 1) {
                            // console.log(data, '上传成功返回数据--------------------')
                            // $('.upload-progress-inner').css('width', '100%');
                            $("#video_archiveId").text(data.resultObject.archiveId)
                            $("#video_fileSize").text(data.resultObject.fileSize)
                            $("#video_duration").text(data.resultObject.duration)
                            let list = chunkInfo
                            list.currentChunk += 1
                            // console.log(list.currentChunk, list.chunkCount)
                            // console.log("第" + list.currentChunk + '张上传成功+++++++++++++')
                            if (list.currentChunk == list.chunkCount) {
                                // console.log('停+++++++++++++')
                                $("#videos").removeAttr("disabled")
                                $("#preview_course_video_text").text("视频ID:" + data.resultObject.archiveId)
                                $(".upload-progress-text").css({ "display": "none" });
                                $(".upload-video-status").text("上传成功").css({
                                    "display": "block",
                                    "color": "#1ea725",
                                });
                                $("#submitVideoButton").val("已上传")
                                $('#submitVideoButton').css({ 'display': 'inline-block' })
                                $('#goOnVideoButton').css({ 'display': 'none' })
                                $("#submitVideoButton").attr("disabled", "disabled")
                                return false
                            }
                            // console.log("不停--------------")
                            list.offset = data.resultObject.offset
                            list.uuid = sessionStorage.getItem('uuid')
                            // console.log(data.resultObject.offset, list)
                            if (list.currentChunk == list.chunkCount - 1) {
                                list.complete = true
                            } else {
                                list.complete = false
                            }
                            // console.log($("#submitVideoButton").val())
                            uploadChunk(list)
                        } else {
                            $(".upload-progress-inner").css("background", "#ff0000") // 把上传条调转为红色
                            $('#submitVideoButton').css({ 'display': 'none' })
                            $('#goOnVideoButton').css({ 'display': 'inline-block' })
                            $("#goOnVideoButton").removeAttr("disabled")
                            $(".upload-video-status").text("上传失败").css({
                                "display": "block",
                                "color": "#ff0000",
                            });
                            // alert(data.msg)
                            // console.log($("#submitVideoButton").val())
                            let list = chunkInfo
                            list.offset = start
                            // list.uuid = sessionStorage.getItem('uuid')
                            // console.log(list, '继续上传')
                            sessionStorage.setItem('chunkList', JSON.stringify(list))
                        }
                    },
                    error: function (error) {
                        $("#videos").removeAttr("disabled")
                        $('#submitVideoButton').removeAttr("disabled");
                        $(".upload-progress-inner").css({ "background": "#ff0000" }); // 把上传条调转为红色
                        $(".upload-progress-text").css({ "display": "none" });
                        $('#submitVideoButton').css({ 'display': 'none' })
                        $('#goOnVideoButton').css({ 'display': 'inline-block' })
                        $("#goOnVideoButton").removeAttr("disabled")
                        $(".upload-video-status").text("上传失败").css({
                            "display": "block",
                            "color": "#ff0000",
                        });
                        // alert(error.responseJSON.msg);
                        // console.log($("#submitVideoButton").val())
                        let list = chunkInfo
                        list.offset = start
                        // list.uuid = sessionStorage.getItem('uuid')
                        // console.log(list, '继续上传')
                        sessionStorage.setItem('chunkList', JSON.stringify(list))
                    },
                });
            } else {
                $("#submitVideoButton").removeAttr("disabled")
                alert(res.msg);
            }
        },
        error: function (err) {
            $("#submitVideoButton").removeAttr("disabled")
            alert("获取上传视频地址失败!")
        }
    })
}

function goOnUploadVideo() {
    var files = document.getElementById('videos').files[0];
    var list = JSON.parse(sessionStorage.getItem('chunkList'))
    list.uuid = sessionStorage.getItem('uuid')
    list.file = files
    uploadChunk(list)
    $("#goOnVideoButton").attr("disabled", "disabled")
}

 

posted @ 2020-09-21 11:22  ssh__F  阅读(447)  评论(0编辑  收藏  举报