Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for custom output filenames and temp files in subfolders #3

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,4 @@ Yes.
<h3>I get errors related to FFMPEG, why?</h3>
<p>Please ensure that you have FFMPEG installed on your PC</p>
<p>run from your cmd / terminal (in linux) the command: ffmpeg --help</p>
<p>If you see results, and don't see "command not found" errors, this plugin should work with your FFMPEG</p>
<p>If you see results, and don't see "command not found" errors, this plugin should work with your FFMPEG</p>
16 changes: 13 additions & 3 deletions handlers/FsHandler.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
const { appendFile, mkdir } = require('fs').promises;
const { appendFile, mkdir, rmdir } = require('fs').promises;
const { openSync, closeSync, existsSync } = require('fs');
const { join } = require('path');

class FsHandler {
async init(outputFolder) {
async init(outputFolder, name = Date.now()) {
this.outputFolder = outputFolder;
this.videoFilename = join(this.outputFolder, Date.now() + '.webm');

// do not put the video in the test subfolder, but in the root recording folder
const videofilename = `../${name}.webm`;

this.videoFilename = join(this.outputFolder, videofilename);
this.imagesPath = join(this.outputFolder, 'images');
this.imagesFilename = join(this.outputFolder, 'images.txt');
await this.verifyPathExists(this.outputFolder);
await this.verifyPathExists(this.imagesPath);
await this.verifyPathExists(this.imagesFilename, 'file');
}

async clearOutputSubFolder() {
if (await existsSync(this.outputFolder)) {
await rmdir(this.outputFolder, { recursive: true });
}
}

createEmptyFile(filename) {
return closeSync(openSync(filename, 'w'));
}
Expand Down
51 changes: 38 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,45 @@ class PuppeteerVideoRecorder {
this.fsHandler = new FsHandler();
}

async init(page, outputFolder){
async init(page, outputFolder, name = Date.now()){
this.page = page;
this.outputFolder = outputFolder;
await this.fsHandler.init(outputFolder);
const { imagesPath,imagesFilename, appendToFile } = this.fsHandler;
this.testName = name;

// append sub-folder name to output folder to form the full output folder name
this.fullOutputFolder = `${this.outputFolder.replace(/\/$/, "")}/${this.testName.replace(/ /gi, '_').toLowerCase()}/`;

await this.fsHandler.init(this.fullOutputFolder, this.testName);

const { imagesPath, imagesFilename, appendToFile } = this.fsHandler;

await this.screenshots.init(page, imagesPath, {
afterWritingImageFile: (filename) => appendToFile(imagesFilename, `file '${filename}'\n`)
// strip the full output foldername from the filename to prevent FFMPEG throwing errors
afterWritingImageFile: (filename) => {
appendToFile(imagesFilename, `file 'images${filename.split(imagesPath)[1]}'\n`)
}
});
}
}

// start recording images
start(options = {}) {
return this.screenshots.start(options);
}


// stop recording and save images as videofile
async stop () {
await this.screenshots.stop();
return this.createVideo();
await this.createVideo();
}

// clear the subfolder with images
async clear () {
await this.fsHandler.clearOutputSubFolder();
}

// stop recording, do not save a video
async cancel () {
await this.screenshots.stop();
}

get defaultFFMpegCommand() {
Expand All @@ -35,17 +57,20 @@ class PuppeteerVideoRecorder {
'-safe 0',
`-i ${imagesFilename}`,
'-framerate 60',
videoFilename
`"${videoFilename}"`
].join(' ');
}

createVideo(ffmpegCommand = '') {
const _ffmpegCommand = ffmpegCommand || this.defaultFFMpegCommand;
exec(_ffmpegCommand, (error, stdout, stderr) => {
if (error) throw new Error(error);
console.log(stdout);
console.log(stderr);
});

return new Promise((resolve, reject) => {
exec(_ffmpegCommand, (error) => {
if (error) reject(error);

resolve();
});
});
}
}

Expand Down