No title

 

Updated Code:

javascript
const multer = require('multer'); const path = require('path'); const fs = require('fs-extra'); const { bucket } = require('./firebaseConfig'); // Import the Firebase Storage bucket // Multer storage for handling chunk uploads in memory (since we won't store them locally) const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); router.post('/upload-video', Authorization.authorized, upload.single('video'), Product.uploadVideo); class Product { async uploadVideo(req, res) { try { const { title, description, course, is_free, instructorId, chunkNumber, totalChunks } = req.body; if (!title || !description || !course || !instructorId || !totalChunks) { return res.status(400).json({ errors: [{ msg: 'Missing required fields' }] }); } const instructor = await Instructor.findById(instructorId); if (!instructor) { return res.status(400).json({ errors: [{ msg: 'Instructor not found' }] }); } const selectedCourse = await ProductModel.findById(course); if (!selectedCourse || selectedCourse.instructor_id.toString() !== instructorId) { return res.status(400).json({ errors: [{ msg: 'Invalid course selection' }] }); } if (!req.file) { return res.status(400).json({ errors: [{ msg: 'No video file uploaded' }] }); } const chunkFileName = `${instructorId}-${course}-${chunkNumber}-${Date.now()}`; // Upload chunk to Firebase Storage const chunkFile = bucket.file(`chunks/${chunkFileName}`); await chunkFile.save(req.file.buffer, { contentType: req.file.mimetype, }); // Check if all chunks have been uploaded const [files] = await bucket.getFiles({ prefix: `chunks/${instructorId}-${course}-` }); const sortedChunks = files.sort((a, b) => parseInt(a.name.split('-').pop()) - parseInt(b.name.split('-').pop())); if (sortedChunks.length === parseInt(totalChunks)) { // Assemble the video from the chunks const finalFileName = `${instructorId}-${course}-${Date.now()}.mp4`; const finalFile = bucket.file(`videos/${finalFileName}`); const writeStream = finalFile.createWriteStream({ contentType: 'video/mp4' }); for (const file of sortedChunks) { const [chunkBuffer] = await file.download(); writeStream.write(chunkBuffer); } writeStream.end(); writeStream.on('finish', async () => { // Clean up chunk files from Firebase Storage for (const file of sortedChunks) { await file.delete(); } // Save video info to the database const video = new Video({ title, description, course: selectedCourse._id, instructor: instructor._id, is_free: is_free === 'true' || is_free === true, video_url: await finalFile.getSignedUrl({ action: 'read', expires: '03-09-2491', // Set expiration as needed }), }); const savedVideo = await video.save(); // Update ProductModel with new video information selectedCourse.video_list.push(savedVideo._id); selectedCourse.video_count += 1; if (is_free === 'true') { selectedCourse.free_video_count += 1; } await selectedCourse.save(); return res.status(201).json({ msg: 'Video uploaded successfully', video: savedVideo }); }); writeStream.on('error', (err) => { console.error('Error writing final video:', err); res.status(500).json({ errors: [{ msg: 'Error assembling video' }] }); }); } else { return res.status(200).json({ msg: 'Chunk uploaded successfully, waiting for more chunks to complete the video' }); } } catch (error) { console.error('Video upload error:', error); return res.status(500).json({ errors: [{ msg: 'Internal server error' }] }); } } } module.exports = new Product();

Explanation:

Post a Comment (0)
Previous Post Next Post