add video upload input

This commit is contained in:
smanylov
2025-12-09 18:36:40 +07:00
parent 8ca445e8c6
commit b72df032fb
4 changed files with 111 additions and 4 deletions
+3 -1
View File
@@ -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>
-2
View File
@@ -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>
);
}