Haskell - превращение нескольких графических файлов в один видеофайл с помощью пакета ffmpeg-light

Фон
Я написал приложение для обработки изображений, которое использует ffmpeg-light пакет для извлечения всех кадров данного видеофайла, чтобы впоследствии программа могла применять оттенки серого, а также алгоритм обнаружения краев для каждого из кадров.

Сейчас я пытаюсь поместить все кадры обратно в один видеофайл.

Подержанные Libs
FFmpeg-светло-0.12.0
JuicyPixels-3.2.8.3
...

Что я пробовал?
Я должен быть честным, я действительно ничего не пробовал, потому что я не знаю, где и как начать. Я видел, что есть пакет под названием Command который позволяет запускать процессы / команды с использованием командной строки. С этим я мог бы использовать ffmpeg (не ffmpeg-light) создать видео из графических файлов, которые мне сначала нужно было бы сохранить на жестком диске, но это было бы немного странно.

В документации ffmpeg-light на hackage (документ ffmpeg-light) я нашел функцию frameWriter, которая звучит многообещающе.

frameWriter :: EncodingParams -> FilePath -> IO (Maybe (AVPixelFormat, V2 CInt, Vector CUChar) -> IO ()) 

Похоже FilePath было бы место, где хранится видеофайл, но я не могу себе представить, как применить кадры как EncodingParams к этой функции.

другие
Я могу получить доступ к:
- r, g, b, a так же какy, a ценности
- ширина изображения / высота / формат

Вопрос
Есть ли способ добиться этого с помощью ffmpeg-light пакет?

Как ffmpeg-light Пакет не хватает документации, когда дело доходит до преобразования из изображений в видео, я действительно буду признателен за вашу помощь. (Я не ожидаю полностью рабочего решения.)

Код
Код, который читает фреймы:

-- Gets and returns all frames that a given video contains
getAllFrames :: String -> IO [(Double, DynamicImage)]
getAllFrames vidPath = do 
  result <- try (imageReaderTime $ File vidPath) :: IO (Either SomeException (IO (Maybe (Image PixelRGB8, Double)), IO()))
  case result of 
    Left ex -> do 
                 printStatus "Invalid video-path or invalid video-format detected." "Video" 
                 return []
    Right (getFrame, _) -> addNextFrame getFrame [] 

-- Adds up all available framesvideo.
addNextFrame :: IO (Maybe (Image PixelRGB8, Double)) -> [(Double, DynamicImage)] -> IO [(Double, DynamicImage)]
addNextFrame getFrame frames = do
  frame <- getFrame
  case frame of 
    Nothing -> do 
                 printStatus "No more frames found." "Video"
                 return frames
    _       -> do                             
                 newFrameData <- fmap ImageRGB8 . swap . fromJust <$> getFrame 
                 printStatus ("Frame: " ++ (show $ length frames) ++ " added.") "Video"
                 addNextFrame getFrame (frames ++ [newFrameData]) 

Где я застрял / Код, который должен конвертировать изображения в видео:

-- Converts from several images to video
juicyToFFmpeg :: [Image PixelYA8] -> ?
juicyToFFmpeg imgs = undefined

1 ответ

Решение

Отказ от ответственности: не знаком с этими библиотеками. Информация почерпнута из типовых подписей и документации.

использование Codec.FFmpeg.Juicy:

Codec.FFmpeg.Juicy.imageWriter ::
  JuicyPixelFormat p =>
  EncodingParams ->
  FilePath ->
  IO (
    Maybe (Image p) -> 
    IO ()
  )

определять

instance JuicyPixelFormat PixelYA8 where
  juicyPixelFormat _  = _ -- in memory format of PixelYA8

juicyToFFmpeg :: [Image PixelYA8] -> FilePath -> IO ()
juicyToFFmpeg is fp = do writer <- imageWriter params fp
                         -- give Just image data to writer to append it
                         forM_ is (writer . Just)
                         writer Nothing -- finalize, or else you'll break it
   where params :: EncodingParams
         params = _ -- Figure out what fps, width, height, etc. you want (hardcode? parameters to juicyToFFmpeg? fold on is?)

Старый ответ

juicyToFFmpeg :: [Image PixelYA8] -> FilePath -> IO ()
juicyToFFmpeg is fp = do writer <- frameWriter (findEncodingParams is) fp
                         forM_ is $ \img -> let form = imgForm img
                                                dims = imgDims img
                                                pixs = imgData img
                                            in writer $ Just (form, dims, pixs)
                         writer Nothing
   where findEncodingParams = _
         imgForm :: Image PixelYA8 -> AVPixelFormat
         imgForm = _ -- however your images are encoded
         imgDims :: Image PixelYA8 -> V2 Int
         imgDims = _ -- duh
         imgData :: Image PixelYA8 -> Vector CUInt
         imgData = _ -- Encode as a bunch of integers, following the value of imgForm
Другие вопросы по тегам