/
parameters.js
156 lines (146 loc) · 4.89 KB
/
parameters.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const Applause = require('applause')
const _ = require('lodash')
const fs = require('fs-extra')
const path = require('path')
const findUp = require('find-up')
const sanitize = require('sanitize-filename')
const sanitizeREGEX = /[._\- ()]*/g
function getInputFilePath (parameters) {
const index = parameters.findIndex(item => item === '-i')
const value = parameters[index + 1]
if (value[0] === '-') return
return value
}
function stringReplace (context, parameters) {
const replacer = Applause.create({ patterns: [ { json: context } ] })
const isArray = Array.isArray(parameters)
const arr = (!isArray ? [parameters] : parameters)
const replaced = arr.map(parameter => {
if (typeof parameter !== 'string') return parameter
const replaced = replacer.replace(parameter).content
return replaced === false
? parameter
: replaced
})
return (!isArray ? replaced[0] : replaced)
}
function reduceParameters (parameters, outputGroupNames, context) {
context = Object.assign({}, context)
let hasResolvedObjects = true
function perform (parameters) {
hasResolvedObjects = false
parameters = parameters.reduce((parameters, option) => {
if (typeof option === 'object') {
hasResolvedObjects = true
const namedParameters = Object
.entries(option)
.filter(([name]) => !outputGroupNames || !outputGroupNames.length || outputGroupNames.includes(name))
.map(([name, value]) => {
// NOTE: This should process nested group names better, only first group comes out currently
context.outputGroupName = name
return stringReplace(context, value)
})
parameters.push(...namedParameters)
return parameters
}
context.outputGroupName = ''
option = stringReplace(context, option)
parameters.push(option)
return parameters
}, [])
return _.flatten(parameters)
}
while (hasResolvedObjects) {
parameters = perform(parameters)
}
return parameters
}
function getGroupNames (parameters) {
const names = parameters.reduce((names, value) => {
if (typeof value !== 'object') return names
const keys = Object.keys(value)
names.push(...keys)
keys.forEach(key => names.push(...getGroupNames(value[key])))
return names
}, [])
return names
}
function getConfig () {
const config = fs.readJsonSync(findUp.sync('.reencoderrc.json'))
return config
}
function getTerminalOutputGroupNames (config) {
const configNames = getGroupNames(config.parameters)
let outputGroupNames = process.argv.filter(name => configNames.includes(name))
outputGroupNames = outputGroupNames.length
? outputGroupNames
: (config.default ?? '').split(/ |,/g)
return outputGroupNames
}
async function getFfmpegParameters (inputDir, inputFile, outputDir, config, outputGroupNames) {
const inputFileParsed = path.parse(inputFile)
// Make sure inputFile is absolute in parameters
inputFile = path.resolve(inputDir, inputFile)
const sanitized = sanitize(inputFileParsed.name).replace(sanitizeREGEX, '')
const parameters = reduceParameters(config.parameters, outputGroupNames, {
inputFile,
inputFileBase: inputFileParsed.base,
// Relative to inputDir unless otherwise specified
inputFileDir: inputFileParsed.dir,
inputFileExt: inputFileParsed.ext,
inputFileName: inputFileParsed.name,
inputFileNameSanitized: sanitized,
inputFileNameSanitizedLowerCase: sanitized.toLowerCase(),
inputFileRoot: inputFileParsed.root,
outputDir,
outputGroupName: ''
})
// Replace input glob with absolute filename
const inputFileIndex = parameters.findIndex(param => param === '-i')
parameters[inputFileIndex + 1] = inputFile
// Make sure to silently not overwrite
const overwriteIndex = parameters.findIndex(param => param === '-y')
if (overwriteIndex === -1) {
parameters.unshift('-n')
}
return parameters
}
function getOutputFilePaths (parameters, propertyName = null) {
let skip = false
let isCaptureNext = false
const outputs = parameters.reduce((outputs, item) => {
const isFlag = (item[0] === '-')
if (isCaptureNext) {
isCaptureNext = false
skip = false
outputs.push(item)
return outputs
}
isCaptureNext = (isFlag && item === propertyName)
if (skip && !isFlag) {
skip = false
return outputs
}
if (isFlag) {
skip = true
return outputs
}
outputs.push(item)
return outputs
}, [])
return outputs
}
async function ensureOutputFilePaths (parameters, parameterName = null) {
const outputFilePaths = getOutputFilePaths(parameters, parameterName)
const fileDirs = outputFilePaths.map(filePath => path.parse(filePath).dir)
await Promise.all(fileDirs.map(fileDir => fs.ensureDir(fileDir)))
return fileDirs
}
module.exports = {
stringReplace,
getInputFilePath,
getConfig,
getTerminalOutputGroupNames,
getFfmpegParameters,
ensureOutputFilePaths
}