module Data.ByteString.IsoBaseFileFormat.Boxes.Time
(referenceTime, utcToMp4, mp4CurrentTime, durationFromSeconds,
TimeScale, Timing)
where
import Data.Time.Clock
import Data.Time.Calendar
import Data.Ratio
import Data.ByteString.IsoBaseFileFormat.Boxes.Box
import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields
import Data.ByteString.IsoBaseFileFormat.Boxes.Versioned
referenceTime :: UTCTime
referenceTime =
let startDay = fromGregorian 1904 1 1
startTime = 0
in UTCTime startDay startTime
utcToMp4 :: Num t
=> UTCTime -> t
utcToMp4 u =
let picoSecondsDiff = toRational $ diffUTCTime u referenceTime
picoSecondsDiffNumerator = numerator picoSecondsDiff
picoSecondsDiffDenominator = denominator picoSecondsDiff
secondsSinceReferenceTime =
div picoSecondsDiffNumerator picoSecondsDiffDenominator
in fromIntegral secondsSinceReferenceTime
mp4CurrentTime :: Num t
=> IO t
mp4CurrentTime = utcToMp4 <$> getCurrentTime
type TimeScale = Template (U32 "timescale") 90000
durationFromSeconds :: Num t
=> TimeScale -> Integer -> t
durationFromSeconds timeScale seconds =
let timeScaleI = fromIntegral $ fromScalar $ templateValue timeScale
in timeScaleI * fromInteger seconds
type Timing (version :: Nat) = Versioned TimingV0 TimingV1 version
type TimingV0 = TimingImpl (Scalar Word32)
type TimingV1 = TimingImpl (Scalar Word64)
type TimingImpl uint =
uint "creation_time"
:+ uint "modification_time"
:+ TimeScale
:+ uint "duration"