fluent-ffmpeg / node-fluent-ffmpeg

A fluent API to FFMPEG (http://www.ffmpeg.org)
MIT License
7.64k stars 874 forks source link

Get buffer after ffmpeg finished it's work #1139

Open ShevKG opened 2 years ago

ShevKG commented 2 years ago

Hello, i am trying to get buffer after ffmpeg convert my audio contained in a writable buffer which i gave to ffmpeg constructor. Is it possible to do that without third-party modules?

Code to reproduce

let FFmpeg = require('fluent-ffmpeg');
  let buffer = new Buffer(data, 'base64');
  let bufferStream = new stream.PassThrough();
  bufferStream.end(buffer);
  let bufferStream_new = new stream.SomeProperty();

new FFmpeg({
    source: bufferStream
  })
  .audioCodec('pcm_mulaw')
  .on('error', function(err) {
    socket.emit('ffmpeg-error', 'ffmpeg : сообщение ошибки: ' + err.message);
  })
  .on('progress', function(progress) {
    socket.emit('ffmpeg-output', Math.round(progress.percent));
    console.log("progress")
  })
  .on('end', function(){
    //socket.emit('merged', dateTimeString + fileName + '-pcm_mulaw.wav');
    console.log('Formating finished!');
    //fs.unlinkSync(audioFile);
    console.log("after");
    //console.log(this.Buffer);
  })
  .writeToStream(bufferStream_new);

Expected results

 writeToBuffer(bufferStream_new);

console.log(bufferStream_new); // Any available buffer to read or just a regular ArrayBuffer instead 

Observed results

ffmpeg : errormsg: ffmpeg exited with code 1: pipe:1: Invalid argument

p.s I am sorry for incorrect example. I just want to show what i want to achieve

galipmedia commented 2 years ago

Try adding the .format('mp4') for example.

filipecatraia commented 2 years ago

I don't want to just say “same issue!”, so below is code for a similar situation. ffmpeg successfully converts the file, and I can verify the audio is as expected if I write to file and listen to it. However, the PassThrough stream doesn't seem to ever get ran, none of the console.log statements fire.

Something to note: the events progress and end never fire either. stderr is the only one that gets triggered, although weirdly it prints out all messages from ffmpeg, not just stderr. That piece of output is consistent with running ffmpeg in the command line without fluent-ffmpeg.

It's sad that we can't make conversion work with buffers and/or streams. That would open up the possibility of in-memory file conversion, which is what I'm aiming for. I don't mind writing to disk, but it'd be cooler to do this The Node Way 😄

const buffers = []
const bufferStream = new stream.PassThrough()

bufferStream
    .on('start', () => {
        console.log('Pass-through stream has started')
    })
    .on('data', function (buf) {
        console.log('bufferStream data', buf)
        buffers.push(buf)
    })
    .on('end', function () {
        const outputBuffer = Buffer.concat(buffers)
        console.log('Done preparing bufferStream')
    })

ffmpeg(inputBuffer)
    .audioCodec('libvorbis')
    .format('ogg')
    .on('start', (commandLine) => {
        console.log('ffmpeg started conversion', commandLine)
    })
    .on('stderr', function (stderrLine) {
        console.error('Stderr output: ' + stderrLine)
    })
    .on('error', function (err) {
        console.error('ffmpeg-error', err)
        reject(err)
    })
    .on('progress', function (progress) {
        console.log('ffmpeg-output', Math.round(progress.percent))
    })
    .on('end', function () {
        console.log('Formating finished!')
    })
    .writeToStream(bufferStream)
wesbos commented 1 year ago

Finding this too - is it not possible to merge and stream the output to buffers? I don't want to save to file - just do it in memory