Minimal bindings to the FFmpeg library. http://github.com/acowley/ffmpeg-light

Latest on Hackage:

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.

BSD3 licensed by Anthony Cowley
Maintained by acowley@gmail.com

Stream frames from an encoded video, or stream frames to a video output file. To read the first frame from an h264-encoded file into a JuicyPixels Maybe DynamicImage,

import Codec.FFmpeg
import Codec.Picture
import Control.Applicative

go :: IO (Maybe DynamicImage)
go = do (getFrame, cleanup) <- imageReader "myVideo.mov"
        (fmap ImageRGB8 <$> getFrame) <* cleanup

Tested with FFmpeg 3.1 - 3.2.4



  • Refactoring to better interoperate with SDL2
  • SDL2 video player demo executable

[Thanks to Vladimir Pankov!]


  • Use Control.Monad.Except instead of the deprecated Control.Monad.Error (Issue reported by Alexander / @AleXoundOS)


  • Query stream duration (Matthias Treydte)
  • Initial support for verbosity control; defaults to quiet * Can be changed with the new setLogLevel function

0.10. 0

  • Fix encoder bug that created a single black frame at the start of every video (Jonathan Daugherty)


  • Add support for camera input (Thomas M. DuBuisson) * Try it: build the demo executable (cabal configure -fBuildDemo) and run cabal run demo -- cam to record 10s of video from a connected camera to an output file camera.mov.

  • Extract frame time stamps from the video stream rather than the codec context (hat tip to Jaro Reinders)


  • Added probe features


  • Update raster demo to use new JuicyPixels-3.2 API


  • Update to transformers-0.4.1 and mtl-2.2.1 * Changed decode-related types to accomodate deprecation of the Error class. This means that if you want to initialize decoders in your own transformer stack that has a MonadError instance, you will need to use the variants with names suffixed by a "T" (for transformer).

  • Update to ffmpeg 2.3

    • Address deprecation warning

      Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated. Set AVStream.time_base instead.

    • Address "non-strictly-monotonic PTS" warning

  • Rasterific bump * Rasterific exports its own linear algebra types as of 0.3


  • Bumped transformers dependency

    Note: The use of mtl still triggers deprecation warnings from transformers.

  • Fixed bug with changing source pixel format from RGB during encoding.

  • Added BGRA pixel format


  • Simplified top-level API to focus on JuicyPixels-based interface


  • Cleaned the API of detritus. Use the image* functions.


  • Juiced the Encode and Decode APIs.

    Using imageWriter and imageReader provides a degree of pixel format polymorphism based on JuicyPixels pixel types.


  • Fixed corrupted output of palettized animated GIFs.

  • Added palettization options

    • Using avPixFmtRgb8 results in a small file

    • Using the default pixel format (avPixFmtPal8) results in a good-looking, fairly large file thanks to JuicyPixels's palettize function.

    • Setting the epPreset field of the EncodingParams value passed to frameWriter to "dither" results in an even prettier, even larger GIF file (again, thanks to JuicyPixels's palettize function).

    • See the demo/Raster.hs for examples.


  • Automatically palettize RGB24 to RGB8 for GIF output.

  • Add a Rasterific demo program that records an animation.


  • Support for GIF encoding (and other palletized formats).


  • Separate Scaler module and friendly libswscaler interface.

  • Generalized toJuicy conversion.

  • Added demo program.


  • Basic h264 encoding and decoding.
comments powered byDisqus