add video upload input
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import ProtectedFilesTable from '@/app/ui/marking-page/protected-files-table';
|
||||
import ProtectionSummary from '@/app/ui/marking-page/protection-summary';
|
||||
import TestSection from '@/app/ui/marking-page/test-section';
|
||||
import { IconVideoFile } from '@/app/ui/icons/icons';
|
||||
import UploadSectionVideo from '@/app/ui/marking-page/upload-section-video';
|
||||
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
@@ -10,6 +11,7 @@ export default function Page() {
|
||||
<h1 >Защита видео</h1>
|
||||
</div>
|
||||
<ProtectionSummary />
|
||||
<UploadSectionVideo />
|
||||
<TestSection />
|
||||
<ProtectedFilesTable />
|
||||
</div>
|
||||
|
||||
@@ -9,8 +9,6 @@ body {
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import React, { useRef, useState, useCallback, ChangeEvent, DragEvent } from 'react';
|
||||
import { IconImageFile } from '@/app/ui/icons/icons';
|
||||
|
||||
interface SelectedFile {
|
||||
file: File;
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useRef } from 'react';
|
||||
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
export default function UploadSectionVideo() {
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [videoId, setVideoId] = useState<string | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const uploadVideoInChunks = async (file: File) => {
|
||||
setUploading(true);
|
||||
setProgress(0);
|
||||
|
||||
const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
|
||||
const uploadId = Date.now().toString();
|
||||
|
||||
let start = 0;
|
||||
let chunkIndex = 0;
|
||||
|
||||
try {
|
||||
while (start < file.size) {
|
||||
const end = Math.min(start + CHUNK_SIZE, file.size);
|
||||
const chunk = file.slice(start, end);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('video', chunk);
|
||||
formData.append('uploadId', uploadId);
|
||||
formData.append('chunkIndex', chunkIndex.toString());
|
||||
formData.append('totalChunks', totalChunks.toString());
|
||||
formData.append('fileName', file.name);
|
||||
formData.append('fileType', file.type);
|
||||
|
||||
const response = await fetch('/api/upload-video', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Upload failed: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
const currentProgress = Math.round(((chunkIndex + 1) / totalChunks) * 100);
|
||||
setProgress(currentProgress);
|
||||
|
||||
if (chunkIndex === totalChunks - 1) {
|
||||
setVideoId(result.videoId);
|
||||
}
|
||||
|
||||
start = end;
|
||||
chunkIndex++;
|
||||
}
|
||||
|
||||
console.log('Video uploaded successfully');
|
||||
} catch (error) {
|
||||
console.error('Upload error:', error);
|
||||
alert('Upload failed');
|
||||
} finally {
|
||||
setUploading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
if (!file.type.startsWith('video/')) {
|
||||
alert('Please select a video file');
|
||||
return;
|
||||
}
|
||||
|
||||
await uploadVideoInChunks(file);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4 mb-1.5">
|
||||
<input
|
||||
type="file"
|
||||
ref={fileInputRef}
|
||||
accept="video/*"
|
||||
onChange={handleFileSelect}
|
||||
className="mb-4"
|
||||
disabled={uploading}
|
||||
/>
|
||||
|
||||
{uploading && (
|
||||
<div className="w-full bg-gray-200 rounded-full h-2.5 mb-4">
|
||||
<div
|
||||
className="bg-blue-600 h-2.5 rounded-full transition-all duration-300"
|
||||
style={{ width: `${progress}%` }}
|
||||
></div>
|
||||
<p className="text-sm text-gray-600 mt-1">Uploading: {progress}%</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{videoId && (
|
||||
<div className="mt-4 p-3 bg-green-100 border border-green-400 text-green-700 rounded">
|
||||
<p>Video uploaded successfully!</p>
|
||||
<p className="text-sm">Video ID: {videoId}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user