| | |
| | | |
| | | <template> |
| | | <div class="greetings" v-loading="loading"> |
| | | <el-upload accept=".mp4, .mp3, .xls, .xlsx, .doc, .docx, .ppt, .pptx, .pdf" :on-change="handleFileChange" :on-preview="view" :auto-upload="false" ref="uploadfileComponent" :limit="1" :on-exceed="handleExceed" v-model:file-list="fileList"> |
| | | <template #trigger> |
| | | <el-button type="primary">选择文件</el-button> |
| | | </template> |
| | | <el-button :disabled="uploadDisabled" style="margin-left: 10px" type="success" @click="handlerUpload">上传</el-button> |
| | | <el-button class="ml-3" type="success" @click="resetData" >重置</el-button> |
| | | <template #tip> |
| | | <br /><br /> |
| | | <span>上传进度:{{ fakeUploadPercentage }}%</span> |
| | | <el-progress :text-inside="true" :stroke-width="26" :percentage="fakeUploadPercentage" /> |
| | | <div class="el-upload__tip text-red">限制一个文件, 新文件将会覆盖原文件</div> |
| | | </template> |
| | | </el-upload> |
| | | <br> |
| | | <div v-if="container.showVideo" style="width: 300px;height: 200px"> |
| | | <video ref="videoPlayer" class="video-js" style="margin: auto auto"></video> |
| | | </div> |
| | | <!-- <div class="greetings" v-loading="loading">--> |
| | | <!-- <el-upload accept=".mp4, .mp3, .xls, .xlsx, .doc, .docx, .ppt, .pptx, .pdf" :on-change="handleFileChange" :on-preview="view" :auto-upload="false" ref="uploadfileComponent" :limit="1" :on-exceed="handleExceed" v-model:file-list="fileList">--> |
| | | <!-- <template #trigger>--> |
| | | <!-- <el-button type="primary">选择文件</el-button>--> |
| | | <!-- </template>--> |
| | | <!-- <el-button :disabled="uploadDisabled" style="margin-left: 10px" type="success" @click="handlerUpload">上传</el-button>--> |
| | | <!-- <el-button class="ml-3" type="success" @click="resetData" >重置</el-button>--> |
| | | <!-- <template #tip>--> |
| | | <!-- <br /><br />--> |
| | | <!-- <span>上传进度:{{ fakeUploadPercentage }}%</span>--> |
| | | <!-- <el-progress :text-inside="true" :stroke-width="26" :percentage="fakeUploadPercentage" />--> |
| | | <!-- <div class="el-upload__tip text-red">限制一个文件, 新文件将会覆盖原文件</div>--> |
| | | <!-- </template>--> |
| | | <!-- </el-upload>--> |
| | | <!-- <br>--> |
| | | <!-- <div v-if="container.showVideo" style="width: 300px;height: 200px">--> |
| | | <!-- <video ref="videoPlayer" class="video-js" style="margin: auto auto"></video>--> |
| | | <!-- </div>--> |
| | | |
| | | </div> |
| | | <!-- </div>--> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessage } from "element-plus"; |
| | | import videojs from "video.js" |
| | | import { computed, nextTick, onMounted, onUnmounted,ref,reactive,watch } from "vue"; |
| | | import SparkMD5 from "spark-md5"; |
| | | import {uploadFileRequest,mergeFileRequest} from "@/api/onlineEducation/upload" |
| | | import pLimit from 'p-limit' |
| | | |
| | | const videoPlayer = ref(null) |
| | | const myPlayer = ref(null) |
| | | const uploadDisabled=ref(false) |
| | | const chunkSize = ref(10 * 1024 * 1024) // 切片大小 |
| | | const uploadedCount=ref(0) //已上传的分配个数 |
| | | const fileChunkList=ref([]) |
| | | const fileList=ref([]) |
| | | const uploadfileComponent=ref(null) |
| | | const emit = defineEmits(["getFile"]); |
| | | const loading = ref(false) |
| | | const props = defineProps({ |
| | | responseType: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }) |
| | | const container=reactive({ |
| | | file:{ |
| | | name:'', |
| | | percentage:0, |
| | | status:1, |
| | | size:0, |
| | | url:'', |
| | | raw:null, |
| | | uid:0 |
| | | }, |
| | | fileMd5:'', |
| | | worker:null, |
| | | showVideo:false |
| | | }) |
| | | // 生成文件hash的进度 |
| | | const hashPercentage = ref(0) |
| | | // 显示在页面上的文件上传进度 |
| | | const fakeUploadPercentage = ref(0) |
| | | const type = ref(); |
| | | onMounted(() => { |
| | | type.value = props.responseType |
| | | // getVideo(props.responseType) |
| | | |
| | | }) |
| | | const resourcePath = ref(); |
| | | const getVideo = (value) => { |
| | | type.value = value; |
| | | if(value == 1){ |
| | | // container.showVideo = true |
| | | nextTick(() => { |
| | | console.log("111111",videoPlayer.value) |
| | | myPlayer.value = videojs(videoPlayer.value, { |
| | | poster: "",//视频封面 |
| | | controls: true,//视频控件 |
| | | autoplay:true,//自动播放 |
| | | sources: [ |
| | | { |
| | | src: resourcePath.value ? import.meta.env.VITE_APP_RESOURCE_API + resourcePath.value : '', |
| | | // src:'', |
| | | type: 'application/x-mpegURL', |
| | | } |
| | | ], |
| | | controlBar: { |
| | | remainingTimeDisplay: { |
| | | displayNegative: false |
| | | } |
| | | }, |
| | | playbackRates: [0.5, 1, 1.5, 2]//设置播放速度 |
| | | }, onPlayerReady) |
| | | }); |
| | | } |
| | | } |
| | | // watch(() => props.responseType, value => getVideo(value)) |
| | | onUnmounted(() => { |
| | | if (myPlayer.value) { |
| | | myPlayer.value.dispose() |
| | | } |
| | | }) |
| | | |
| | | const dispose = () => { |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // resourcePath.value = '' |
| | | // } |
| | | container.showVideo = false; |
| | | resourcePath.value = '' |
| | | hashPercentage.value=0 |
| | | uploadPercentage.value=0 |
| | | fakeUploadPercentage.value=0 |
| | | uploadedCount.value=0 |
| | | fileChunkList.value=[] |
| | | fileList.value=[] |
| | | } |
| | | |
| | | const changeType = (val) => { |
| | | type.value = val |
| | | dispose() |
| | | if(val == 1){ |
| | | container.showVideo = true |
| | | nextTick(() => { |
| | | getVideo(val) |
| | | }) |
| | | } |
| | | } |
| | | const openValue = ref(); |
| | | const open = (val) => { |
| | | console.log("val",val) |
| | | openValue.value = val |
| | | fakeUploadPercentage.value = 100 |
| | | if(val.resourceType == 1){ |
| | | container.showVideo = true |
| | | resourcePath.value = val.resourcePath; |
| | | getVideo(val.resourceType) |
| | | }else { |
| | | container.showVideo = false |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | fileList.value.push({ |
| | | path: val.resourcePath, |
| | | name: val.originName |
| | | }) |
| | | } |
| | | } |
| | | const view = (file) => { |
| | | console.log('vlco',file) |
| | | // console.log("点击文件=>", file); |
| | | const url = import.meta.env.VITE_APP_RESOURCE_API + file.path; |
| | | const link = document.createElement("a"); |
| | | link.href = url; |
| | | link.download = file.name; |
| | | // link.target = "_blank"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | } |
| | | // video初始化完成的回调函数 |
| | | const onPlayerReady = () => { |
| | | myPlayer.value.log("play.....") |
| | | bindVideoEvents() |
| | | } |
| | | // 绑定事件 |
| | | const bindVideoEvents = () => { |
| | | if (!myPlayer.value) return |
| | | myPlayer.value.on('play', onPlay) |
| | | myPlayer.value.on('pause', onPause) |
| | | myPlayer.value.on('ended', onEnded) |
| | | myPlayer.value.on('timeupdate', onTimeupdate) |
| | | myPlayer.value.on('loadedmetadata', onLoadedmetadata) |
| | | myPlayer.value.on('fullscreenchange', onFullscreenchange) |
| | | myPlayer.value.on('error', err => { |
| | | console.log('视频加载发生错误', err) |
| | | }) |
| | | } |
| | | |
| | | const onPlay = () => { |
| | | console.log('播放视频') |
| | | } |
| | | const onPause = () => { |
| | | console.log('暂停播放') |
| | | } |
| | | const onEnded = () => {} |
| | | const onTimeupdate = () => { |
| | | console.log('播放位置已更改时,播放时间更新') |
| | | } |
| | | // 全屏切换 |
| | | const onFullscreenchange = () => { |
| | | console.log('全屏状态改变') |
| | | } |
| | | // 元数据加载完成 |
| | | const onLoadedmetadata = () => { |
| | | console.log('元数据加载完成') |
| | | |
| | | } |
| | | |
| | | |
| | | //计算文件上传的进度 |
| | | const uploadPercentage= computed({ |
| | | get(){ |
| | | if(!container.file||!fileChunkList.value.length){ |
| | | return 0 |
| | | } |
| | | const loaded=fileChunkList.value.map(item => item.size * item.percentage).reduce((acc,cur) => { |
| | | return acc+cur |
| | | }) |
| | | console.log('loaded',uploadedCount.value,loaded) |
| | | return parseInt((loaded/container.file.size).toFixed(2)) |
| | | }, |
| | | set(value){ |
| | | return value |
| | | } |
| | | }) |
| | | |
| | | // watch uploadPercentage,得到fakeUploadPercentage |
| | | watch(uploadPercentage, (newValue) => { |
| | | if (newValue >= fakeUploadPercentage.value) { |
| | | fakeUploadPercentage.value = newValue |
| | | } |
| | | }) |
| | | |
| | | const resetData = () => { |
| | | container.showVideo = false |
| | | resourcePath.value = '' |
| | | hashPercentage.value=0 |
| | | uploadPercentage.value=0 |
| | | fakeUploadPercentage.value=0 |
| | | uploadedCount.value=0 |
| | | fileChunkList.value=[] |
| | | fileList.value=[] |
| | | if(container.worker){ |
| | | container.worker.onmessage=null |
| | | } |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | const file = { |
| | | resourceSize: null, |
| | | md5: '', |
| | | resourcePath: '', |
| | | mediaType: '', |
| | | docPage: 0, |
| | | resourceLength: '', |
| | | originName:'' |
| | | } |
| | | emit("getFile",file) |
| | | } |
| | | |
| | | //选择了文件 |
| | | const handleFileChange=(uploadFile,uploadFiles) =>{ |
| | | // resetData() |
| | | if(!uploadFile){ |
| | | return |
| | | } |
| | | container.file=uploadFile |
| | | fileList.value=uploadFiles |
| | | } |
| | | |
| | | const handleExceed= (files) => { |
| | | uploadfileComponent.value.clearFiles() |
| | | nextTick(() => { |
| | | uploadfileComponent.value.handleStart(files[0]) |
| | | }) |
| | | } |
| | | |
| | | //上传 |
| | | const handlerUpload= async() => { |
| | | |
| | | if(type.value == null){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请先选择资源类型' |
| | | }); |
| | | return false |
| | | } |
| | | |
| | | if(!container.file.raw){ |
| | | return |
| | | } |
| | | if(container.file.raw.size > 1024 * 1024 * 1000){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '文件大小不能超过1G' |
| | | }); |
| | | return false |
| | | } |
| | | |
| | | const filetype = container.file.raw.name.split(".").pop(); |
| | | const extension = (filetype === "mp4" || filetype ==="mp3" || filetype ==="xls" || filetype === "xlsx" || filetype ==="doc" || filetype ==="docx" || filetype === "ppt" || filetype ==="pptx" || filetype ==="pdf"); |
| | | if (!extension ) { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '暂不支持该格式上传' |
| | | }); |
| | | return false; |
| | | } |
| | | if((type.value == 1 && filetype != 'mp4') || (type.value == 2 && filetype != 'mp3')){ |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传所选资源类型的文件' |
| | | }); |
| | | return false; |
| | | } |
| | | if(type.value == 3){ |
| | | if( filetype == 'xls' || filetype == 'xlsx' || filetype == 'doc'|| filetype == 'docx'|| filetype == 'ppt'|| filetype == 'pptx'|| filetype == 'pdf' ){ |
| | | |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: '请上传所选资源类型的文件' |
| | | }); |
| | | return false; |
| | | } |
| | | } |
| | | loading.value = true |
| | | //文件分片 |
| | | const chunkList=createFileChunk(container.file.raw) |
| | | console.log('文件分了多少片:',chunkList.length) |
| | | //通过webworker计算出文件hash |
| | | container.fileMd5=await calculateMd5(chunkList) |
| | | console.log('文件hash1:',container.fileMd5) |
| | | // container.fileMd5=await getFileMD5(container.file.raw) |
| | | // console.log('文件hash2:',container.hash) |
| | | |
| | | fileChunkList.value=[] |
| | | fileChunkList.value=chunkList.map(({file},index) => ({ |
| | | fileMd5:container.fileMd5, |
| | | index, |
| | | chunkName: `${container.fileMd5}-${index}`, |
| | | chunk:file, |
| | | size:file.size, |
| | | // 如果已上传切片数组uploadedList中包含这个切片,则证明这个切片之前已经上传成功了,进度设为100。 |
| | | percentage:0 |
| | | })) |
| | | |
| | | uploadChunks(fileChunkList) |
| | | |
| | | } |
| | | |
| | | //文件分片 |
| | | const createFileChunk = (file,size=chunkSize.value) => { |
| | | const chunkList=[] |
| | | let cur=0 |
| | | while(cur<file.size){ |
| | | chunkList.push({ |
| | | file:file.slice(cur,cur+size), |
| | | }) |
| | | cur+=size |
| | | } |
| | | return chunkList |
| | | } |
| | | |
| | | //计算文件md5 方法1 |
| | | const calculateMd5 = (chunkList) => { |
| | | return new Promise((resolve) => { |
| | | container.worker=new Worker('/hash.js') |
| | | container.worker.postMessage({fileChunkList:chunkList}) |
| | | container.worker.onmessage= (e) => { |
| | | const {percentage,hash} = e.data |
| | | hashPercentage.value=percentage.toFixed(2) |
| | | if(hash){ |
| | | resolve(hash) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | //计算文件md5 方法2 |
| | | const getFileMD5 = (file) => { |
| | | return new Promise((resolve, reject) => { |
| | | const spark = new SparkMD5.ArrayBuffer() |
| | | const fileReader = new FileReader() |
| | | fileReader.onload = (e) => { |
| | | spark.append(e.target?.result) |
| | | resolve(spark.end()) |
| | | } |
| | | fileReader.onerror = () => { |
| | | reject('') |
| | | } |
| | | fileReader.readAsArrayBuffer(file) |
| | | }) |
| | | } |
| | | |
| | | //计算上传进度 |
| | | const createProgressHandler = (item) => { |
| | | console.log('createProgresshandler -> item', item); |
| | | return (p) => { |
| | | if(item.percentage>=100){ |
| | | item.percentage = 100 |
| | | }else{ |
| | | item.percentage=parseInt(String((p.loaded/p.total)*100)) |
| | | } |
| | | // 确保进度百分比不会超过100% |
| | | if (item.percentage > 100) item.percentage = 100 |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | //上传切片 |
| | | const uploadChunks= async(uploadedList) => { |
| | | const limit = pLimit(10); // 控制并发数为10 |
| | | const requestList=uploadedList.value.map(({chunk,chunkName,index,fileMd5}) => { |
| | | const formdata=new FormData() |
| | | formdata.append('file',chunk) |
| | | formdata.append('chunkName',chunkName) |
| | | formdata.append('fileName',container.file.name) |
| | | formdata.append('fileMd5',fileMd5) |
| | | formdata.append('index',index) |
| | | return {formdata,index} |
| | | }).map(async ({formdata,index}) => { |
| | | return limit(() => doUploadChunk({data:formdata,onUploadProgress:createProgressHandler(fileChunkList.value[index])})) |
| | | }) |
| | | await Promise.all(requestList) |
| | | console.log("数组:",fileChunkList) |
| | | if(uploadedCount.value>=fileChunkList.value.length){ |
| | | mergeRequest() |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | const doUploadChunk = ({data,onUploadProgress}) => { |
| | | return new Promise((resolve) => { |
| | | uploadFileRequest(data,onUploadProgress).then((result) => { |
| | | let resData=result.data |
| | | if(result&&result.code==200){ |
| | | uploadedCount.value=uploadedCount.value+1 |
| | | fileChunkList.value[data.get('index')].percentage=100 //手动更新进度 |
| | | console.log(uploadedCount.value,'result--------------') |
| | | } |
| | | resolve('done') |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const mergeRequest = async() => { |
| | | if(container.file.name.lastIndexOf(".") === -1){ |
| | | ElMessage.warning("请输入文件后缀名") |
| | | return |
| | | } |
| | | let data=await mergeFileRequest({fileMd5:container.fileMd5,fileName:container.file.name}) |
| | | console.log(data,"mege------------222") |
| | | if(data && data.code==200){ |
| | | const filetype = data.data.originName.split(".").pop(); |
| | | if(filetype == 'mp4' || filetype == 'MP4'){ |
| | | container.showVideo = true |
| | | await nextTick(() => { |
| | | |
| | | console.log("myPlayer.value",myPlayer.value) |
| | | myPlayer.value.src( |
| | | { |
| | | src: import.meta.env.VITE_APP_RESOURCE_API +data.data.path, |
| | | type: 'application/x-mpegURL', |
| | | }) |
| | | // myPlayer.value.load() |
| | | myPlayer.value.play().catch((error) => { |
| | | console.error('Error playing video:', error); |
| | | }); |
| | | }) |
| | | // myPlayer.value.pause() |
| | | //myPlayer.value.reset() |
| | | } |
| | | const file = { |
| | | resourceSize: data.data.size, |
| | | md5: data.data.md5, |
| | | resourcePath: data.data.path, |
| | | mediaType: filetype, |
| | | docPage: data.data.docPage, |
| | | resourceLength: data.data.resourceLength, |
| | | originName: data.data.originName |
| | | } |
| | | emit("getFile",file) |
| | | |
| | | |
| | | loading.value = false |
| | | ElMessage.success("上传成功") |
| | | }else{ |
| | | ElMessage.success("合并数据失败") |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | dispose, |
| | | changeType, |
| | | open |
| | | }); |
| | | // import { ElMessage } from "element-plus"; |
| | | // import videojs from "video.js" |
| | | // import { computed, nextTick, onMounted, onUnmounted,ref,reactive,watch } from "vue"; |
| | | // import SparkMD5 from "spark-md5"; |
| | | // import {uploadFileRequest,mergeFileRequest} from "@/api/onlineEducation/upload" |
| | | // import pLimit from 'p-limit' |
| | | // |
| | | // const videoPlayer = ref(null) |
| | | // const myPlayer = ref(null) |
| | | // const uploadDisabled=ref(false) |
| | | // const chunkSize = ref(10 * 1024 * 1024) // 切片大小 |
| | | // const uploadedCount=ref(0) //已上传的分配个数 |
| | | // const fileChunkList=ref([]) |
| | | // const fileList=ref([]) |
| | | // const uploadfileComponent=ref(null) |
| | | // const emit = defineEmits(["getFile"]); |
| | | // const loading = ref(false) |
| | | // const props = defineProps({ |
| | | // responseType: { |
| | | // type: Number, |
| | | // default: 0 |
| | | // } |
| | | // }) |
| | | // const container=reactive({ |
| | | // file:{ |
| | | // name:'', |
| | | // percentage:0, |
| | | // status:1, |
| | | // size:0, |
| | | // url:'', |
| | | // raw:null, |
| | | // uid:0 |
| | | // }, |
| | | // fileMd5:'', |
| | | // worker:null, |
| | | // showVideo:false |
| | | // }) |
| | | // // 生成文件hash的进度 |
| | | // const hashPercentage = ref(0) |
| | | // // 显示在页面上的文件上传进度 |
| | | // const fakeUploadPercentage = ref(0) |
| | | // const type = ref(); |
| | | // onMounted(() => { |
| | | // type.value = props.responseType |
| | | // // getVideo(props.responseType) |
| | | // |
| | | // }) |
| | | // const resourcePath = ref(); |
| | | // const getVideo = (value) => { |
| | | // type.value = value; |
| | | // if(value == 1){ |
| | | // // container.showVideo = true |
| | | // nextTick(() => { |
| | | // console.log("111111",videoPlayer.value) |
| | | // myPlayer.value = videojs(videoPlayer.value, { |
| | | // poster: "",//视频封面 |
| | | // controls: true,//视频控件 |
| | | // autoplay:true,//自动播放 |
| | | // sources: [ |
| | | // { |
| | | // src: resourcePath.value ? import.meta.env.VITE_APP_RESOURCE_API + resourcePath.value : '', |
| | | // // src:'', |
| | | // type: 'application/x-mpegURL', |
| | | // } |
| | | // ], |
| | | // controlBar: { |
| | | // remainingTimeDisplay: { |
| | | // displayNegative: false |
| | | // } |
| | | // }, |
| | | // playbackRates: [0.5, 1, 1.5, 2]//设置播放速度 |
| | | // }, onPlayerReady) |
| | | // }); |
| | | // } |
| | | // } |
| | | // // watch(() => props.responseType, value => getVideo(value)) |
| | | // onUnmounted(() => { |
| | | // if (myPlayer.value) { |
| | | // myPlayer.value.dispose() |
| | | // } |
| | | // }) |
| | | // |
| | | // const dispose = () => { |
| | | // // if (myPlayer.value) { |
| | | // // myPlayer.value.dispose() |
| | | // // resourcePath.value = '' |
| | | // // } |
| | | // container.showVideo = false; |
| | | // resourcePath.value = '' |
| | | // hashPercentage.value=0 |
| | | // uploadPercentage.value=0 |
| | | // fakeUploadPercentage.value=0 |
| | | // uploadedCount.value=0 |
| | | // fileChunkList.value=[] |
| | | // fileList.value=[] |
| | | // } |
| | | // |
| | | // const changeType = (val) => { |
| | | // type.value = val |
| | | // dispose() |
| | | // if(val == 1){ |
| | | // container.showVideo = true |
| | | // nextTick(() => { |
| | | // getVideo(val) |
| | | // }) |
| | | // } |
| | | // } |
| | | // const openValue = ref(); |
| | | // const open = (val) => { |
| | | // console.log("val",val) |
| | | // openValue.value = val |
| | | // fakeUploadPercentage.value = 100 |
| | | // if(val.resourceType == 1){ |
| | | // container.showVideo = true |
| | | // resourcePath.value = val.resourcePath; |
| | | // getVideo(val.resourceType) |
| | | // }else { |
| | | // container.showVideo = false |
| | | // // if (myPlayer.value) { |
| | | // // myPlayer.value.dispose() |
| | | // // } |
| | | // fileList.value.push({ |
| | | // path: val.resourcePath, |
| | | // name: val.originName |
| | | // }) |
| | | // } |
| | | // } |
| | | // const view = (file) => { |
| | | // console.log('vlco',file) |
| | | // // console.log("点击文件=>", file); |
| | | // const url = import.meta.env.VITE_APP_RESOURCE_API + file.path; |
| | | // const link = document.createElement("a"); |
| | | // link.href = url; |
| | | // link.download = file.name; |
| | | // // link.target = "_blank"; |
| | | // document.body.appendChild(link); |
| | | // link.click(); |
| | | // document.body.removeChild(link); |
| | | // } |
| | | // // video初始化完成的回调函数 |
| | | // const onPlayerReady = () => { |
| | | // myPlayer.value.log("play.....") |
| | | // bindVideoEvents() |
| | | // } |
| | | // // 绑定事件 |
| | | // const bindVideoEvents = () => { |
| | | // if (!myPlayer.value) return |
| | | // myPlayer.value.on('play', onPlay) |
| | | // myPlayer.value.on('pause', onPause) |
| | | // myPlayer.value.on('ended', onEnded) |
| | | // myPlayer.value.on('timeupdate', onTimeupdate) |
| | | // myPlayer.value.on('loadedmetadata', onLoadedmetadata) |
| | | // myPlayer.value.on('fullscreenchange', onFullscreenchange) |
| | | // myPlayer.value.on('error', err => { |
| | | // console.log('视频加载发生错误', err) |
| | | // }) |
| | | // } |
| | | // |
| | | // const onPlay = () => { |
| | | // console.log('播放视频') |
| | | // } |
| | | // const onPause = () => { |
| | | // console.log('暂停播放') |
| | | // } |
| | | // const onEnded = () => {} |
| | | // const onTimeupdate = () => { |
| | | // console.log('播放位置已更改时,播放时间更新') |
| | | // } |
| | | // // 全屏切换 |
| | | // const onFullscreenchange = () => { |
| | | // console.log('全屏状态改变') |
| | | // } |
| | | // // 元数据加载完成 |
| | | // const onLoadedmetadata = () => { |
| | | // console.log('元数据加载完成') |
| | | // |
| | | // } |
| | | // |
| | | // |
| | | // //计算文件上传的进度 |
| | | // const uploadPercentage= computed({ |
| | | // get(){ |
| | | // if(!container.file||!fileChunkList.value.length){ |
| | | // return 0 |
| | | // } |
| | | // const loaded=fileChunkList.value.map(item => item.size * item.percentage).reduce((acc,cur) => { |
| | | // return acc+cur |
| | | // }) |
| | | // console.log('loaded',uploadedCount.value,loaded) |
| | | // return parseInt((loaded/container.file.size).toFixed(2)) |
| | | // }, |
| | | // set(value){ |
| | | // return value |
| | | // } |
| | | // }) |
| | | // |
| | | // // watch uploadPercentage,得到fakeUploadPercentage |
| | | // watch(uploadPercentage, (newValue) => { |
| | | // if (newValue >= fakeUploadPercentage.value) { |
| | | // fakeUploadPercentage.value = newValue |
| | | // } |
| | | // }) |
| | | // |
| | | // const resetData = () => { |
| | | // container.showVideo = false |
| | | // resourcePath.value = '' |
| | | // hashPercentage.value=0 |
| | | // uploadPercentage.value=0 |
| | | // fakeUploadPercentage.value=0 |
| | | // uploadedCount.value=0 |
| | | // fileChunkList.value=[] |
| | | // fileList.value=[] |
| | | // if(container.worker){ |
| | | // container.worker.onmessage=null |
| | | // } |
| | | // // if (myPlayer.value) { |
| | | // // myPlayer.value.dispose() |
| | | // // } |
| | | // const file = { |
| | | // resourceSize: null, |
| | | // md5: '', |
| | | // resourcePath: '', |
| | | // mediaType: '', |
| | | // docPage: 0, |
| | | // resourceLength: '', |
| | | // originName:'' |
| | | // } |
| | | // emit("getFile",file) |
| | | // } |
| | | // |
| | | // //选择了文件 |
| | | // const handleFileChange=(uploadFile,uploadFiles) =>{ |
| | | // // resetData() |
| | | // if(!uploadFile){ |
| | | // return |
| | | // } |
| | | // container.file=uploadFile |
| | | // fileList.value=uploadFiles |
| | | // } |
| | | // |
| | | // const handleExceed= (files) => { |
| | | // uploadfileComponent.value.clearFiles() |
| | | // nextTick(() => { |
| | | // uploadfileComponent.value.handleStart(files[0]) |
| | | // }) |
| | | // } |
| | | // |
| | | // //上传 |
| | | // const handlerUpload= async() => { |
| | | // |
| | | // if(type.value == null){ |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '请先选择资源类型' |
| | | // }); |
| | | // return false |
| | | // } |
| | | // |
| | | // if(!container.file.raw){ |
| | | // return |
| | | // } |
| | | // if(container.file.raw.size > 1024 * 1024 * 1000){ |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '文件大小不能超过1G' |
| | | // }); |
| | | // return false |
| | | // } |
| | | // |
| | | // const filetype = container.file.raw.name.split(".").pop(); |
| | | // const extension = (filetype === "mp4" || filetype ==="mp3" || filetype ==="xls" || filetype === "xlsx" || filetype ==="doc" || filetype ==="docx" || filetype === "ppt" || filetype ==="pptx" || filetype ==="pdf"); |
| | | // if (!extension ) { |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '暂不支持该格式上传' |
| | | // }); |
| | | // return false; |
| | | // } |
| | | // if((type.value == 1 && filetype != 'mp4') || (type.value == 2 && filetype != 'mp3')){ |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '请上传所选资源类型的文件' |
| | | // }); |
| | | // return false; |
| | | // } |
| | | // if(type.value == 3){ |
| | | // if( filetype == 'xls' || filetype == 'xlsx' || filetype == 'doc'|| filetype == 'docx'|| filetype == 'ppt'|| filetype == 'pptx'|| filetype == 'pdf' ){ |
| | | // |
| | | // }else { |
| | | // ElMessage({ |
| | | // type: 'warning', |
| | | // message: '请上传所选资源类型的文件' |
| | | // }); |
| | | // return false; |
| | | // } |
| | | // } |
| | | // loading.value = true |
| | | // //文件分片 |
| | | // const chunkList=createFileChunk(container.file.raw) |
| | | // console.log('文件分了多少片:',chunkList.length) |
| | | // //通过webworker计算出文件hash |
| | | // container.fileMd5=await calculateMd5(chunkList) |
| | | // console.log('文件hash1:',container.fileMd5) |
| | | // // container.fileMd5=await getFileMD5(container.file.raw) |
| | | // // console.log('文件hash2:',container.hash) |
| | | // |
| | | // fileChunkList.value=[] |
| | | // fileChunkList.value=chunkList.map(({file},index) => ({ |
| | | // fileMd5:container.fileMd5, |
| | | // index, |
| | | // chunkName: `${container.fileMd5}-${index}`, |
| | | // chunk:file, |
| | | // size:file.size, |
| | | // // 如果已上传切片数组uploadedList中包含这个切片,则证明这个切片之前已经上传成功了,进度设为100。 |
| | | // percentage:0 |
| | | // })) |
| | | // |
| | | // uploadChunks(fileChunkList) |
| | | // |
| | | // } |
| | | // |
| | | // //文件分片 |
| | | // const createFileChunk = (file,size=chunkSize.value) => { |
| | | // const chunkList=[] |
| | | // let cur=0 |
| | | // while(cur<file.size){ |
| | | // chunkList.push({ |
| | | // file:file.slice(cur,cur+size), |
| | | // }) |
| | | // cur+=size |
| | | // } |
| | | // return chunkList |
| | | // } |
| | | // |
| | | // //计算文件md5 方法1 |
| | | // const calculateMd5 = (chunkList) => { |
| | | // return new Promise((resolve) => { |
| | | // container.worker=new Worker('/hash.js') |
| | | // container.worker.postMessage({fileChunkList:chunkList}) |
| | | // container.worker.onmessage= (e) => { |
| | | // const {percentage,hash} = e.data |
| | | // hashPercentage.value=percentage.toFixed(2) |
| | | // if(hash){ |
| | | // resolve(hash) |
| | | // } |
| | | // } |
| | | // }) |
| | | // } |
| | | // |
| | | // //计算文件md5 方法2 |
| | | // const getFileMD5 = (file) => { |
| | | // return new Promise((resolve, reject) => { |
| | | // const spark = new SparkMD5.ArrayBuffer() |
| | | // const fileReader = new FileReader() |
| | | // fileReader.onload = (e) => { |
| | | // spark.append(e.target?.result) |
| | | // resolve(spark.end()) |
| | | // } |
| | | // fileReader.onerror = () => { |
| | | // reject('') |
| | | // } |
| | | // fileReader.readAsArrayBuffer(file) |
| | | // }) |
| | | // } |
| | | // |
| | | // //计算上传进度 |
| | | // const createProgressHandler = (item) => { |
| | | // console.log('createProgresshandler -> item', item); |
| | | // return (p) => { |
| | | // if(item.percentage>=100){ |
| | | // item.percentage = 100 |
| | | // }else{ |
| | | // item.percentage=parseInt(String((p.loaded/p.total)*100)) |
| | | // } |
| | | // // 确保进度百分比不会超过100% |
| | | // if (item.percentage > 100) item.percentage = 100 |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | // |
| | | // //上传切片 |
| | | // const uploadChunks= async(uploadedList) => { |
| | | // const limit = pLimit(10); // 控制并发数为10 |
| | | // const requestList=uploadedList.value.map(({chunk,chunkName,index,fileMd5}) => { |
| | | // const formdata=new FormData() |
| | | // formdata.append('file',chunk) |
| | | // formdata.append('chunkName',chunkName) |
| | | // formdata.append('fileName',container.file.name) |
| | | // formdata.append('fileMd5',fileMd5) |
| | | // formdata.append('index',index) |
| | | // return {formdata,index} |
| | | // }).map(async ({formdata,index}) => { |
| | | // return limit(() => doUploadChunk({data:formdata,onUploadProgress:createProgressHandler(fileChunkList.value[index])})) |
| | | // }) |
| | | // await Promise.all(requestList) |
| | | // console.log("数组:",fileChunkList) |
| | | // if(uploadedCount.value>=fileChunkList.value.length){ |
| | | // mergeRequest() |
| | | // } |
| | | // |
| | | // } |
| | | // |
| | | // |
| | | // const doUploadChunk = ({data,onUploadProgress}) => { |
| | | // return new Promise((resolve) => { |
| | | // uploadFileRequest(data,onUploadProgress).then((result) => { |
| | | // let resData=result.data |
| | | // if(result&&result.code==200){ |
| | | // uploadedCount.value=uploadedCount.value+1 |
| | | // fileChunkList.value[data.get('index')].percentage=100 //手动更新进度 |
| | | // console.log(uploadedCount.value,'result--------------') |
| | | // } |
| | | // resolve('done') |
| | | // }) |
| | | // }) |
| | | // } |
| | | // |
| | | // const mergeRequest = async() => { |
| | | // if(container.file.name.lastIndexOf(".") === -1){ |
| | | // ElMessage.warning("请输入文件后缀名") |
| | | // return |
| | | // } |
| | | // let data=await mergeFileRequest({fileMd5:container.fileMd5,fileName:container.file.name}) |
| | | // console.log(data,"mege------------222") |
| | | // if(data && data.code==200){ |
| | | // const filetype = data.data.originName.split(".").pop(); |
| | | // if(filetype == 'mp4' || filetype == 'MP4'){ |
| | | // container.showVideo = true |
| | | // await nextTick(() => { |
| | | // |
| | | // console.log("myPlayer.value",myPlayer.value) |
| | | // myPlayer.value.src( |
| | | // { |
| | | // src: import.meta.env.VITE_APP_RESOURCE_API +data.data.path, |
| | | // type: 'application/x-mpegURL', |
| | | // }) |
| | | // // myPlayer.value.load() |
| | | // myPlayer.value.play().catch((error) => { |
| | | // console.error('Error playing video:', error); |
| | | // }); |
| | | // }) |
| | | // // myPlayer.value.pause() |
| | | // //myPlayer.value.reset() |
| | | // } |
| | | // const file = { |
| | | // resourceSize: data.data.size, |
| | | // md5: data.data.md5, |
| | | // resourcePath: data.data.path, |
| | | // mediaType: filetype, |
| | | // docPage: data.data.docPage, |
| | | // resourceLength: data.data.resourceLength, |
| | | // originName: data.data.originName |
| | | // } |
| | | // emit("getFile",file) |
| | | // |
| | | // |
| | | // loading.value = false |
| | | // ElMessage.success("上传成功") |
| | | // }else{ |
| | | // ElMessage.success("合并数据失败") |
| | | // } |
| | | // } |
| | | // |
| | | // defineExpose({ |
| | | // dispose, |
| | | // changeType, |
| | | // open |
| | | // }); |
| | | </script> |
| | | |
| | | |
| | | <style scoped> |
| | | .greetings{ |
| | | :deep(.video-js) { |
| | | width: 300px; |
| | | height: 200px; |
| | | } |
| | | :deep(.el-icon--close) { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | h1 { |
| | | font-weight: 500; |
| | | font-size: 2.6rem; |
| | | position: relative; |
| | | top: -10px; |
| | | } |
| | | |
| | | h3 { |
| | | font-size: 1.2rem; |
| | | } |
| | | |
| | | .greetings h1, |
| | | .greetings h3 { |
| | | text-align: center; |
| | | } |
| | | |
| | | @media (min-width: 1024px) { |
| | | .greetings h1, |
| | | .greetings h3 { |
| | | text-align: left; |
| | | } |
| | | } |
| | | </style> |