diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.12.1
+* Bump base upper bound
+* Rewritten Travis-CI support for GHC 8.02, 8.2.2, and 8.4.2
+
 # 0.12.0
 
 * Refactoring to better interoperate with SDL2
diff --git a/demo/Main.hs b/demo/Main.hs
--- a/demo/Main.hs
+++ b/demo/Main.hs
@@ -1,6 +1,6 @@
+module Main where
 import Codec.FFmpeg
 import Codec.Picture
-import Control.Applicative
 import Control.Monad (replicateM_)
 import qualified Data.Time.Clock as C
 import qualified Data.Vector.Storable as V
@@ -9,7 +9,8 @@
 
 -- The example used in the README
 firstFrame :: IO (Maybe DynamicImage)
-firstFrame = do (getFrame, cleanup) <- imageReader (File "myVideo.mov")
+firstFrame = do initFFmpeg
+                (getFrame, cleanup) <- imageReader (File "myVideo.mov")
                 (fmap ImageRGB8 <$> getFrame) <* cleanup
 
 -- | Generate a video that pulses from light to dark.
@@ -21,9 +22,9 @@
          go 600 _ _ = boom Nothing
          go n d i = do boom' $ V.replicate (sz*sz) (fromIntegral i)
                        let i' = i + d
-                       if i' < 100 
+                       if i' < 100
                        then go (n+1) 1 101
-                       else if i' > 255 
+                       else if i' > 255
                             then go (n+1) (-1) 254
                             else go (n+1) d i'
      go 0 (-1) 255
@@ -37,7 +38,7 @@
 -- | Decoding example. Try changing 'ImageRGB8' to 'ImageY8' in the
 -- 'savePngImage' lines to automatically decode to grayscale images!
 testDecode :: FilePath -> IO ()
-testDecode vidFile = 
+testDecode vidFile =
   do initFFmpeg
      (getFrame, cleanup) <- imageReaderTime (File vidFile)
      frame1 <- getFrame
@@ -86,11 +87,11 @@
           case args of
             [] -> testEncode
             [s]
-              | s `elem` ["--help", "-help", "-h"] -> error usage 
+              | s `elem` ["--help", "-help", "-h"] -> error usage
               | s == "cam" -> testCamera
             [vidFile] -> testDecode vidFile
             _ -> error usage
-  where usage = 
+  where usage =
           unlines [ "Usage: demo [videoFile]"
                   , "  If no argument is given, a test video named "
                   , "  pulse.mov is generated."
@@ -98,4 +99,3 @@
                   , "  If a file name is given, then two frames are "
                   , "  extracted: the first frame, and the 301st."
                   , "  These are saved to frame1.png and frame2.png" ]
-
diff --git a/demo/Raster.hs b/demo/Raster.hs
--- a/demo/Raster.hs
+++ b/demo/Raster.hs
@@ -1,7 +1,7 @@
 module Main where
 import Codec.FFmpeg
 import Codec.Picture
-import Codec.Picture.Types (dropTransparency)
+-- import Codec.Picture.Types (dropTransparency)
 import Control.Monad (forM_)
 import Graphics.Rasterific
 import Graphics.Rasterific.Linear
@@ -86,13 +86,13 @@
 
 -- | Adapted from the Rasterific logo example.
 logoTest :: Texture PixelRGBA8 -> Vector -> Image PixelRGBA8
-logoTest texture insetOrigin = 
+logoTest texture insetOrigin =
   renderDrawing fgSizei fgSizei background (bg >> drawing)
-  where 
+  where
     beziers = logo 40 False $ V2 10 10
     inverse = logo 20 True $ (V2 20 20 + insetOrigin)
     bg = withTexture bgGrad . fill $ rectangle (V2 0 0) fgSize fgSize
-    drawing = withTexture texture . fill 
+    drawing = withTexture texture . fill
             . transform (applyTransformation $ scale fgScale fgScale)
             $ beziers ++ inverse
 
diff --git a/ffmpeg-light.cabal b/ffmpeg-light.cabal
--- a/ffmpeg-light.cabal
+++ b/ffmpeg-light.cabal
@@ -1,5 +1,5 @@
 name:                ffmpeg-light
