目前
,我正在开发一个图像处理应用程序,该应用程序使用 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