視訊分片上傳,斷點續傳
阿新 • • 發佈:2020-09-21
樣式
<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") }