-version:             0.12.0.1
+version:             0.12.1.0
 synopsis:            Minimal bindings to the FFmpeg library.
 
 description:         Stream frames from an encoded video, or stream frames to
@@ -15,19 +15,20 @@
                      > go = do (getFrame, cleanup) <- imageReader "myVideo.mov"
                      >         (fmap ImageRGB8 <$> getFrame) <* cleanup
                      .
-                     Tested with FFmpeg 3.1 - 3.2.4
+                     Tested with FFmpeg 3.1 - 3.4.2
 
 license:             BSD3
 license-file:        LICENSE
 author:              Anthony Cowley
 maintainer:          acowley@gmail.com
-copyright:           Copyright (C) 2014 Anthony Cowley
+copyright:           Copyright (C) 2018 Anthony Cowley
 homepage:            http://github.com/acowley/ffmpeg-light
 bug-reports:         http://github.com/acowley/ffmpeg-light/issues
 category:            Codec
 build-type:          Simple
-extra-source-files:  src/hscMacros.h, CHANGELOG.md
+extra-source-files:  src/hscMacros.h, src/nameCompat.h, CHANGELOG.md
 cabal-version:       >=1.10
+tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.2
 
 source-repository head
   type:     git
@@ -66,7 +67,7 @@
                        Codec.FFmpeg.Internal.Debug,
                        Codec.FFmpeg.Internal.Linear
   build-tools:         hsc2hs
-  build-depends:       base >=4.6 && < 4.11,
+  build-depends:       base >=4.6 && < 4.12,
                        either,
                        exceptions,
                        vector >= 0.10.9 && < 0.13,
diff --git a/src/Codec/FFmpeg/Decode.hs b/src/Codec/FFmpeg/Decode.hs
--- a/src/Codec/FFmpeg/Decode.hs
+++ b/src/Codec/FFmpeg/Decode.hs
@@ -7,11 +7,9 @@
 import Codec.FFmpeg.Enums
 import Codec.FFmpeg.Scaler
 import Codec.FFmpeg.Types
-import Control.Applicative
 import Control.Arrow (first)
 import Control.Monad (when, void)
 import Control.Monad.Except
-import Control.Monad.IO.Class
 import Control.Monad.Trans.Maybe
 import Foreign.C.String
 import Foreign.C.Types
diff --git a/src/Codec/FFmpeg/Encode.hs b/src/Codec/FFmpeg/Encode.hs
--- a/src/Codec/FFmpeg/Encode.hs
+++ b/src/Codec/FFmpeg/Encode.hs
@@ -12,7 +12,6 @@
 import Codec.FFmpeg.Scaler
 import Codec.FFmpeg.Types
 import Codec.Picture
-import Control.Applicative
 import Control.Monad (when, void)
 import Data.Bits
 import Data.IORef
diff --git a/src/Codec/FFmpeg/Enums.hsc b/src/Codec/FFmpeg/Enums.hsc
--- a/src/Codec/FFmpeg/Enums.hsc
+++ b/src/Codec/FFmpeg/Enums.hsc
@@ -10,6 +10,7 @@
 #include <libavutil/pixfmt.h>
 #include <libavutil/mathematics.h>
 #include <libswscale/swscale.h>
+#include "nameCompat.h"
 
 newtype AVMediaType = AVMediaType CInt deriving (Eq, Storable)
 #enum AVMediaType,AVMediaType \
diff --git a/src/Codec/FFmpeg/Internal/Linear.hs b/src/Codec/FFmpeg/Internal/Linear.hs
--- a/src/Codec/FFmpeg/Internal/Linear.hs
+++ b/src/Codec/FFmpeg/Internal/Linear.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 -- | Minimal operations on small vector types.
 module Codec.FFmpeg.Internal.Linear where
-import Control.Applicative
 import Foreign.C.Types
 import Foreign.Ptr (castPtr)
 import Foreign.Storable
