Skip to content

Parse individual jpegs from an ffmpeg pipe when output codec(-c:v) is set to mjpeg and format(-f) is set to image2pipe, singlejpeg, mjpeg, or mpjeg.

License

Notifications You must be signed in to change notification settings

kevinGodell/pipe2jpeg

Repository files navigation

pipe2jpeg

Buy me a coffee Donate via PayPal build Build status GitHub issues GitHub license npm

Parse individual jpegs from an FFmpeg pipe when the output codec(-c:v) is set to mjpeg and the format(-f) is set to image2pipe, singlejpeg, mjpeg, or mpjpeg.

installation:

npm install pipe2jpeg --save

usage:

The following example uses ffmpeg's testsrc to simulate a video input and generate 100 downscaled jpeg images at a rate of 1 per second. The jpeg images are piped in from ffmpeg's stdout and parsed for the start of image(SOI) and end of image(EOI) file markers. Using the default configuration, Pipe2Jpeg dispatches a "data" event that contains a complete jpeg image buffer. For more configuration options, view the docs.

const Pipe2Jpeg = require('pipe2jpeg');

const { spawn } = require('child_process');

let jpegCounter = 0;

const params = [
  /* log info to console */
  '-loglevel',
  'quiet',

  /* use an artificial video input */
  '-re',
  '-f',
  'lavfi',
  '-i',
  'testsrc=size=1920x1080:rate=15',

  /* set output flags */
  '-an',
  '-c:v',
  'mjpeg',
  '-pix_fmt',
  'yuvj420p',
  '-f',
  'image2pipe', // image2pipe, singlejpeg, mjpeg, or mpjpeg
  '-vf',
  'fps=1,scale=640:360',
  '-q',
  '2',
  '-frames',
  '100',
  'pipe:1'
];

const p2j = new Pipe2Jpeg();

p2j.on('data', (jpeg) => {
  console.log('received jpeg', ++jpegCounter);
});

const ffmpeg = spawn('ffmpeg', params, {stdio : ['ignore', 'pipe', 'ignore']});

ffmpeg.on('error', (error) => {
  console.log(error);
});

ffmpeg.on('exit', (code, signal) => {
  console.log('exit', code, signal);
});

ffmpeg.stdout.pipe(p2j);

Setting readableObjectMode to true will cause the output to be an object containing list and totalLength properties:

const p2j = new Pipe2Jpeg({ readableObjectMode: true /* default false */ });

p2j.on('data', ({ list, totalLength }) => {
  // list is array of buffers comprising the jpeg
  console.log(Array.isArray(list), Buffer.isBuffer(list[0]));
  // totalLength is cumulative size of buffers in list
  console.log(Number.isInteger(totalLength));
  // list of buffers can be concatenated as needed
  const jpeg = Buffer.concat(list, totalLength);
});

// the list property will be set with the latest value
const list = p2j.list;

While readableObjectMode is set to true, bufferConcat can be set to true to cause the list of buffers to be concatenated into a single buffer:

const p2j = new Pipe2Jpeg({ readableObjectMode: true /* default false */, bufferConcat: true /* default false */ });

p2j.on('data', ({ jpeg }) => {
  // jpeg is complete as a single buffer
  console.log(Buffer.isBuffer(jpeg));
});

// the jpeg property will be set with the latest value
const jpeg = p2j.jpeg;

If you have consistently sized jpegs, then setting byteOffset to a number approximately 75% of the expected size can minimize the time searching for EOI and result in a small performance gain:

const p2j = new Pipe2Jpeg({ byteOffset: 10000 /* default 200 */ });

While readableObjectMode is set to false or bufferConcat is set to true, an experimental buffer pool can be used to reduce garbage collection and increase performance:

const p2j = new Pipe2Jpeg({ pool: 1 /* default 0 */ });

testing:

Clone the repository

git clone https://github.com/kevinGodell/pipe2jpeg.git

Change into the directory

cd pipe2jpeg

Initialize with npm

npm install

Start the tests

npm test

About

Parse individual jpegs from an ffmpeg pipe when output codec(-c:v) is set to mjpeg and format(-f) is set to image2pipe, singlejpeg, mjpeg, or mpjeg.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published