-
Notifications
You must be signed in to change notification settings - Fork 12
/
index.js
102 lines (85 loc) · 2.9 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
* @name Redditube
* A video generator from Reddit
* posts and comments.
*
* @copyright (C) 2020 by Charly Poirier
*/
const Reddit = require(`./libs/reddit.js`);
const Screenshot = require(`./libs/screenshot.js`);
const Voiceover = require(`./libs/voiceover.js`);
const Video = require(`./libs/video.js`);
const EventEmitter = require(`events`);
const path = require(`path`);
const fs = require(`fs`);
module.exports = new EventEmitter();
/**
* Configure authentification parameters
* for Reddit.
*
* @param {Object} configuration The configuration object
*/
module.exports.config = Reddit.config;
/**
* Make a video from a Reddit submission ID.
*
* @param {String} id ID of a Reddit submission.
* @param {Number} n Number of comments in the video.
*
* @return {Promise<String>} Path to the generated video file.
*/
module.exports.make = async function (id, n=5) {
this.emit(`start`);
// 1. Fetch the submission
this.emit(`status`, `Fetching the submission`);
const submission = Reddit.clean(await Reddit.fetch(id));
// 2. Make clips
const tmp = path.join(__dirname, `/tmp`);
if (!fs.existsSync(tmp)) fs.mkdirSync(tmp);
const clips = [];
let clip;
n = Math.min(n, submission.comments.length);
this.emit(`status`, `Generating introduction clip`);
const screenshot = await Screenshot.submission(submission);
const voiceover = await Voiceover.submission(submission);
clip = await Video.make(screenshot, voiceover);
clip = await Video.glitch(clip);
clips.push(clip);
for (let i=0; i<n; ++i) {
n = Math.min(n, submission.comments.length);
this.emit(`status`, `Generating comment clip ${i+1} out of ${n}`);
let screenshots, voiceovers;
try {
if (!submission.comments[i]) break;
screenshots = await Screenshot.comment(submission.comments[i]);
voiceovers = await Voiceover.comment(submission.comments[i]);
} catch (e) {
submission.comments.splice(i--, 1);
continue;
}
let temporary = [];
for (let j=0; j<screenshots.length; ++j) {
clip = await Video.make(screenshots[j], voiceovers[j]);
temporary.push(clip);
}
clip = await Video.smartMerge(temporary);
clip = await Video.glitch(clip);
clips.push(clip);
}
// 3. Edit the final video
this.emit(`status`, `Merging all clips`);
const video = await Video.smartMerge(clips)
this.emit(`status`, `Adding background music`);
const final_video = await Video.music(video);
this.emit(`end`);
// 4. Remove temporary files
fs.readdir(`${__dirname}/tmp`, (err, files) => {
if (err) throw err;
for (const file of files) {
fs.unlink(`${__dirname}/tmp/${file}`, err => {
if (err) throw err;
});
}
});
return final_video;
}