This commit is contained in:
禺狨 2023-03-08 11:40:45 +08:00
commit d66c19bb4c
3 changed files with 64 additions and 19 deletions

View File

@ -12,7 +12,7 @@ import {
} from "antd";
import Dragger from "antd/es/upload/Dragger";
import { useRef, useState } from "react";
import { generateUUID } from "../../utils";
import { generateUUID, parseVideo } from "../../utils";
import { minioUploadId } from "../../api/upload";
import { UploadChunk } from "../../js/minio-upload-chunk";
import { storeResource } from "../../api/resource";
@ -52,12 +52,13 @@ export const UploadVideoButton = (props: PropsInterface) => {
multiple: true,
beforeUpload: async (file: File) => {
if (file.type === "video/mp4") {
let videoInfo = await parseVideo(file);
// 添加到本地待上传
let data = await getMinioUploadId();
let run = new UploadChunk(file, data["upload_id"], data["filename"]);
let item: FileItem = {
id: generateUUID(),
duration: 0,
duration: videoInfo.duration,
name: file.name,
size: file.size,
progress: 0,
@ -128,20 +129,6 @@ export const UploadVideoButton = (props: PropsInterface) => {
</Button>
<div className="none">
{fileList.length > 0 &&
fileList.map((item) => (
<video
key={item.id}
src={URL.createObjectURL(item.file)}
onCanPlayThrough={(e: any) => {
item.duration = parseInt(e.target.duration);
item.loading = false;
}}
></video>
))}
</div>
{showModal && (
<Modal
width={800}

4
src/types/index.ts Normal file
View File

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

View File

@ -1,4 +1,6 @@
import { assert } from "console";
import moment from "moment";
import { VideoParseInfo } from "../types";
export function getToken(): string {
return window.localStorage.getItem("playedu-backend-token") || "";
@ -16,7 +18,7 @@ export function dateFormat(dateStr: string) {
return moment(dateStr).format("YYYY-MM-DD HH:mm");
}
export const generateUUID = (): string => {
export function generateUUID(): string {
let guid = "";
for (let i = 1; i <= 32; i++) {
let n = Math.floor(Math.random() * 16.0).toString(16);
@ -24,4 +26,56 @@ export const generateUUID = (): string => {
if (i === 8 || i === 12 || i === 16 || i === 20) guid += "-";
}
return guid;
}
export function transformBase64ToBlob(
base64: string,
mime: string,
filename: string
): File {
const arr = base64.split(",");
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
export function parseVideo(file: File): Promise<VideoParseInfo> {
return new Promise((resolve, reject) => {
let video = document.createElement("video");
video.muted = true;
video.setAttribute("src", URL.createObjectURL(file));
video.setAttribute("autoplay", "autoplay");
video.setAttribute("crossOrigin", "anonymous"); //设置跨域 否则toDataURL导出图片失败
video.setAttribute("width", "400"); //设置大小如果不设置下面的canvas就要按需设置
video.setAttribute("height", "300");
video.currentTime = 7; //视频时长,一定要设置,不然大概率白屏
video.addEventListener("loadeddata", function () {
let canvas = document.createElement("canvas"),
width = video.width, //canvas的尺寸和图片一样
height = video.height;
canvas.width = width; //画布大小,默认为视频宽高
canvas.height = height;
let ctx = canvas.getContext("2d");
if (!ctx) {
return reject("无法捕获视频帧");
}
ctx.drawImage(video, 0, 0, width, height); //绘制canvas
let dataURL = canvas.toDataURL("image/png"); //转换为base64
const imageFile = transformBase64ToBlob(
dataURL,
"image/png",
file.name + ".png"
);
video.remove();
let info: VideoParseInfo = {
poster: imageFile,
duration: parseInt(video.duration + ""),
};
return resolve(info);
});
});
}