forked from dra-ft/supercut-x-padma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
127 lines (99 loc) · 3.33 KB
/
server.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const express = require('express')
const cors = require('cors')
const fs = require('fs')
const ffmpeg = require('fluent-ffmpeg')
const childProcess = require('child_process')
const { deleteFile } = require('./functions')
const { v1: uuidv1, v4: uuidv4 } = require('uuid')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// TODO : enable for only frontend
app.use(cors())
const port = process.env.PORT || 3001
app.get('/', (req, res) => {
res.send('supercut x padma')
})
app.get('/partVideo', (req, res) => {
const url = req.query.url
const startTime = req.query.in
const duration = req.query.duration
try {
res.status(206)
res.set('Content-Type', 'video/mp4')
ffmpeg(url)
.seekInput(startTime)
.duration(duration)
.format('webm')
.on('stderr', function(stderrLine) {
console.log('Stderr output: ' + stderrLine);
})
.on('error', function(err, stdout, stderr) {
console.log('Cannot process video: ' + err.message);
})
.pipe(res, {end: true})
} catch(error) {
console.log(error)
}
})
app.post('/supercut', (req, res) => {
try {
const body = req.body
const id = uuidv4()
const outputFile = `${process.cwd()}/${id}.mp4`;
const w = 640
const h = 480
const inputs = []
const filter1 = []
const filter2 = []
for(let i = 0; i < body.cuts.length; i++) {
const v = body.cuts[i]
const vinput = ['-ss', v.ss, '-t', v.duration, '-i', v.url]
inputs.push(...vinput)
filter1.push(`[${i}:v]scale=${w}:${h}:force_original_aspect_ratio=decrease,pad=${w}:${h}:-1:-1,setsar=1[v${i}];`)
filter2.push(`[v${i}][${i}:a]`)
}
const filterComplex1 = filter1.join(' ')
const filterComplex2 = filter2.join('')
const filterComplex3 = `concat=n=${body.cuts.length}:v=1:a=1[v][a]`
const streamMapping = ['-map', '[v]', '-map', '[a]']
// removing '-fps_mode', 'vfr' to check if it works without variable framerate
const filterComplex = ['-filter_complex', `${filterComplex1} ${filterComplex2}${filterComplex3}`]
inputs.push(...filterComplex)
inputs.push(...streamMapping)
inputs.push(`${outputFile}`)
console.log(`ffmpeg command: ${inputs.join(' ')}`)
console.log(inputs)
const child = childProcess.spawn('ffmpeg', inputs)
child.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
child.on('close', (code, signal) => {
console.log(`Process exited with code: ${code} ${signal}`);
if (code === 0) {
console.log(`FFmpeg finished successfully`);
// res.status(206)
res.set('Content-Type', 'video/mp4')
fs.createReadStream(outputFile)
.pipe(res, {end: true})
.on('error', (error) => {
console.log(`FS error: ${error}`)
})
.on('finish', () => {
console.log(`deleting file: ${outputFile}`)
deleteFile(outputFile)
})
} else {
console.log(`FFmpeg encountered an error, check the console output`);
}
});
} catch(err) {
console.log(err)
}
})
app.listen(port, () => {
console.log(`Server listening on port ${port}`)
})