diff --git a/src/Codec/FFmpeg/Juicy.hs b/src/Codec/FFmpeg/Juicy.hs
--- a/src/Codec/FFmpeg/Juicy.hs
+++ b/src/Codec/FFmpeg/Juicy.hs
@@ -8,19 +8,14 @@
 import Codec.FFmpeg.Enums
 import Codec.FFmpeg.Internal.Linear (V2(..))
 import Codec.FFmpeg.Types
-import Control.Applicative
-import Control.Arrow (first, (&&&))
+import Control.Arrow (first)
 import Control.Monad ((>=>))
 import Control.Monad.Except
-import Control.Monad.IO.Class
-import Control.Monad.Trans.Class
 import Control.Monad.Trans.Maybe
 import Data.Foldable (traverse_)
 import qualified Data.Vector.Storable as V
 import qualified Data.Vector.Storable.Mutable as VM
 import Foreign.C.Types
-import Foreign.Marshal.Array (advancePtr, copyArray)
-import Foreign.Ptr (castPtr, Ptr)
 import Foreign.Storable (sizeOf)
 import Data.Maybe (maybe)
 
@@ -35,7 +30,7 @@
 frameToVectorT frame = do
 
   bufSize <- fromIntegral <$> frameBufferSizeT frame
-       
+
   v <- MaybeT $ do
 
          v <- VM.new bufSize
@@ -61,16 +56,16 @@
   v <- frameToVectorT frame
 
   MaybeT $ do
-  
+
     w <- fromIntegral <$> getWidth frame
     h <- fromIntegral <$> getHeight frame
-    
+
     let mkImage :: V.Storable (PixelBaseComponent a)
                 => (Image a -> DynamicImage) -> Maybe DynamicImage
         mkImage c = Just $ c (Image w h (V.unsafeCast v))
-  
+
     fmt <- getPixelFormat frame
-        
+
     return $ case () of
                _ | fmt == avPixFmtRgb24 -> mkImage ImageRGB8
                  | fmt == avPixFmtGray8 -> mkImage ImageY8
@@ -81,15 +76,15 @@
 -- | Convert an 'AVFrame' to an 'Image'.
 toJuicyImage :: forall p. JuicyPixelFormat p => AVFrame -> IO (Maybe (Image p))
 toJuicyImage frame = runMaybeT $ do
-  
+
   fmt <- lift $ getPixelFormat frame
   guard (fmt == juicyPixelFormat ([] :: [p]))
-          
+
   MaybeT $ do
-    
+
     w <- fromIntegral <$> getWidth frame
     h <- fromIntegral <$> getHeight frame
-    
+
     fmap (Image w h . V.unsafeCast) <$> frameToVector frame
 
 
