Ffmpeg, video to png

Hello everyone,

I am trying to extract thumbnail from video with waffle and ffmpeg.

I do have a transformer like this

  def transform(:thumb, _) do
    {:ffmpeg, fn(input, output) -> "-i #{input} -f png #{output}" end, :png}
  end

but this fail with

Unable to find a suitable output format

And this fail in the console too.

$ ffmpeg -i small.mp4 -f png out_small.png
...
[NULL @ 0x7f8e93801400] Requested output format 'png' is not a suitable output format
out_small.png: Invalid argument

It looks my ffmpeg does not support png creation, as png is not listed in formats.

$ ffmpeg -formats | grep png
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.2.2_1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.0.1.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.0.1.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
 DE apng            Animated Portable Network Graphics
 D  png_pipe        piped png sequence

I have success using apng, or gif, but not png, nor jpg.

I guess it is my ffmpeg version which is broken. It’s the latest installed by brew, on Mac osx.

So my question is, do You have png listed in your ffmpeg formats?

Thanks in advance

I have ffmpeg version 3.4.6 and it seems I have the same supported formats.

Here is the output of the command ffmpeg -formats | grep png:

ffmpeg version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
 DE apng            Animated Portable Network Graphics
 D  png_pipe        piped png sequence
1 Like

Thanks, so it seems it’s not only Mac :slight_smile:

1 Like

I think you just need to provide a few more arguments to your ffmpeg command and that by default, ffmpeg assumes you want to convert the video to another video format.
I am running MacOS and ffmpeg 4.2.2 as well and am able to create a thumbnail with the following command:
ffmpeg -i sample.mp4 -ss 00:00:01.000 -vframes 1 output.png
Note we tell ffmpeg to take 1 frame (with -vframes 1), from a specific point (-ss <timestamp>) in the video.

2 Likes

Thanks for your response, I have to say I could generate png on the console, with this…

ffmpeg -ss 00:01 -i small.mp4 -t 00:02 -frames:v 1 outsmall.png

But it fails in the waffle transformation function

  def transform(:thumb, _) do
    {:ffmpeg, fn(input, output) -> "-ss 00:01 -i #{input} -t 00:02 -frames:v 1 #{output}" end, :png}
  end

[error] {:error, ["ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers\n  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)\n  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.2.2_1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.0.1.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.0.1.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack\n  libavutil      56. 31.100 / 56. 31.100\n  libavcodec     58. 54.100 / 58. 54.100\n  libavformat    58. 29.100 / 58. 29.100\n  libavdevice    58.  8.100 / 58.  8.100\n  libavfilter     7. 57.100 /  7. 57.100\n  libavresample   4.  0.  0 /  4.  0.  0\n  libswscale      5.  5.100 /  5.  5.100\n  libswresample   3.  5.100 /  3.  5.100\n  libpostproc    55.  5.100 / 55.  5.100\nInput #0, mov,mp4,m4a,3gp,3g2,mj2, from '/var/folders/39/633s5xh54jjgntzl838zv56c0000gn/T//plug-1580/multipart-1580813808-273373503129595-7':\n  Metadata:\n    major_brand     : mp42\n    minor_version   : 0\n    compatible_brands: mp42isomavc1\n    creation_time   : 2010-03-20T21:29:11.000000Z\n    encoder         : HandBrake 0.9.4 2009112300\n  Duration: 00:00:05.57, start: 0.000000, bitrate: 551 kb/s\n    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 560x320, 465 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)\n    Metadata:\n      creation_time   : 2010-03-20T21:29:11.000000Z\n      encoder         : JVT/AVC Coding\n    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 83 kb/s (default)\n    Metadata:\n      creation_time   : 2010-03-20T21:29:11.000000Z\n[NULL @ 0x7fc22d802200] Unable to find a suitable output format for '/var/folders/39/633s5xh54jjgntzl838zv56c0000gn/T/ZE7BC755M55YFI2KSQF2BYJKNNFZOEPJ'\n/var/folders/39/633s5xh54jjgntzl838zv56c0000gn/T/ZE7BC755M55YFI2KSQF2BYJKNNFZOEPJ: Invalid argument\n"]}

I suppose the :png option of waffle trigger -f png

This one work, for animated png.

  def transform(:thumb, _) do
    {:ffmpeg, fn(input, output) -> "-i #{input} -f apng #{output}" end, :png}
  end

Are you sure that there are no spaces in input and output?

2 Likes

Thanks for your response,

I am quite confident with the syntax, as this is how it is written in the waffle documentation.

https://hexdocs.pm/waffle/Waffle.Processor.html#content

I thought png and jpg would be supported out of the box, but it seems not :slight_smile:

It’s not a syntax issue they were speaking of but rather that the list form should be used as it will properly escape arguments where the string form will not.

However, running ffmpeg -ss 01:23:45 -i some-big-video-I-have.mpeg -vframes 1 -q:v 2 output.png works fine here and I have the same output from ffmpeg -formats | grep png as you do.

1 Like

Thanks for your response, using this syntax is working for me at the command line, but not with waffle.

I still receive unable to find a suitable format when waffle tries to extract the image from the video.

Have you tried the list form in waffle though? I.E. instead of something like:

"some arguments and #{input} and #{output}"

Have you tried:

["some", "arguments", "and", input, "and", output]

Instead?

1 Like

Oh nice, I will try and report.

1 Like

After many tests, I found the solution. The format to specify is now image2 for png.

This works

  def transform(:thumb, _) do
    {:ffmpeg, fn(input, output) -> ["-i", input, "-f", "image2", "-vframes", "1", output] end, :png}
  end

# or this too

  def transform(:thumb, _) do
    {:ffmpeg, fn(input, output) -> "-i #{input} -f image2 -vframes 1 #{output}" end, :png}
  end

It’s possible to pass a list or a string, but -f image2 is the key.

For reference, this is where I found the way to correctly transform a video to a png thumbnail.

https://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/image_sequence

Thank You all for the helps :slight_smile:

6 Likes