首先安装插件
npm install webuploader --save
npm install jquery@1.12.4
index.vue
<template>
<div>
<!-- 视频分片上传
npm install webuploader --save
npm install jquery@1.12.4 -S -->
<video-upload :files="videoList"
:libCode="libCode"
ref="videoUpload"
@videoUploadStart="videoUploadStart"
@videoUploadEnd="videoUploadEnd"
@videoUploadDel="videoUploadDel" ></video-upload>
</div>
</template>
<script>
import videoUpload from './videoUpload' // 视频分片
export default {
name: 'navMenu',
components: {
videoUpload
},
data () {
return {
libCode: ''
}
},
methods: {
videoUploadStart () { // 视频文件上传开始
console.log('视频文件上传开始')
},
videoUploadEnd (data) { // 视频文件上传成功
console.log('视频上传成功', data)
},
videoUploadDel () {
console.log('删除了视频')
}
}
}
</script>
<style scoped>
</style>
videoUpload.vue
<template>
<!--视频上传-->
<div class='localUpload'>
<div class="dialog_content">
<div class="middle_operation">
<!-- <span v-show="activeResType !== 'test'"> -->
<webuploader :libCode="libCode"
ref="uploader"
:cancel-file = "cancelFile"
:stop-file="stopFile"
:continue-file="continueFile"
@file-add="fileAddFun"
@percentage="percentageFun"
@cancel-edit="cancelFun"
@upload-end="uploadEndFun"
@upload-config="uploadConfig">
</webuploader>
<!-- </span> -->
</div>
<div class="el-upload__tip">支持H264编码的mp4</div>
<div class="bottom_content">
<el-table
v-for="(value, key, index) in tableDataObj"
:key="index"
:data="value"
:ref="'multipleTable' + key"
style="width: 100%"
:show-header="false">
<!-- 标题 -->
<el-table-column>
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
{{ scope.row.name }}
<div class="resName" slot="reference">
{{ scope.row.name }}
</div>
</el-popover>
</template>
</el-table-column>
<!-- 进度 -->
<el-table-column
width="100">
<template slot-scope="scope">
<span>{{ scope.row.percentage }}</span>
</template>
</el-table-column>
<!-- 操作-->
<el-table-column
width="100">
<template slot-scope="scope" v-if="scope.row.success">
<span class="opertaions btnD" @click="openDeleteRes(scope.row, scope.$index)">重新上传</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
// import { Get } from '@common'
import webuploader from './webuploader.vue'
export default {
name: 'localUpload',
components: {
webuploader
},
props: {
files: {
type: Array,
default: null
},
libCode: {
type: String,
default: ''
}
},
watch: {
files (nv) {
if (this.$route.params.data) { // 编辑
this.tableDataObj['FILE_1'] = []
this.tableDataObj['FILE_1'].push({
name: nv[0].name,
percentage: '100%',
fileRecordId: nv[0].fileRecordId,
success: true
})
this.$refs.uploader.fileList.push(nv[0].url)
this.$refs.uploader.videoUrl = nv[0].url
this.$forceUpdate()
}
}
},
data () {
return {
basePath: '',
resType: [
{
title: '音视频',
tag: 'media'
}
],
cancelFile: null, // 取消上传的文件
stopFile: null, // 暂停上传的文件
continueFile: null, // 继续上传的文件
urls: {
delRes: '/app/coursepacket/courseware/delResourceWareList' // 删除资源
},
tabPosition: 'top',
tableDataObj: {}, // 资源列表对象
fileRecordId: '',
cfId: ''
}
},
computed: {},
created () {
},
mounted () {
},
beforeDestroy () {
},
methods: {
dealData (file) {
this.tableDataObj = {} // 清空列表
this.tableDataObj[file.resType + file.id] = []
this.tableDataObj[file.resType + file.id].push({
name: file.name,
percentage: file.percentage ? file.percentage + '%' : '等待上传',
ext: file.ext,
resId: file.id,
file: file
})
this.$emit('videoUploadStart')
},
fileAddFun (file) {
this.dealData(file)
this.$forceUpdate()
},
percentageFun (file) {
this.dealData(file)
this.$forceUpdate()
// this.isEmptyFun()
},
uploadEndFun (file, resp) {
// console.log(file, resp)
let data = resp.data
this.tableDataObj[file.resType + file.id] = []
if (resp && resp.status === 0) {
// 上传成功
this.tableDataObj[file.resType + file.id].push({
name: file.name,
percentage: file.percentage ? file.percentage + '%' : '等待上传',
ext: file.ext,
resId: file.id,
id: data.ID,
coursePackageId: this.id,
success: true,
fileRecordId: data.fileRecordId
})
this.$message.success('上传成功!')
this.$refs.uploader.videoUrl = data.url
data.cfId = this.cfId
this.$emit('videoUploadEnd', { file, data })
} else {
// 上传失败
delete this.tableDataObj[file.resType + file.id]
this.$message.error(resp.message)
}
this.$forceUpdate()
// this.isEmptyFun()
},
uploadConfig (cfId) {
this.cfId = cfId
},
cancelFun () {},
// 暂停文件上传
stopUpload (item) {
this.stopFile = item.file
},
// 继续文件上传
continueUpload (item) {
this.continueFile = item.file
},
// 取消文件上传
cancelUpload (item) {
// this.$confirm('确认取消文件上传操作?', '取消文件上传', {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// type: 'warning',
// })
// .then(() => {
this.cancelFile = item.file
let key = item.file.resType + item.file.id
delete this.tableDataObj[key]
this.$message.success('已取消文件上传')
// })
// .catch(() => {})
},
openDeleteRes (item) { // 删除上传完成文件
this.tableDataObj = {}
this.$refs.uploader.fileList = []
this.$refs.uploader.videoUrl = ''
this.$emit('videoUploadDel')
const params = {
files: item.fileRecordId
}
this.$api.newList.deleteFile(params).then(res => {
const data = res.data
if (data.status === 0) {
console.log('删除成功!')
} else {
console.log('删除失败!' + data.message)
}
})
}
}
}
</script>
<style>
.localUpload .el-dialog__footer{
text-align: center;
}
</style>
<style scoped>
.el-upload__tip {
font-size: 12px;
color: #606266;
margin-top: 7px;
}
.btnD {
cursor: pointer;
}
</style>
webuploader.vue
<template>
<div id="webuploader">
<!-- <p @click="cancelEdit" id="filePicker" class="filePicker">本地上传</p> -->
<div @click="cancelEdit" id="filePicker" class="filePicker">
<i class="el-icon-upload iconUpload"></i>
<p class="textUpload">点击上传</p>
</div>
<video v-if="videoUrl" :src="videoUrl" controls="controls" controlslist="nodownload" class="videoPlay"></video>
</div>
</template>
<script>
import WebUploader from 'webuploader'
// import { Get } from '@common'
export default {
props: {
libCode: {
type: String,
default: ''
},
// 要取消上传的文件
cancelFile: {
default: null
},
// 要暂停上传的文件
stopFile: {
default: null
},
// 要继续上传的文件
continueFile: {
default: null
}
},
data () {
return {
fileList: [],
basePath: '',
subjectID: '',
subjectName: '',
uploader: null,
curResType: '', // 当前上传文件的类型
accept: {
media: {
exteensions: 'mp4',
mimeTypes: '.mp4'
}
},
ext: {
media: [
'MP4'
]
},
cfDeviceName: '',
cfRelurl: '',
cfId: '',
videoUrl: ''
}
},
watch: {
// 取消文件上传
cancelFile (file) {
if (file) {
this.uploader.cancelFile(file)
}
},
// 暂停文件上传
stopFile (file) {
if (file) {
this.uploader.stop(file)
}
},
// 继续文件上传
continueFile (file) {
if (file) {
this.uploader.upload(file.id)
}
}
},
created () {},
mounted () {
this.initUploader()
},
methods: {
// 创建WebUploader实例
initUploader () {
let that = this
this.uploader = WebUploader.create({
auto: false, // 选完文件后,是否自动上传
swf: 'https://cdn.bootcss.com/webuploader/0.1.1/Uploader.swf', // swf文件路径
pick: {
id: '#filePicker', // 选择文件的按钮
multiple: false // 是否多文件上传 默认false
},
accept: {
exteensions: 'mp4',
mimeTypes: '.mp4'
}, // 允许选择文件格式。
threads: 1,
resize: false, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
fileNumLimit: 100, // 限制上传个数
// formData: that.formData, // 上传所需参数
// method: 'POST',
chunked: true, // 分片上传
chunkSize: 1 * 1024 * 1024, // 分片大小
duplicate: true // 是否重复上传
})
// 文件加入队列前,判断文件类型
this.uploader.on('beforeFileQueued', file => {
// console.log(file)
if (this.fileList.length === 1) {
this.$message.warning('资源数已达上限,不能继续上传')
return false
}
if (file.size === 0) {
this.$message({
message: '仅支持上传大于0KB的文件!',
type: 'warning'
})
return false
}
// if (
// this.ext[this.resType].indexOf(file.ext.toLocaleUpperCase()) === -1
// ) {
// this.$message.error('不支持的文件格式!')
// return false
// }
})
// 文件参数设置,开始上传
this.uploader.on('fileQueued', file => {
const params = {
type: '视频',
libCode: this.libCode
}
this.$api.newList.getFileConfig(params).then(res => {
const data = res.data
if (data.status === 0) {
this.cfId = data.data.cfId
this.$emit('upload-config', this.cfId)
this.cfDeviceName = data.data.cfDeviceName
this.cfRelurl = data.data.cfRelurl
// 文件上传参数
let formData = {
deviceName: this.cfDeviceName,
remoteFile: this.cfRelurl,
remoteFileName: file.name,
chunked: true,
guid: file.source.uid
}
this.$emit('file-add', file)
this.uploader.options.formData = formData
this.uploader.options.server = window.PROJECT_CONFIG.BASE_URL + '/dynamicFile/uploadFile.do'
this.fileList = [] // 清空列表
this.fileList.push(file)
this.uploader.upload(file)
// this.uploadFile(file)
// this.fileList.forEach(file => { // 开始上传
// this.uploader.upload(file)
// })
} else {
console.log(data.message)
}
})
})
// 分片发送前参数设置,解决多个文件同时分片上传时参数错乱的问题
this.uploader.on('uploadBeforeSend', (obj, data) => {
// this.uploader.options.server = obj.file.resType
data.guid = obj.file.guid
data.ext = obj.file.ext
})
// 文件上传进度
this.uploader.on('uploadProgress', function (file, percentage) {
file.percentage = Math.round(percentage * 100)
that.$emit('percentage', file)
})
// 上传成功
this.uploader.on('uploadSuccess', function (file, resp) {
that.$emit('upload-end', file, resp)
})
// 上传失败
this.uploader.on('uploadError', function (file, resp) {
that.$message.error('上传资源失败,请稍后再试', file, resp)
})
// 上传完成,不管成功或失败
this.uploader.on('uploadComplete', function (file) {
console.log(file)
})
},
// 点击确定 开始上传
startUpload () {
this.fileList.forEach(file => {
this.uploader.upload(file)
})
},
// 取消重命名
cancelEdit () {
this.$emit('cancel-edit')
}
}
}
</script>
<style>
/* .webuploader-element-invisible {
opacity: 0;
} */
.webuploader-container {
position: relative;
}
.webuploader-element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
}
.webuploader-pick {
width: 100%;
height: 100%;
position: relative;
display: inline-block;
cursor: pointer;
color: #fff;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
/* .webuploader-pick-hover {
background: #00a2d4;
} */
.webuploader-pick-disable {
opacity: 0.6;
pointer-events:none;
}
.opertaions{
color: #d0252e;
}
</style>
<style scoped>
#webuploader {
position: relative;
}
.add {
padding-left: 15px;
}
.filePicker{
background-color: #fff;
border: 1px dashed #d9d9d9;
border-radius: 6px;
box-sizing: border-box;
width: 360px;
height: 180px;
text-align: center;
position: relative;
overflow: hidden;
}
.iconUpload {
font-size: 70px;
display: block;
margin: 40px auto 10px;
color: #C0C4CC;
}
.textUpload {
font-size: 16px;
text-align: center;
display: block;
color: #666;
}
.videoPlay {
width: 360px;
height: 150px;
position: absolute;
top: 0;
left: 0;
}
</style>