Ich benutze ffmpeg-light, JuicyPixels und gloss, um ein Video mit Haskell anzuzeigen. Ich möchte die Metadaten von Videos finden, die ich automatisch spiele, aber ich habe noch keinen Weg gefunden, dies zu tun.Wie finde ich mp4-Metadaten mit ffmpeg-light in haskell?
Ich möchte auf Metadaten wie die Auflösung und die Framerate des Videos zugreifen.
Können Sie mir helfen?
EDIT:
Ich habe Ihre Lösung @CRDrost versucht, aber das Video nun mit 2x Normalgeschwindigkeit. Ich nehme an, dass die Funktion imageReaderTime falsche Zeitstempel gibt.
EDIT 2:
Die abnorme Spielgeschwindigkeit ist ein Fehler in der ffmpeg-Licht-Bibliothek. Ich habe eine issue im Github-Repository geöffnet.
Meine aktualisierten Code:
import Graphics.Gloss
import Codec.FFmpeg
import Codec.FFmpeg.Juicy
import Codec.Picture
import Control.Applicative
import Data.Maybe
import Graphics.Gloss.Juicy
import Control.Monad
-- import System.IO.Unsafe (unsafePerformIO)-- for debugging purposes
resolution :: (Int,Int)
resolution = (640, 360)
frameCount :: Int
frameCount = 100
main :: IO()
main = do
initFFmpeg
(getFrame, cleanup) <- imageReaderTime "big_buck_bunny.mp4"
frames <- replicateM frameCount $ nextFrame getFrame
cleanup
animate (InWindow "Nice Window" resolution (10,10)) white (frameAt frames)
nextFrame :: IO (Maybe (Image PixelRGB8, Double)) -> IO (Picture, Float)
nextFrame getFrame = mapSnd realToFrac . mapFst fromImageRGB8 . fromJust <$> getFrame
frameAt :: [(Picture, Float)] -> Float -> Picture
frameAt list time = fst . head . dropWhile ((< time) . snd) $ list
mapFst :: (a -> c) -> (a, b) -> (c, b)
mapFst f (a, b) = (f a, b) -- applies f to first element of a 2-tuple
mapSnd :: (b -> c) -> (a, b) -> (a, c)
mapSnd f (a, b) = (a, f b) -- applies f to the second element of a 2-tuple