UNPKG

framo

Version:

Glorious media processing right in your browser with Typescript support

127 lines 5.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FrameExtractorService = void 0; const tslib_1 = require("tslib"); const utility_1 = require("../utility/utility"); const ffmpeg_service_1 = require("./ffmpeg.service"); const outputFilePrefix = "out"; const outputFileDigits = 6; class FrameExtractorService { constructor() { this.ffmpegService = ffmpeg_service_1.FfmpegService.getInstance(); this.extractFrames = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { try { const fileBlob = yield this.ffmpegService.fetchFile(config.filename, config.file); const { parameters, outputFilenames } = yield this.getParameters(config, fileBlob); yield this.ffmpegService.ffmpeg.run(...parameters); const blobs = outputFilenames.map((filename) => { const data = this.ffmpegService.ffmpeg.FS("readFile", filename); return new Blob([data.buffer]); }); return blobs; } catch (error) { throw new Error(error); } }); } static getInstance() { if (!FrameExtractorService.instance) { FrameExtractorService.instance = new FrameExtractorService(); } return FrameExtractorService.instance; } getParameters(config, fileBlob) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const auxillaryParameters = ["-y"]; let parametersResponse = { parameters: [], outputFilenames: [], }; if (config.timePoints) { parametersResponse = this.getTimeBasedParameters(config); } else if (config.timeInterval) { parametersResponse = yield this.getIntervalBasedParameters(config, fileBlob); } const response = { parameters: [...parametersResponse.parameters, ...auxillaryParameters], outputFilenames: parametersResponse.outputFilenames, }; return response; }); } getTimeBasedParameters(config) { var _a; const inParameters = []; const outParameters = []; const outputFilenames = []; const scale = config.resolution ? utility_1.Utility.getScale(config.resolution) : ''; (_a = config.timePoints) === null || _a === void 0 ? void 0 : _a.forEach((timePoint, index) => { inParameters.push(...this.getSingleTimeBasedParameter(timePoint, config.filename)); const outputFilename = utility_1.Utility.getOutputFilename(index, config.outputExtension); outputFilenames.push(outputFilename); outParameters.push(...this.getOutputMappingParameter(index, outputFilename, scale)); }); const response = { parameters: [...inParameters, ...outParameters], outputFilenames, }; return response; } getSingleTimeBasedParameter(time, filename) { return ["-ss", `${time}`, "-i", filename]; } getOutputMappingParameter(index, outputFilename, scale) { const outputMapping = ["-map", `${index}:v`, "-frames:v", "1"]; if (scale) { outputMapping.push(...['-vf', scale]); } outputMapping.push(outputFilename); return outputMapping; } getIntervalBasedParameters(config, fileBlob) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const mediainfo = yield this.ffmpegService.getMediaInfo(fileBlob); const videoDuration = utility_1.Utility.getVideoDuration(mediainfo); const frameCount = utility_1.Utility.getFrameCount(mediainfo); console.log(frameCount); const interval = config.timeInterval; const rate = (1 / (interval !== null && interval !== void 0 ? interval : 1)).toFixed(2); const scale = config.resolution ? utility_1.Utility.getScale(config.resolution) : ''; const inParameters = this.getInParametersForIntervalBasedExtraction(config.filename, rate, scale); const outParameters = [`out_%0${outputFileDigits}d.${config.outputExtension}`]; const outputFilenames = []; for (let i = interval, j = 1; i <= videoDuration; i += interval, j++) { const outputFilename = utility_1.Utility.getFilenameWithPadding(j, 'out', outputFileDigits, config.outputExtension); outputFilenames.push(outputFilename); } const response = { parameters: [...inParameters, ...outParameters], outputFilenames, }; return response; }); } getOutputFilenamesForIntervalBasedParameters(interval, videoDuration, extension) { const filenames = []; const numberOfFrames = videoDuration / interval; for (let i = 1; i <= numberOfFrames; i++) { const filenumber = i.toString().padStart(outputFileDigits, "0"); filenames.push(`${outputFilePrefix}_${filenumber}.${extension}`); } return filenames; } getInParametersForIntervalBasedExtraction(filename, rate, scale) { const inParameters = ['-i', filename, '-vf']; if (scale) { inParameters.push(`fps=${rate},${scale}`); } else { inParameters.push(`fps=${rate}`); } return inParameters; } } exports.FrameExtractorService = FrameExtractorService; //# sourceMappingURL=frame-extractor.service.js.map