const functions = require("firebase-functions"); const admin = require("firebase-admin"); const {Storage} = require("@google-cloud/storage"); const ffmpeg = require("fluent-ffmpeg"); const ffmpegStatic = require("ffmpeg-static"); const fs = require("fs-extra"); const path = require("path"); const ytdl = require("ytdl-core"); admin.initializeApp(); const gcs = new Storage(); const bucketName = admin.storage().bucket().name; ffmpeg.setFfmpegPath(ffmpegStatic); exports.processVideo = functions.firestore .document("lessons/{lessonId}") .onUpdate(async (change, context) => { const {videoUrl, processedUrl, processing} = change.after.data(); const {lessonId} = context.params; if (!videoUrl || processedUrl || processing) { return null; } await change.after.ref.update({ processing: true, processedUrl: null, }); try { const tempLocalPath = path.join("/tmp", `${lessonId}-original.mp4`); const convertedPath = path.join("/tmp", `${lessonId}-converted.mp4`); functions.logger.log(`Baixando vídeo de: ${videoUrl}`); const videoStream = ytdl(videoUrl, {quality: "highestvideo"}); await new Promise((resolve, reject) => { videoStream.pipe(fs.createWriteStream(tempLocalPath)); videoStream.on("end", resolve); videoStream.on("error", reject); }); functions.logger.log("Vídeo baixado com sucesso."); functions.logger.log( "Iniciando a conversão para 720p..."); await new Promise((resolve, reject) => { ffmpeg(tempLocalPath) .videoCodec("libx264") .audioCodec("aac") .size("1280x720") .on("end", resolve) .on("error", reject) .save(convertedPath); }); functions.logger.log("Conversão concluída."); const storageFilePath = `videos/${lessonId}-converted.mp4`; await gcs.bucket(bucketName).upload(convertedPath, { destination: storageFilePath, metadata: { contentType: "video/mp4", metadata: { firebaseStorageDownloadTokens: lessonId, }, }, }); functions.logger.log("Upload para o Storage concluído."); const [url] = await gcs.bucket(bucketName) .file(storageFilePath) .getSignedUrl({ action: "read", expires: "03-09-2491", }); await change.after.ref.update({ processedUrl: url, processing: false, }); functions.logger.log("Firestore atualizado com o novo URL."); fs.removeSync(tempLocalPath); fs.removeSync(convertedPath); return null; } catch (error) { functions.logger.error("Erro no processamento do vídeo:", error); await change.after.ref.update({ processing: false, processingError: true, }); return null; } });