Created
January 10, 2025 10:23
-
-
Save GoodnessEzeokafor/861c884ae5ee8d813a996a222e432757 to your computer and use it in GitHub Desktop.
Multipart File Upload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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