Skip to content

Instantly share code, notes, and snippets.

@GoodnessEzeokafor
Created January 10, 2025 10:23
Show Gist options
  • Save GoodnessEzeokafor/861c884ae5ee8d813a996a222e432757 to your computer and use it in GitHub Desktop.
Save GoodnessEzeokafor/861c884ae5ee8d813a996a222e432757 to your computer and use it in GitHub Desktop.
Multipart File Upload
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Upload</title>
</head>
<body>
<form action="/upload" method="POST" enctype="multipart/form-data" onsubmit="return handleFormSubmit(event)">
<label for="video-upload">Upload Video:</label>
<input type="file" id="video-upload" name="video" accept="video/*,.mkv">
<button type="submit">Upload</button>
</form>
<video controls>
<source
src="https://cirrden-web-app.lon1.cdn.digitaloceanspaces.com/videos/uploads/01a35434-82b1-44e5-bf5d-be9ad4092fdf/Sakra.2023.720p.BluRay.x264-Mkvking.mkv"
type="video/x-matroska">
Your browser does not support the video tag.
</video>
<script>
// async function uploadLargeFile(file) {
// const chunkSize = 5 * 1024 * 1024; // 5MB
// const chunks = [];
// let offset = 0;
// while (offset < file.size) {
// const chunk = file.slice(offset, offset + chunkSize);
// chunks.push(chunk);
// offset += chunkSize;
// }
// const mimeType = file.type
// // Step 1: Initiate Upload
// const initRes = await fetch('http://localhost:3421/api/v1/uploads/video/initiate', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ fileName: file.name, mimeType }),
// });
// const { uploadId } = await initRes.json();
// // Step 2: Upload Chunks
// const uploadedParts = await Promise.all(
// chunks.map(async (chunk, index) => {
// const formData = new FormData();
// formData.append('partData', chunk);
// formData.append('partNumber', index + 1);
// formData.append('uploadId', uploadId);
// formData.append('fileName', file.name);
// formData.append('mimeType', mimeType);
// const uploadRes = await fetch('http://localhost:3421/api/v1/uploads/video/part', {
// method: 'POST',
// body: formData,
// });
// const { ETag, PartNumber } = await uploadRes.json();
// return { ETag, PartNumber };
// })
// );
// // Step 3: Complete Upload
// const completeRes = await fetch('http://localhost:3421/api/v1/uploads/video/complete', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ uploadId, fileName: file.name, parts: uploadedParts, mimeType }),
// });
// const { fileUrl } = await completeRes.json();
// console.log('Uploaded file URL:', fileUrl);
// return fileUrl;
// }
// async function handleFormSubmit(event) {
// // Prevent the form from submitting immediately
// event.preventDefault();
// // You can handle the form data here, like performing validation
// const fileInput = document.getElementById("video-upload");
// const file = fileInput.files[0];
// // if (!file) {
// // alert("Please select a video file.");
// // return false;
// // }
// // Prepare the FormData object to send the file
// const formData = new FormData();
// formData.append("videos", file);
// await uploadLargeFile(file)
// // try {
// // // Send the file to the server using fetch
// // const response = await fetch("http://localhost:3421/api/v1/uploads/videos", {
// // method: "POST",
// // body: formData,
// // });
// // // Check if the request was successful
// // if (!response.ok) {
// // throw new Error("Video upload failed");
// // }
// // // Handle the server's response
// // const data = await response.json();
// // alert("Video uploaded successfully: " + data.message); // Assuming a message is returned from the server
// // } catch (error) {
// // // Handle any errors during the fetch request
// // console.error("Error uploading video:", error);
// // alert("Error uploading video: " + error.message);
// // }
// return false; // prevent form submission if handled via JavaScript
// }
async function uploadLargeFile(file) {
const chunkSize = 5 * 1024 * 1024; // 5MB
const chunks = [];
let offset = 0;
while (offset < file.size) {
const chunk = file.slice(offset, offset + chunkSize);
chunks.push(chunk);
offset += chunkSize;
}
const mimeType = file.type;
// Step 1: Initiate Upload
const initRes = await fetch('http://localhost:3421/api/v1/uploads/video/initiate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileName: file.name, mimeType }),
});
const { uploadId } = await initRes.json();
// Step 2: Upload Chunks
const uploadedParts = await Promise.all(
chunks.map(async (chunk, index) => {
const formData = new FormData();
formData.append('partData', chunk);
formData.append('partNumber', index + 1);
formData.append('uploadId', uploadId);
formData.append('fileName', file.name);
// formData.append('mimeType', mimeType);
const uploadRes = await fetch('http://localhost:3421/api/v1/uploads/video/part', {
method: 'POST',
body: formData,
});
const { ETag, PartNumber } = await uploadRes.json();
return { ETag, PartNumber };
})
);
// Step 3: Complete Upload
const completeRes = await fetch('http://localhost:3421/api/v1/uploads/video/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ uploadId, fileName: file.name, parts: uploadedParts, mimeType }),
});
const { fileUrl } = await completeRes.json();
console.log(`Uploaded file URL (${file.name}):`, fileUrl);
return fileUrl;
}
async function handleFormSubmit(event) {
// Prevent the form from submitting immediately
event.preventDefault();
// Get all selected files
const fileInput = document.getElementById("video-upload");
const files = fileInput.files;
if (!files.length) {
alert("Please select video files.");
return false;
}
// Upload each file
const uploadPromises = Array.from(files).map(file => uploadLargeFile(file));
try {
// Wait for all uploads to complete
const uploadedFiles = await Promise.all(uploadPromises);
console.log("All files uploaded successfully:", uploadedFiles);
alert("All videos uploaded successfully!");
} catch (error) {
console.error("Error uploading videos:", error);
alert("Error uploading videos: " + error.message);
}
return false; // prevent form submission if handled via JavaScript
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment