//dotenv require('dotenv').config(); //ffmpeg var ffmpeg = require('fluent-ffmpeg'); //nextcloud client const { Client, Server, GetFilesRecursivelyCommand, CommandStatus } = require("nextcloud-node-client"); const server = new Server({ basicAuth: { password: process.env.nextcloud_PASSWD, username: process.env.nextcloud_ID, }, url: process.env.nextcloud_URL, }); //built-in const path = require("path"); const fs = require('fs').promises; const util = require('util'); // const { pipeline } = require('stream'); // const pump = util.promisify(pipeline); //uuid const { v1: uuidv1, v4: uuidv4, } = require('uuid'); //moment const moment = require("moment-timezone"); //fastify const fastify = require("fastify")({ logger: false, }); fastify.register(require("fastify-static"), { root: path.join(__dirname, "public"), prefix: "/" }); fastify.register(require("fastify-formbody")); fastify.register(require("fastify-multipart")); fastify.register(require("point-of-view"), { engine: { handlebars: require("handlebars") } }); //socket.io var io = require("socket.io")(fastify.server, { pingInterval: 1000, pingTimeout: 3000 }); //get '/' fastify.get("/", function (request, reply) { // reply.get("/src/pages/parade.hbs", {}); //??? reply.view("/src/pages/parade.hbs", {}); }); //get '/entry', '/entry/' ["/entry", "/entry/"].forEach(function(item) { fastify.get(item, function (request, reply) { reply.view("/src/pages/entry.hbs", {}); }); }); // --> https://stackoverflow.com/a/40899275 // all the regex didn't work for me -- a 'last resort' method //get '/list', '/list/' ["/list", "/list/"].forEach(function(item) { fastify.get(item, async function (request, reply) { //get list const client = new Client(server); const sourceFolder = await client.getFolder("/Storage/public/sound-parade/"); const subFolders = await sourceFolder.getSubFolders(); let folders = []; for (const subFolder of subFolders) { console.log("folder", subFolder.name); folders.push(path.basename(subFolder.name)); } reply.view("/src/pages/list.hbs", { list: folders }); }); }); //get '/folders' fastify.get("/folders", async function (request, reply) { //get list const client = new Client(server); const sourceFolder = await client.getFolder("/Storage/public/sound-parade/"); const subFolders = await sourceFolder.getSubFolders(); let folders = []; for (const subFolder of subFolders) { console.log("folder", subFolder.name); folders.push(subFolder.name); } reply.send({ list: folders }); }); // //get '/folder:{foldername}' // fastify.get("/folder/:foldername", async function (request, reply) { // reply.send({ foldername: foldername }); // }); //post on '/entry' fastify.post("/entry", async function (request, reply) { // stores files to tmp dir and return paths const files = await request.saveRequestFiles(); let audiofile = files.find(f => f.fieldname == 'audiofile'); let pixelfile = files.find(f => f.fieldname == 'pixels'); let tmpdir = path.dirname(audiofile.filepath); // console.log(audiofile.fields.message.value); //convert to mp3 ? if (path.extname(audiofile.filename) !== ".mp3") { console.log("convert to mp3..."); function converter() { return new Promise((resolve, reject) => { // let outputFile = tmpdir + "/converted.mp3"; // --> https://stackoverflow.com/a/36109219 (a quick tip on fluent-ffmpeg) ffmpeg() .addInput(audiofile.filepath) .on("error", function(err) { reject(err); }) .on("end", function() { resolve(outputFile); }) .outputOptions('-b:a 192000') .output(outputFile) .run(); }); } await converter(); // console.log(await fs.readdir(tmpdir)); } //upload const client = new Client(server); //create unique folder ==> timestamp + uuid const folder = await client.createFolder("Storage/public/sound-parade/" + moment().tz('Asia/Seoul').format('YYYYMMDD-HHmmss - ') + uuidv1()); const file = await folder.createFile("audio.mp3", await fs.readFile(tmpdir + '/converted.mp3')); const text = await folder.createFile("message.txt", Buffer.from(audiofile.fields.message.value)); const image = await folder.createFile("pixels.png", await fs.readFile(pixelfile.filepath)); reply.view("/src/pages/entry.hbs", {}); //??? }); //socket.io var score = require("./public/score.json"); // //there will be 16 rooms called: "room0", "room1", ... , "room15" //if any other room is requested.. well, we will simply reject. var roommax = 16; // io.on("connection", function(socket) { console.log("someone connected."); socket.on("disconnect", function() { console.log("someone disconnected."); }); socket.on("room", function(room, fn) { // parseInt(room) if (room >= 0 && room < roommax) { socket.join("room" + room); fn(true); } else { fn(false); } }); }); // var pointer = 0; // pointer : 0 ~ (length-1) var looper; (looper = function(timeout) { setTimeout(function() { //pointer = 20; // console.log(score[pointer]); // for (var index = 0; index < roommax; index++) { // NOTE: 'pointer' must be 'remembered' since 'pointer' will increase almost immediately! pass as argument => 'pointed' // NOTE: 'index' is same => 'indexed' setTimeout(function(pointed, indexed) { io.to("room" + indexed).emit("post", score[pointed]); }, score[pointer].object.showtime * index, pointer, index); } var timegap = score[pointer].timegap.base + Math.random()*score[pointer].timegap.random; // console.log(timegap); pointer++; if (pointer >= score.length) pointer = 0; looper(timegap); }, timeout); })(1000); //listen fastify.listen(10000, function (err, address) { if (err) { fastify.log.error(err) process.exit(1) } console.log(`Your app is listening on ${address}`) fastify.log.info(`server listening on ${address}`) });