96 lines
3.0 KiB
JavaScript
Executable File
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;
|
|
}
|
|
});
|