browsertime
Version:
Get performance metrics from your web page using Browsertime.
130 lines (118 loc) • 3.74 kB
JavaScript
import path from 'node:path';
import get from 'lodash.get';
import { getRecorder } from './screenRecording/recorder.js';
import { getVideoMetrics } from './postprocessing/visualmetrics/getVideoMetrics.js';
import { finetuneVideo } from './postprocessing/finetune/index.js';
import { rename, removeFile, removeDirAndFiles } from '../support/fileUtil.js';
import { pathToFolder } from '../support/pathToFolder.js';
/**
* Create a new Video that handles everything with the video
* @class
*/
export class Video {
constructor(storageManager, options, browser) {
this.options = options;
this.storageManager = storageManager;
this.tmpDir = storageManager.directory;
this.recorder = getRecorder(options, browser, this.tmpDir);
this.isRecording = false;
}
async setupDirs(index, url) {
const storageManager = this.storageManager;
this.index = index;
this.videoDir = await storageManager.createSubDataDir(
path.join(pathToFolder(url, this.options), 'video')
);
await storageManager.createSubDataDir(
path.join(pathToFolder(url, this.options), 'video', 'images', '' + index)
);
this.filmstripDir = await storageManager.createSubDataDir(
path.join(pathToFolder(url, this.options), 'filmstrip', '' + index)
);
}
/**
* Start recoding a video.
* @returns {Promise} Promise object that represents when the video started
*/
async record(pageNumber, index, visitedPageNumber) {
this.pageNumber = pageNumber;
this.index = index;
this.visitedPageNumber = visitedPageNumber;
// skip recording if we already have one going
if (!this.isRecording) {
this.isRecording = true;
let temporary = path.join(this.tmpDir, 'x11-tmp.mp4');
return this.recorder.start(temporary);
}
}
/**
* Stop recording the video.
* @returns {Promise} Promise object that represents when the video stopped
*/
async stop(url) {
this.isRecording = false;
if (url === undefined) {
return this.recorder.stop(this.videoPath);
} else {
this.videoPath = path.join(
this.storageManager.directory,
pathToFolder(url, this.options),
'video',
this.index + '.mp4'
);
await this.setupDirs(this.index, url);
return this.recorder.stop(this.videoPath);
}
}
async cleanup() {
// Keep or remove the original file
if (get(this.options, 'videoParams.keepOriginalVideo', false)) {
const originalFile = path.join(
this.videoDir,
this.index + '-original.mp4'
);
await rename(this.videoPath, originalFile);
} else {
await removeFile(this.videoPath);
}
// Remove all tmp videos (and screenshots)
return removeDirAndFiles(path.join(this.videoDir, 'tmp'));
}
/**
Post process video: get visual metrics, finetune the video and remove it
if you don't want it
*/
async postProcessing(timingMetrics, visualElements) {
let videoMetrics;
if (this.options.visualMetrics) {
videoMetrics = await getVideoMetrics(
this.videoDir,
this.filmstripDir,
this.videoPath,
this.index,
visualElements,
this.storageManager,
this.pageNumber,
this.visitedPageNumber,
this.options
);
}
await (this.options.video === true
? finetuneVideo(
this.videoDir,
this.videoPath,
this.index,
videoMetrics,
timingMetrics,
this.options
)
: removeFile(this.videoPath));
return videoMetrics;
}
getRecordingStartTime() {
return this.recorder.recordingStartTime;
}
getTimeToFirstFrame() {
return this.recorder.timeToFirstFrame;
}
}