Skip to content

Instantly share code, notes, and snippets.

@Townsheriff
Last active September 3, 2020 13:33
Show Gist options
  • Select an option

  • Save Townsheriff/77fcfdc22a51e26d954d0392dd5eb3d6 to your computer and use it in GitHub Desktop.

Select an option

Save Townsheriff/77fcfdc22a51e26d954d0392dd5eb3d6 to your computer and use it in GitHub Desktop.
FFmpeg testing matrix with CSV summaries
const maxRates = [5000, 10000, 15000, 20000];
const cq = [15, 16, 17, 18, 19, 20];
const bFrames = [-1, 1, 2, 3, 4, 10, 20];
const gop = [25];
const videoDuration = [30];
const codec = 'hevc_nvenc';
const decklinkCardName = 'DeckLink Quad HDMI Recorder (1)';
const decklinkInput = 'hdmi';
const ps = require('child_process');
const fs = require('fs');
const crypto = require('crypto');
const md5 = (text) => crypto.createHash('md5').update(text).digest("hex")
const runID = Date.now() + '-' + md5(
JSON.stringify(maxRates) +
JSON.stringify(cq) +
JSON.stringify(bFrames) +
JSON.stringify(gop) +
JSON.stringify(videoDuration) +
codec +
decklinkCardName +
decklinkInput
) + '.csv';
const appendRow = (...args) => {
fs.appendFileSync(runID, args.join(', ') + '\n')
}
const genMatrix = (...arrays) => {
if (arrays.length === 1) {
return arrays[0].map(el => [el]);
}
const [rhs, ...otherArrays] = arrays;
const matrix = genMatrix(...otherArrays);
const newMatrix = [];
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < rhs.length; j++) {
newMatrix[i * rhs.length + j] = [rhs[j], ...matrix[i]]
}
}
return newMatrix;
}
const genFileName = ([videoDuration, maxRate, cq, bFrames, gop]) => {
return `codec-${codec}-maxrate-${maxRate}-cq-${cq}-init_qpB-${bFrames}-g-${gop}-t-${videoDuration}.mp4`;
}
const genCommand = (options) => {
const [videoDuration, maxRate, cq, bFrames, gop] = options;
const fileName = genFileName(options);
return `ffmpeg -video_input '${decklinkInput}' -f decklink -i '${decklinkCardName}' -g ${gop} -c:a libfdk_aac -c:v ${codec} -preset slow -tune hq -rc:v vbr_hq -2pass 1 -s 3840x2160 -maxrate:v ${maxRate}k -cq ${cq} -init_qpB ${bFrames} -b:v ${maxRate} -bufsize ${maxRate * 2} -b_ref_mode 2 -temporal_aq 1 -rc-lookahead 1 -vsync 0 -t ${videoDuration} '${fileName}' -y`;
}
const testMatrix = genMatrix(videoDuration, maxRates, cq, bFrames, gop);
const runCommand = (options) => {
const command = genCommand(options);
const fileName = genFileName(options);
if (fs.existsSync(fileName)) {
console.log(`skipping - ${fileName} file already exist`);
return;
}
console.log(`${command}`);
ps.execSync(command, {
shell: true,
});
const stats = fs.statSync(fileName)
const fileSizeInBytes = stats["size"]
const fileSizeInMegabytes = fileSizeInBytes / 1000000.0
appendRow(...options, fileName, fileSizeInMegabytes, command)
}
for (let i = 0; i < testMatrix.length; i++) {
console.log(`Start: ${i + 1}/${testMatrix.length}`);
runCommand(testMatrix[i]);
console.log(`Finish: ${i + 1}/${testMatrix.length}`);
console.log(`--------------------------------------`);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment