|
@@ -3,9 +3,12 @@ import { ref, reactive, computed, watch } from 'vue'
|
|
|
import {apiAudio,apiVideo,apiMediaCommon} from '@/api/media'
|
|
|
import { apiAuthor } from '@/api/author'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
+import { uploadFileToMinIO } from "../common/uploadFile"
|
|
|
|
|
|
const emits = defineEmits('save')
|
|
|
const show = defineModel('show', { type: Boolean, default: false })
|
|
|
+const showProgress = ref(false);
|
|
|
+const percentage = ref(0);
|
|
|
const props = defineProps({
|
|
|
mediaType:{
|
|
|
type:String,
|
|
@@ -75,6 +78,8 @@ watch(show,(newval)=>{
|
|
|
mediaCover:'',
|
|
|
duration:0
|
|
|
})
|
|
|
+ showProgress.value = false;
|
|
|
+ percentage.value = 0;
|
|
|
}
|
|
|
})
|
|
|
|
|
@@ -107,6 +112,33 @@ const uploadRef = ref(null)
|
|
|
function handleUpload(){
|
|
|
uploadRef.value?.$el.getElementsByTagName('input')[0].click()
|
|
|
}
|
|
|
+
|
|
|
+function getMediaDuration(file,callback,failback){
|
|
|
+ let durations = 0;
|
|
|
+ const url = URL.createObjectURL(file);
|
|
|
+ const mediaElement = document.createElement(file.type.startsWith("audio") ? "audio" : "video");
|
|
|
+ mediaElement.src = url;
|
|
|
+ mediaElement.preload = "metadata";
|
|
|
+ mediaElement.onloadedmetadata = () => {
|
|
|
+ durations = Math.ceil(mediaElement.duration * 1000); //ms
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
+ callback(durations)
|
|
|
+ };
|
|
|
+ mediaElement.onerror = () => {
|
|
|
+ ElMessage.error('获取多媒体时长失败,请重新上传')
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
+ failback()
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+function getPrePath(file){
|
|
|
+ const date = new Date();
|
|
|
+ const year = date.getFullYear();
|
|
|
+ const month = ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1);
|
|
|
+ const day = (date.getDate() < 10 ? '0' : '') + date.getDate();
|
|
|
+ return `ht/${file.type.startsWith("audio") ? "audio" : "video"}/${'' + year + month}/${'' + year + month + day}/`
|
|
|
+}
|
|
|
+
|
|
|
async function handleUploadMedia(file){
|
|
|
uploadLoading.value = true
|
|
|
const {type} = file.file
|
|
@@ -115,17 +147,55 @@ async function handleUploadMedia(file){
|
|
|
uploadLoading.value = false
|
|
|
return
|
|
|
}
|
|
|
- let form = new FormData();
|
|
|
- form.append('File',file.file);
|
|
|
- const res = props.mediaType==='audio'
|
|
|
- ?await apiAudio.uploadAudioFile(form)
|
|
|
- :await apiVideo.uploadVideoFile(form)
|
|
|
- uploadLoading.value = false
|
|
|
- if(res.Ret!==200) return
|
|
|
- mediaData.fileUrl = res.Data.Url||""
|
|
|
- mediaData.duration = res.Data.DurationMillisecond||0
|
|
|
|
|
|
+ getMediaDuration(file.file,async (durations) => { //success
|
|
|
+ let res = await apiMediaCommon.getMinioSign();
|
|
|
+ if(res.Ret != 200) {
|
|
|
+ ElMessage.warning('获取minio临时签名错误')
|
|
|
+ uploadLoading.value = false
|
|
|
+ return
|
|
|
+ };
|
|
|
+ let { Data } = res;
|
|
|
+ percentage.value = 0;
|
|
|
+ showProgress.value = true;
|
|
|
+ try {
|
|
|
+ const fileUrl = await uploadFileToMinIO(file.file,{
|
|
|
+ endpoint:Data.Endpoint,
|
|
|
+ region: Data.RegionId,
|
|
|
+ forcePathStyle: true,
|
|
|
+ credentials: {
|
|
|
+ accessKeyId:Data.AccessKeyId,
|
|
|
+ secretAccessKey:Data.SecretKeyId,
|
|
|
+ },
|
|
|
+ chunkSize : 5 * 1024 * 1024,
|
|
|
+ bucketName:Data.Bucketname,
|
|
|
+ imgHost:Data.ImgHost,
|
|
|
+ prePath:getPrePath(file.file),//存储路径,没有则不传
|
|
|
+ onProgress: (progress) => {
|
|
|
+ percentage.value = progress;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ setTimeout(() => {
|
|
|
+ ElMessage.success('上传成功');
|
|
|
+ uploadLoading.value = false;
|
|
|
+ showProgress.value = false;
|
|
|
+ percentage.value = 0;
|
|
|
+ mediaData.fileUrl = fileUrl||"";
|
|
|
+ mediaData.duration = durations||0;
|
|
|
+ }, 300);
|
|
|
+ } catch (error) {
|
|
|
+ uploadLoading.value = false
|
|
|
+ showProgress.value = false;
|
|
|
+ percentage.value = 0;
|
|
|
+ ElMessage.error('上传失败,请重试')
|
|
|
+ }
|
|
|
+ },() => { //fail
|
|
|
+ uploadLoading.value = false;
|
|
|
+ showProgress.value = false;
|
|
|
+ percentage.value = 0;
|
|
|
+ })
|
|
|
}
|
|
|
+
|
|
|
//获取音频长度
|
|
|
function getAudioDuration(file){
|
|
|
return new Promise((resolve,reject)=>{
|
|
@@ -209,7 +279,7 @@ function handleUploadImg(file){
|
|
|
<el-dialog v-model="show" :title="dialogTitle" width="530px" draggable>
|
|
|
<div class="content-wrap">
|
|
|
<el-form label-width="95px" label-position="left" :model="mediaData" :rules="rules" ref="formRef">
|
|
|
- <el-form-item prop="fileUrl" class="upload-form-item">
|
|
|
+ <el-form-item prop="fileUrl" class="upload-form-item" style="position: relative;">
|
|
|
<el-input :placeholder="props.mediaType==='audio'?'音频格式限制mp3、m4a':'视频格式限制mp4,编码器为H.264'" v-model="mediaData.fileUrl" disabled>
|
|
|
<template #append>
|
|
|
<el-button
|
|
@@ -229,6 +299,7 @@ function handleUploadImg(file){
|
|
|
</el-upload>
|
|
|
</template>
|
|
|
</el-input>
|
|
|
+ <el-progress v-if="showProgress" type="circle" :percentage="percentage" :width="50" class="progress-postion"/>
|
|
|
</el-form-item>
|
|
|
<el-form-item prop="mediaCover" label="照片" v-if="props.mediaType==='video'">
|
|
|
<ImageUpload
|
|
@@ -283,5 +354,18 @@ function handleUploadImg(file){
|
|
|
.upload-form-item{
|
|
|
margin-left: -95px;
|
|
|
}
|
|
|
+ .progress-postion{
|
|
|
+ position: absolute;
|
|
|
+ right: -50px;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+.content-wrap{
|
|
|
+ .el-progress__text{
|
|
|
+ font-size: 12px !important;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|