I have a media stream with associated named pipe to it. The program reads data from pipe and processes frames with processFrame
.
module Main where
import Codec.FFmpeg
import Codec.FFmpeg.Decode
import Control.Monad.Except (runExceptT)
main :: IO ()
main = do
initFFmpeg
-- get IO reader
eResult <- runExceptT $ frameReader avPixFmtRgb24 (File "pipe")
case eResult of
Left err -> do print "couldn't establish frameReader\n"
print err
Right (getMaybeFrame, cleanup) -> do
-- read and process frames until av_read_frame returns no frames
loopWhileTrue (getAndProcessFrame getMaybeFrame)
cleanup
where
loopWhileTrue f = do result <- f
case result of
True -> loopWhileTrue f
False -> return ()
where
getAndProcessFrame gMF = do
maybeFrame <- gMF
case maybeFrame of
Just frame -> do tc <- timeCondition
if tc
then do processFrame frame
else return ()
return True
Nothing -> return False
timeCondition = return True
processFrame :: AVFrame -> IO ()
processFrame frame = do isKeyFrame <- getKeyFrame frame
if isKeyFrame
then do pts <- getPts frame
print pts
else return ()
I need to perform processFrame
only once in a minute, bypassing all other frames.
This code does not have a proper time condition, only a timeCondition
stub.
I planned to write a proper timeCondition
function which returns True
when a certain time has passed since last processFrame
, otherwise False
. But this looks too imperative and it's not clear how to use Monads/MVars for this. What's the right way of designing such a program in Haskell?