diff --git a/src/Codec/FFmpeg/Probe.hsc b/src/Codec/FFmpeg/Probe.hsc
--- a/src/Codec/FFmpeg/Probe.hsc
+++ b/src/Codec/FFmpeg/Probe.hsc
@@ -1,4 +1,3 @@
-
 {-# LANGUAGE
     ForeignFunctionInterface,
     GeneralizedNewtypeDeriving
@@ -20,7 +19,7 @@
 import Control.Applicative ( Applicative )
 import Control.Monad.Catch ( MonadMask, finally )
 import Control.Monad.Reader
-import Control.Monad.Trans.Either
+import Control.Monad.Trans.Except
 import Data.Int ( Int64 )
 import Foreign.C.String ( CString, peekCString, withCString )
 import Foreign.C.Types ( CInt(..) )
@@ -50,7 +49,7 @@
 
 withAvFile :: (MonadMask m, MonadIO m) => String -> AvFormat m a -> m a
 withAvFile fn f = do
-    ectx <- runEitherT $ openFile fn
+    ectx <- runExceptT $ openFile fn
     case ectx of
         Left e    -> liftIO $ fail e
         Right ctx -> finally
diff --git a/src/Codec/FFmpeg/Types.hsc b/src/Codec/FFmpeg/Types.hsc
--- a/src/Codec/FFmpeg/Types.hsc
+++ b/src/Codec/FFmpeg/Types.hsc
@@ -2,7 +2,6 @@
              GeneralizedNewtypeDeriving #-}
 module Codec.FFmpeg.Types where
 import Codec.FFmpeg.Enums
-import Control.Applicative
 import Control.Monad (zipWithM_,when)
 import Foreign.C.String (CString)
 import Foreign.C.Types
@@ -14,6 +13,7 @@
 #include <libavutil/avutil.h>
 #include <libswscale/swscale.h>
 #include "hscMacros.h"
+#include "nameCompat.h"
 
 class HasPtr a where
   getPtr :: a -> Ptr ()
@@ -137,6 +137,7 @@
 #mkField AVClass, AVClass
 #hasField AVInputFormat, AVClass, priv_class
 
+#if LIBAVUTIL_VERSION_MAJOR > 52
 getAVCategory :: AVInputFormat -> IO Category
 getAVCategory aif =
   do c <- getAVClass aif
@@ -152,6 +153,7 @@
         AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT,\
         AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, AV_CLASS_CATEGORY_DEVICE_OUTPUT, AV_CLASS_CATEGORY_DEVICE_INPUT,\
         AV_CLASS_CATEGORY_NB
+#endif
 
 newtype AVIOContext = AVIOContext (Ptr ()) deriving (Storable, HasPtr)
 
diff --git a/src/nameCompat.h b/src/nameCompat.h
new file mode 100644
--- /dev/null
+++ b/src/nameCompat.h
@@ -0,0 +1,54 @@
+/* Older versions of libav (and perhaps ffmpeg) used a different
+   naming scheme for constants. Since distributions like Ubuntu 12.04
+   are locked down with these old versions, we hack in support for the
+   newer constant names. */
+
+#if LIBAVUTIL_VERSION_MAJOR < 53
+#define AV_PIX_FMT_NONE PIX_FMT_NONE
+#define AV_PIX_FMT_RGB24 PIX_FMT_RGB24
+#define AV_PIX_FMT_RGBA PIX_FMT_RGBA
+#define AV_PIX_FMT_BGRA PIX_FMT_BGRA
+#define AV_PIX_FMT_Y400A PIX_FMT_Y400A
+#define AV_PIX_FMT_RGB8 -1
+#define AV_PIX_FMT_BGR8 -1
+#define AV_PIX_FMT_RGB4_BYTE -1
+#define AV_PIX_FMT_BGR4_BYTE -1
+#define AV_PIX_FMT_GRAY8 PIX_FMT_GRAY8
+#define AV_PIX_FMT_GRAY8A -1
+#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
+#define AV_PIX_FMT_YUV420P12 -1
+#define AV_PIX_FMT_YUV422P12 -1
+#define AV_PIX_FMT_YUV444P12 -1
+#define AV_PIX_FMT_YUV420P14 -1
+#define AV_PIX_FMT_YUV422P14 -1
+#define AV_PIX_FMT_YUV444P14 -1
+#define AV_PIX_FMT_RGBA64 -1
+#define AV_PIX_FMT_BGRA64 -1
+#define AV_PIX_FMT_PAL8 PIX_FMT_PAL8
+
+#define AV_CODEC_ID_H264 CODEC_ID_H264
+#define AV_CODEC_ID_THEORA CODEC_ID_THEORA
+#define AV_CODEC_ID_MPEG4 CODEC_ID_MPEG4
+#define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
+#define AV_CODEC_ID_GIF CODEC_ID_GIF
+#define AV_CODEC_ID_AAC CODEC_ID_AAC
+#define AV_CODEC_ID_MP3 CODEC_ID_MP3
+#define AV_CODEC_ID_DTS CODEC_ID_DTS
+#define AV_CODEC_ID_HEVC -1
+#define AV_CODEC_ID_VC1 -1
+#define AV_CODEC_ID_RAWVIDEO CODEC_ID_RAWVIDEO
+
+#define FF_PROFILE_MPEG2_AAC_LOW -1
+#define FF_PROFILE_MPEG2_AAC_HE -1
+
+#define AVIO_FLAG_DIRECT -1
+
+#define AV_ROUND_PASS_MINMAX -1
+
+#define CODEC_FLAG_UNALIGNED -1
+#define CODEC_FLAG_OUTPUT_CORRUPT -1
+
+#define AV_LOG_TRACE 56
+#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET)
+
+#endif
