4

目前
,我正在开发一个图像处理应用程序,该应用程序使用 ffmpeg-light 来获取给定视频文件的所有帧,以便之后程序可以对每个帧应用灰度以及边缘检测算法。

在友好的 stackoverflowers 的帮助下,我能够使用 ffmpeg-lights 的frameWriter功能设置一种能够将多个图像转换为一个视频文件的方法。

问题
应用程序运行良好,直到它到达frameWriter函数的那一刻,我真的不知道为什么,因为没有抛出错误或异常消息。(操作系统:Win 10 64 位)

我尝试了什么?
我试过..
- ffmpeg 的不同版本(从 3.2 到 3.4)。
- ffmpeg.exe 使用命令行测试是否缺少任何编解码器,但我尝试的任何转换都有效。
- 不同的 EncodingParams-combinations: like.. EncodingParams width height fps (Nothing) (Nothing) "medium"

问题
不幸的是,上述方法均无效,并且网络缺乏针对该特定案例的信息。也许我错过了一些重要的东西(比如 ghc 标志或其他东西)或者在我的代码中犯了更大的错误。这就是为什么我要问你:你对我有什么建议/建议吗?

Haskell 包
- ffmpeg-light-0.12.0
- JuicyPixels-3.2.8.3

代码

{--------------------------------------------------------------------------------------------
 Applies "juicyToFFmpeg'" and "getFPS" to a list of images and saves the output-video
 to a user defined location.
---------------------------------------------------------------------------------------------}     
saveVideo :: String -> [Image PixelYA8] -> Int -> IO ()
saveVideo path imgs fps = do
         -- program stops after hitting next line --
         frame <- frameWriter ep path
         ------------------------------------------------
         Prelude.mapM_ (frame . Just) ffmpegImgs 
         frame Nothing
         where ep = EncodingParams width height fps (Just avCodecIdMpeg4) (Just avPixFmtGray8a) "medium"
               width      = toCInt $ imageWidth  $ head imgs
               height     = toCInt $ imageHeight $ head imgs
               ffmpegImgs = juicyToFFmpeg' imgs
               toCInt x   = fromIntegral x :: CInt

{--------------------------------------------------------------------------------------------
 Converts a single image from JuicyPixel-format to ffmpeg-light-format. 
---------------------------------------------------------------------------------------------}      
juicyToFFmpeg :: Image PixelYA8 -> (AVPixelFormat, V2 CInt, Vector CUChar)
juicyToFFmpeg img = (avPixFmtGray8a, V2 (toCInt width) (toCInt height), ffmpegData)
                  where toCInt   x   = fromIntegral x :: CInt
                        toCUChar x   = fromIntegral x :: CUChar
                        width        = imageWidth img
                        height       = imageHeight img
                        ffmpegData   = VS.map toCUChar (imageData img)

{--------------------------------------------------------------------------------------------
 Converts a list of images from JuicyPixel-format to ffmpeg-light-format. 
---------------------------------------------------------------------------------------------}                        
juicyToFFmpeg' :: [Image PixelYA8] -> [(AVPixelFormat, V2 CInt, Vector CUChar)]
juicyToFFmpeg' imgs = Prelude.foldr (\i acc -> acc++[juicyToFFmpeg i]) [] imgs

{--------------------------------------------------------------------------------------------
 Simply calculates the FPS for image-to-video conversion.
 -> frame :: (Double, DynamicImage) where Double is a timestamp of when it got extracted 
---------------------------------------------------------------------------------------------}
getFPS :: [(Double, DynamicImage)] -> Int
getFPS frames = div (ceiling $ lastTimestamp - firstTimestamp) frameCount :: Int
              where firstTimestamp = fst $ head frames
                    lastTimestamp  = fst $ last frames
                    frameCount     = length frames
4

1 回答 1

2

我怀疑您遇到的问题与 Windows 环境和 Haskell 中 ffmpeg 的使用有关(即 ffmpeg-simple)

我能够在 Ubuntu 16.04 上成功编译和运行您的模块,尽管我确实从 ffmpeg 收到了运行时错误:

$ ./main
[NULL @ 0x1ea6900] Unable to find a suitable output format for 'foo.avi'
main: Couldn't allocate output format context
CallStack (from HasCallStack):
  error, called at src/Codec/FFmpeg/Encode.hs:214:17 in ffmpeg-light-
0.12.0-DYHyy7pUAhZ7WHcd6Y2mLO:Codec.FFmpeg.Encode

似乎可以通过调整一些 ffmpeg 参数来修复上述错误,但由于这不是您遇到的问题,所以我决定不再进一步调试它。

以防万一我的main

main :: IO ()
main = do
  Right (ImageYA8 img) <- readPng "foo_ya.png"
  saveVideo "foo.avi" (replicate 10 img) 10

我在 Windows 7 64 位上运行了同样的东西,似乎我无法完全满足依赖关系。

在 Windows 上完成编译和依赖安装:

> stack exec -- pacman -Syu
> stack exec -- pacman -S mingw-w64-x86_64-gtk3
> stack exec -- pacman -S mingw-w64-x86_64-pkg-config
> stack exec -- pacman -S mingw-w64-x86_64-ffmpeg
> stack --install-ghc --resolver lts-9.10 exec --package vector --package JuicyPixels --package ffmpeg-light -- ghc main.hs -O2 -threaded
> stack exec -- main.exe

运行时导致弹出错误cmdps简单地退出):

在动态链接库 zlib1.dll 中找不到过程入口点 inflateValidate

我不是 Windows 开发方面的专家,所以我觉得我错过了一些东西。希望我的尝试至少会有所帮助。

于 2017-10-26T09:22:09.270 回答