const { Worker } = require('bullmq'); const fs = require('fs'); const path = require('path'); const { connection } = require('./imageQueue'); const { resizeTo8K } = require('../utils/imageHelper'); const { injectGPSCoordinates } = require('../utils/exifHelper'); const Asset = require('../models/Asset'); const Scene = require('../models/Scene'); /** * Khởi tạo Worker để xử lý hàng đợi 'image-processing' */ const imageWorker = new Worker('image-processing', async (job) => { const { tempFilePath, processedFilePath, latitude, longitude, assetId, sceneId } = job.data; console.log(`[Worker] Bắt đầu xử lý Job ${job.id} cho Scene: ${sceneId}`); try { // Quy trình tối giản: Chỉ Resize ảnh sang 8K (Sharp) // Vì người dùng đã stitch ảnh từ Insta360 Studio, file upload đã là Equirectangular JPEG. await resizeTo8K(tempFilePath, processedFilePath); // 3. Chèn GPS Metadata await injectGPSCoordinates(processedFilePath, latitude, longitude); // 4. Cập nhật đường dẫn file thực tế vào Database // Lúc này ảnh đã sẵn sàng để phục vụ (8K) await Asset.findByIdAndUpdate(assetId, { filePath: processedFilePath }); await Scene.findByIdAndUpdate(sceneId, { scene_url: processedFilePath, status: 'completed' // Xử lý xong }); // 5. Dọn dẹp file tạm if (fs.existsSync(tempFilePath)) fs.unlinkSync(tempFilePath); console.log(`[Worker] Hoàn tất xử lý Job ${job.id}`); return { success: true }; } catch (error) { console.error(`[Worker Error] Job ${job.id} thất bại:`, error.message); await Scene.findByIdAndUpdate(sceneId, { status: 'failed' }); // Đánh dấu lỗi throw error; // Đẩy lỗi để BullMQ thực hiện retry } }, { connection }); imageWorker.on('completed', (job) => { console.log(`Job ${job.id} đã hoàn thành thành công.`); }); imageWorker.on('failed', (job, err) => { console.error(`Job ${job.id} thất bại sau nhiều lần thử: ${err.message}`); }); module.exports = imageWorker;