完善视频上传

This commit is contained in:
none 2023-03-08 15:56:06 +08:00
parent b12fb1d7a9
commit 9428cf1785
7 changed files with 56 additions and 47 deletions

View File

@ -115,6 +115,19 @@ export class HttpClient {
}); });
}); });
} }
request(config: object) {
return new Promise((resolve, reject) => {
this.axios
.request(config)
.then((res) => {
resolve(res.data);
})
.catch((err) => {
reject(err.data);
});
});
}
} }
const APP_URL = process.env.REACT_APP_URL || ""; const APP_URL = process.env.REACT_APP_URL || "";

View File

@ -1,14 +1,7 @@
import client from "./internal/httpClient"; import client from "./internal/httpClient";
export function image(categoryId: number, file: File) {
return client.post("/backend/v1/upload/image", {
category_id: categoryId,
file: file,
});
}
export function minioUploadId(extension: string) { export function minioUploadId(extension: string) {
return client.get("/backend/v1/upload/minio-upload-id", { return client.get("/backend/v1/upload/minio/upload-id", {
extension, extension,
}); });
} }
@ -17,16 +10,31 @@ export function minioPreSignUrl(
filename: string, filename: string,
partNumber: number partNumber: number
) { ) {
return client.get("/backend/v1/upload/minio-pre-sign-url", { return client.get("/backend/v1/upload/minio/pre-sign-url", {
upload_id: uploadId, upload_id: uploadId,
filename, filename,
part_number: partNumber, part_number: partNumber,
}); });
} }
export function minioMerge(filename: string, uploadId: string) { export function minioMergeVideo(
return client.get("/backend/v1/upload/minio-merge", { filename: string,
uploadId: string,
categoryId: number,
originalFilename: string,
extension: string,
size: number,
duration: number,
poster: string
) {
return client.post("/backend/v1/upload/minio/merge-video", {
filename, filename,
upload_id: uploadId, upload_id: uploadId,
original_filename: originalFilename,
category_id: categoryId,
size,
duration,
extension,
poster,
}); });
} }

View File

