@calipsa/video-utils
Version:
Video utilities
61 lines • 2.77 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fluent_ffmpeg_1 = __importDefault(require("fluent-ffmpeg"));
const stream_utils_1 = require("@calipsa/stream-utils");
const getFrameAt_1 = __importDefault(require("../getFrameAt"));
const getFrameIndices_1 = __importDefault(require("./getFrameIndices"));
exports.default = async ({ path, numFrames, videoMetadata, ffmpegCommandOptions, configureFfmpeg, }) => {
const videoStreamMetaData = videoMetadata.streams.find(item => item.codec_type === 'video');
if (!videoStreamMetaData) {
throw new Error('No video streams found');
}
const { nb_frames: numInputFramesStr, start_time: startTime = 0, duration: durationStr, } = videoStreamMetaData;
const duration = durationStr === undefined ? undefined : +durationStr;
if (!duration || !Number.isFinite(duration)) {
throw new TypeError(`ffprobe returned invalid duration: ${durationStr}`);
}
if (numFrames === 1) {
const frame = await (0, getFrameAt_1.default)({
path,
time: startTime + duration / 2,
ffmpegCommandOptions,
configureFfmpeg,
});
return [frame];
}
const numInputFrames = numInputFramesStr === undefined ? undefined : +numInputFramesStr;
if (!numInputFrames || !Number.isFinite(numInputFrames)) {
throw new TypeError(`ffprobe returned invalid nb_frames: ${numInputFramesStr}`);
}
const frameIndices = (0, getFrameIndices_1.default)(numInputFrames, numFrames);
const filterSelect = frameIndices.map(i => `eq(n\\,${i})`).join('+');
const outStream = new stream_utils_1.StreamWithFrames();
const vcodec = 'mjpeg';
return new Promise((resolve, reject) => {
const proc = (0, fluent_ffmpeg_1.default)(path, ffmpegCommandOptions)
.output(outStream, {
end: true,
})
.noAudio()
// .setStartTime(startTime)
.format('image2pipe') // -f
.videoCodec(vcodec) // -vcodec
.size('640x480')
// .fpsOutput(numFrames / duration)
// .videoFilter(`fps=${numFrames / duration}`)
// .outputOption('-filter:v', `fps=${numFrames / duration}`)
.videoFilter(`select='${filterSelect}'`)
.outputOption('-vsync', 'vfr') // make the above work
.outputOption('-q:v', '2')
.on('error', reject)
.on('end', () => {
resolve(outStream.buffers);
});
configureFfmpeg?.(proc);
proc.run();
});
};
//# sourceMappingURL=index.js.map