sound-parade/server.js
2022-01-14 02:01:15 +09:00

238 lines
6.4 KiB
JavaScript

//dotenv
require('dotenv').config();
//ffmpeg
var ffmpeg = require('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.view("/src/pages/parade.hbs", {});
});
["/entry", "/entry/"].forEach(function(path) {
fastify.get(path, function (request, reply) {
reply.view("/src/pages/entry.hbs", {});
});
});
// --> https://stackoverflow.com/a/40899275
// all the regex doesn't work... last resort.
["/list", "/list/"].forEach(function(path) {
fastify.get(path, async function (request, reply) {
let params = {};
//
const client = new Client(server);
//files
const sourceFolder = await client.getFolder("/Storage/public/sound-parade/");
// const folderFiles = await sourceFolder.getFiles();
// for (const file of folderFiles) {
// console.log(file.name);
// }
const subFolders = await sourceFolder.getSubFolders();
for (const subFolder of subFolders) {
console.log("folder", subFolder.name);
}
// // only pdfs and jpg should be listed
// // const fileFilterFunction = (file) => {
// // // if (file.mime === "application/pdf" || file.mime === "image/jpeg") {
// // // return file;
// // // }
// // return file;
// // }
//
// const options = {
// sourceFolder,
// // filterFile: fileFilterFunction,
// };
//
// const command = new GetFilesRecursivelyCommand(client, options);
// // get files asynchronously (will not throw exceptions!)
// command.execute();
//
// // check the processing status as long as the command is running
// while (command.isFinished() !== true) {
// // wait one second
// await (async () => { return new Promise(resolve => setTimeout(resolve, 1000)) })();
// console.log(command.getPercentCompleted() + "%");
// }
//
// // use the result to do the needful
// const uploadResult = command.getResultMetaData();
//
// if (command.getStatus() === CommandStatus.success) {
// console.log(uploadResult.messages);
// for (const file of command.getFiles()) {
// console.log(file.name);
// }
// } else {
// console.log(uploadResult.errors);
// }
reply.view("/src/pages/list.hbs", params);
});
});
//'post'
fastify.post("/", 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');
// console.log(audiofile.fields.message.value);
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());
//convert to mp3
let dir = path.dirname(audiofile.filepath);
function converter() {
return new Promise((resolve,reject) => {
var process = new ffmpeg(audiofile.filepath);
process.then(function (video) {
// Callback mode
video.fnExtractSoundToMP3(dir + '/converted.mp3', function (error, file) {
if (!error) {
console.log('Audio file: ' + file);
resolve()
}
});
}, function (err) {
console.log('Error: ' + err);
});
});
}
const file = await folder.createFile(audiofile.filename, await fs.readFile(audiofile.filepath));
// const text = await folder.createFile("message.txt", Buffer.from(audiofile.fields.message.value));
// const image = await folder.createFile(pixelfile.filename, await fs.readFile(pixelfile.filepath));
// //mp3 conversion
// console.log(await fs.readdir(dir));
//
//
console.log(await fs.readdir(dir));
reply.view("/src/pages/entry.hbs", {});
});
//
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}`)
});