@ -18,7 +18,7 @@ export const UploadImageSub = (props: PropsInterface) => {
multiple: true, multiple: true,
action: action:
config.app_url + config.app_url +
"/backend/v1/upload/image?category_id=" + "/backend/v1/upload/file?category_id=" +
props.categoryId, props.categoryId,
headers: { headers: {
authorization: "Bearer " + getToken(), authorization: "Bearer " + getToken(),

View File

@ -13,9 +13,8 @@ import {
import Dragger from "antd/es/upload/Dragger"; import Dragger from "antd/es/upload/Dragger";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { generateUUID, parseVideo } from "../../utils"; import { generateUUID, parseVideo } from "../../utils";
import { minioUploadId } from "../../api/upload"; import { minioMergeVideo, minioUploadId } from "../../api/upload";
import { UploadChunk } from "../../js/minio-upload-chunk"; import { UploadChunk } from "../../js/minio-upload-chunk";
import { storeResource } from "../../api/resource";
interface PropsInterface { interface PropsInterface {
categoryId: number; categoryId: number;
@ -24,6 +23,8 @@ interface PropsInterface {
interface FileItem { interface FileItem {
id: string; id: string;
filename: string;
uploadId: string;
name: string; name: string;
duration: number; duration: number;
size: number; size: number;
@ -36,6 +37,7 @@ interface FileItem {
isErr: boolean; isErr: boolean;
errMsg: string; errMsg: string;
remoteName: string; remoteName: string;
poster: string;
} }
export const UploadVideoButton = (props: PropsInterface) => { export const UploadVideoButton = (props: PropsInterface) => {
@ -52,6 +54,7 @@ export const UploadVideoButton = (props: PropsInterface) => {
multiple: true, multiple: true,
beforeUpload: async (file: File) => { beforeUpload: async (file: File) => {
if (file.type === "video/mp4") { if (file.type === "video/mp4") {
// 视频封面解析 || 视频时长解析
let videoInfo = await parseVideo(file); let videoInfo = await parseVideo(file);
// 添加到本地待上传 // 添加到本地待上传
let data = await getMinioUploadId(); let data = await getMinioUploadId();
@ -59,6 +62,8 @@ export const UploadVideoButton = (props: PropsInterface) => {
let item: FileItem = { let item: FileItem = {
id: generateUUID(), id: generateUUID(),
duration: videoInfo.duration, duration: videoInfo.duration,
filename: data["filename"],
uploadId: data["upload_id"],
name: file.name, name: file.name,
size: file.size, size: file.size,
progress: 0, progress: 0,
@ -70,25 +75,21 @@ export const UploadVideoButton = (props: PropsInterface) => {
isErr: false, isErr: false,
errMsg: "", errMsg: "",
remoteName: data["filename"], remoteName: data["filename"],
poster: videoInfo.poster,
}; };
item.run.on("success", (url: string) => { item.run.on("success", () => {
minioMergeVideo(
item.filename,
item.uploadId,
props.categoryId,
item.name,
"mp4",
item.size,
item.duration,
item.poster
).then(() => {
item.isSuc = true; item.isSuc = true;
setFileList([...localFileList.current]); setFileList([...localFileList.current]);
// 创建上传记录
storeResource(
props.categoryId,
item.file.name,
"mp4",
item.file.size,
"minio",
"",
item.remoteName,
url,
{
duration: item.duration,
}
).then(() => {
message.success(`${item.file.name} 上传成功`); message.success(`${item.file.name} 上传成功`);
}); });
}); });

View File

@ -1,5 +1,5 @@
import axios, { Axios } from "axios"; import axios, { Axios } from "axios";
import { minioMerge, minioPreSignUrl } from "../api/upload"; import { minioPreSignUrl } from "../api/upload";
export class UploadChunk { export class UploadChunk {
client: Axios; client: Axios;
@ -13,7 +13,7 @@ export class UploadChunk {
filename: string; filename: string;
onError: ((err: string) => void | undefined) | undefined; onError: ((err: string) => void | undefined) | undefined;
onSuccess: ((url: string) => void | undefined) | undefined; onSuccess: (() => void | undefined) | undefined;
onRetry: (() => void | undefined) | undefined; onRetry: (() => void | undefined) | undefined;
onProgress: ((progress: number) => void) | undefined; onProgress: ((progress: number) => void) | undefined;
@ -51,15 +51,7 @@ export class UploadChunk {
} }
if (this.chunkIndex > this.chunkNumber) { if (this.chunkIndex > this.chunkNumber) {
//上传完成 //上传完成
minioMerge(this.filename, this.uploadId) this.onSuccess && this.onSuccess();
.then((res: any) => {
let url = res.data.url;
this.onSuccess && this.onSuccess(url);
})
.catch((e) => {
console.error("文件合并失败", e);
this.onError && this.onError("失败.3");
});
return; return;
} }
this.onProgress && this.onProgress &&

View File

@ -1,4 +1,4 @@
export interface VideoParseInfo { export interface VideoParseInfo {
poster:File; poster:string;
duration:number; duration:number;
} }

View File

@ -65,14 +65,9 @@ export function parseVideo(file: File): Promise<VideoParseInfo> {
} }
ctx.drawImage(video, 0, 0, width, height); //绘制canvas ctx.drawImage(video, 0, 0, width, height); //绘制canvas
let dataURL = canvas.toDataURL("image/png"); //转换为base64 let dataURL = canvas.toDataURL("image/png"); //转换为base64
const imageFile = transformBase64ToBlob(
dataURL,
"image/png",
file.name + ".png"
);
video.remove(); video.remove();
let info: VideoParseInfo = { let info: VideoParseInfo = {
poster: imageFile, poster: dataURL,
duration: parseInt(video.duration + ""), duration: parseInt(video.duration + ""),
}; };
return resolve(info); return resolve(info);