Skip to content

Commit

Permalink
feat: Add FFmpegUtil captureVideoFrame function.
Browse files Browse the repository at this point in the history
  • Loading branch information
drawcall committed Mar 26, 2024
1 parent 971688c commit 89fbfec
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v7.3.5
* Add FFmpegUtil captureVideoFrame function.
* Add FFmpegUtil convertVideoToGif function.

## v7.0.1
* Add support for output transparent video.
* Add scene time detection function.
Expand Down
26 changes: 22 additions & 4 deletions examples/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
FFScene,
FFImage,
FFCreator,
FFmpegUtil,
} = require('../');

const createFFTask = () => {
Expand Down Expand Up @@ -194,10 +195,27 @@ of FFText`,
});

creator.on('complete', e => {
console.log(
colors.magenta(`FFCreator completed: \n USEAGE: ${e.useage} \n PATH: ${e.output} `),
);
console.log(colors.green(`\n --- You can press the s key or the w key to restart! --- \n`));
setTimeout(async () => {
await FFmpegUtil.captureVideoFrame({
input: e.output,
output: `${outputDir}face.jpg`,
frame: 5,
});
console.log(colors.green(`\n --- Screenshot: ${outputDir}face.jpg --- \n`));

await FFmpegUtil.convertVideoToGif({
input: e.output,
output: `${outputDir}video.gif`,
fps: 15,
width: 200,
});
console.log(colors.green(`\n --- gif: ${outputDir}video.gif --- \n`));

console.log(
colors.magenta(`FFCreator completed: \n USEAGE: ${e.useage} \n PATH: ${e.output} `),
);
console.log(colors.green(`\n --- You can press the s key or the w key to restart! --- \n`));
}, 100);
});

return creator;
Expand Down
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const FFVideoAlbum = require('./node/videos');
const FFAudio = require('./audio/audio');
const FFTween = require('./animate/tween');
const FFLogger = require('./utils/logger');
const FFmpegUtil = require('./utils/ffmpeg');
const FFCreatorCenter = require('./center/center');

module.exports = {
Expand All @@ -51,5 +52,6 @@ module.exports = {
FFVideoAlbum,
FFTween,
FFLogger,
FFmpegUtil,
FFCreatorCenter,
};
37 changes: 36 additions & 1 deletion lib/utils/ffmpeg.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
*
* @object
*/
const path = require('path');
const siz = require('siz');
const Utils = require('./utils');
const isArray = require('lodash/isArray');
const forEach = require('lodash/forEach');
const ffmpeg = require('fluent-ffmpeg');
Expand Down Expand Up @@ -40,7 +42,7 @@ const FFmpegUtil = {
* Set the installation path of the current server ffprobe.
* If not set, the ffprobe command of command will be found by default.
* Environment variable FFPROBE_PATH is used in ffmpeg-probe.
*
*
* @param {string} path - installation path of the current server ffprobe
* @public
*/
Expand Down Expand Up @@ -124,6 +126,39 @@ const FFmpegUtil = {
});
},

captureVideoFrame({ input, output, time = '00:00:00.000' }) {
return new Promise((resolve, reject) => {
const directory = path.dirname(output);
const filename = path.basename(output) || `${Utils.genUuid()}.jpg`;
const fullfilepath = path.join(directory, filename);

ffmpeg(input)
.screenshots({ count: 1, timemarks: [time], filename: filename }, directory)
.on('end', () => {
resolve(fullfilepath);
})
.on('error', error => {
reject(new Error(`Error taking screenshot: ${error.message}`));
});
});
},

convertVideoToGif({ input, output, fps = 12, width = 360 }) {
return new Promise((resolve, reject) => {
ffmpeg(input)
.output(output)
.videoFilters([`fps=${fps}`, `scale=${width}:-1`])
.outputOptions('-loop 0')
.on('end', () => {
resolve(output);
})
.on('error', error => {
reject(new Error(`Error taking Gif: ${error.message}`));
})
.run();
});
},

concatOpts(opts, arr) {
if (isArray(arr)) {
forEach(arr, o => opts.push(o));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ffcreator",
"version": "7.3.1",
"version": "7.3.5",
"description": "FFCreator is a lightweight and flexible short video production library",
"main": "lib/index.js",
"types": "types/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/// <reference path="./lib/FFChart.d.ts" />
/// <reference path="./lib/FFRect.d.ts" />
/// <reference path="./lib/FFExtras.d.ts" />
/// <reference path="./lib/FFmpegUtil.d.ts" />
/// <reference path="./lib/FFLogger.d.ts" />
/// <reference path="./lib/FFTween.d.ts" />
/// <reference path="./lib/FFCreatorCenter.d.ts" />
Expand Down
29 changes: 29 additions & 0 deletions types/lib/FFmpegUtil.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// FFmpegUtil.d.ts

declare namespace FFCreatorSpace {
interface FFmpegUtil {
getFFmpeg(): any;

setFFmpegPath(path: string): void;

setFFprobePath(path: string): void;

createCommand(conf?: { threads?: number }): any;

interceptVideo(options: { video: string; ss: string; to: string; output: string }): void;
captureVideoFrame(options: { input: string; output: string; frame?: number }): Promise<string>;

convertVideoToGif(options: {
input: string;
output: string;
fps?: number;
width?: number;
}): Promise<string>;

concatOpts(opts: any[], arr: any[] | any): void;

destroy(command: any): void;
}

const FFmpegUtil: FFmpegUtil;
}

0 comments on commit 89fbfec

Please sign in to comment.