fluent ffmpeg size output option not working

2019-07-13 15:49发布

问题:

Summary: I'm trying to limit output to 3mb, .outputOptions('-fs 3000000') isn't working for me, the file is coming back with a size of 119260428 or 119mb.

Here is the code to try for yourself, all you need is a test.mp3 large enough that the resulting testoutput.ogg is > 3mb:

var ffmpeg = require("fluent-ffmpeg");
var command = ffmpeg();

var convertToOGG = function(){
  var fileName = 'test.mp3'

  ffmpeg.ffprobe(fileName, function(err, metadata) {
    command
      .input(fileName)
      .inputFormat("mp3")
      .audioChannels(1)
      .outputOptions('-fs', 3000000)
      .output('testoutput.ogg')
      .on("progress", function(progress) {
        console.log("Processing: " + progress.timemark);
      })
      .on("error", function(err, stdout, stderr) {
        console.log("Cannot process video: " + err.message);
      })
      .on("end", function(stdout, stderr) {
        ffmpeg.ffprobe('testoutput.ogg', function(err,metadata){
          if(metadata.format.size >= 3000000){

            console.log("didn't work")
          } 
        })
      })
    .run();
  });
};

convertToOGG();

Per the fluent-ffmpeg documentation you should be able to use a ffmpeg command in an output option: outputOption()

This method allows passing any output-related option to ffmpeg. You can call it with a single argument to pass a single option, optionnaly with a space-separated parameter:

/* Single option */
ffmpeg('/path/to/file.avi').outputOptions('-someOption');

and in FFMPEG's documentation:

-fs limit_size (output) Set the file size limit, expressed in bytes. No further chunk of bytes is written after the limit is exceeded. The size of the output file is slightly more than the requested file size.

It's giving me no errors, just seemingly ignoring the file size limit of 99mb and outputting a 119.3mb file.

Edit - Looks like -fs 3000000 is working for mp3 to wav, but still wont do mp3 to ogg. This is the output from running the command in terminal:

✗ ffmpeg -i test.mp3 -fs 3000000 testoutput.ogg
ffmpeg version 3.2.2 Copyright (c) 2000-2016 the FFmpeg developers
  built with Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.2.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
  libavutil      55. 34.100 / 55. 34.100
  libavcodec     57. 64.101 / 57. 64.101
  libavformat    57. 56.100 / 57. 56.100
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libavresample   3.  1.  0 /  3.  1.  0
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
[mp3 @ 0x7fc6a4000000] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'test.mp3':
  Metadata:
    lyrics-eng      : xxx
    title           : xxx
    artist          : xxx
    album_artist    : xxx
    album           : xxx
    genre           : xxx
  Duration: 03:27:28.74, start: 0.000000, bitrate: 128 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, mono, s16p, 128 kb/s
    Stream #0:1: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 540x360, 90k tbr, 90k tbn, 90k tbc
    Metadata:
      title           : Array
      comment         : Cover (front)
[swscaler @ 0x7fc6a4808800] deprecated pixel format used, make sure you did set range correctly
[ogg @ 0x7fc6a3815800] Frame rate very high for a muxer not efficiently supporting it.
Please consider specifying a lower framerate, a different muxer or -vsync 2
Output #0, ogg, to 'testoutput.ogg':
  Metadata:
    lyrics-eng      : xxx
    title           : xxx
    artist          : xxx
    album_artist    : xxx
    album           : xxx
    genre           : xxx
    encoder         : Lavf57.56.100
    Stream #0:0: Video: theora (libtheora), yuv444p, 540x360, q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tbc
    Metadata:
      title           : Array
      DESCRIPTION     : Cover (front)
      encoder         : Lavc57.64.101 libtheora
      lyrics-eng      : xxx
      artist          : xxx
      ALBUMARTIST     : xxx
      album           : xxx
      genre           : xxx
    Stream #0:1: Audio: vorbis (libvorbis), 44100 Hz, mono, fltp
    Metadata:
      encoder         : Lavc57.64.101 libvorbis
      lyrics-eng      : xxx
      title           : xxx
      artist          : xxx
      ALBUMARTIST     : xxx
      album           : xxx
      genre           : xxx
Stream mapping:
  Stream #0:1 -> #0:0 (mjpeg (native) -> theora (libtheora))
  Stream #0:0 -> #0:1 (mp3 (native) -> vorbis (libvorbis))
Press [q] to stop, [?] for help
frame=    1 fps=0.0 q=-0.0 Lsize=  116465kB time=03:27:28.71 bitrate=  76.6kbits/s speed=61.2x
video:9kB audio:114907kB subtitle:0kB other streams:0kB global headers:6kB muxing overhead: 1.347787%

回答1:

The source mp3 contains a cover image. Attempting to transcode the source file to ogg results in an unusually high framerate for the video stream.

There's a problem with the framerate estimation: 90k fps resembles the stream timebase value:

[ogg @ 0x7fc6a3815800] Frame rate very high for a muxer not efficiently supporting it.
[...]
Stream #0:0: Video: theora (libtheora), yuv444p, 540x360, q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tbc

This could be caused by a problem with the source file, a bug in ffmpeg or maybe both.

A quick solution is to ignore the cover image using either -map 0:a or -vn.