kz_educa/functions/index.js

96 lines
3.0 KiB
JavaScript
Executable File

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;
}
});