packages feed

isobmff-builder 0.3.0.0 → 0.9.0.0

raw patch · 28 files changed

+1329/−457 lines, 28 filesdep +data-defaultdep +lensdep +textdep ~bytestringdep ~singletonsdep ~type-listPVP ok

version bump matches the API change (PVP)

Dependencies added: data-default, lens, text, time

Dependency ranges changed: bytestring, singletons, type-list, vector-sized

API changes (from Hackage documentation)

- Data.ByteString.IsoBaseFileFormat.Boxes.Box: AtMostOnce :: Cardinality
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: ExactlyOnce :: Cardinality
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: OnceOrMore :: Cardinality
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [Box'] :: (IsBoxType' b, ValidBoxes b ts) => BoxContent b -> Boxes ts -> Box' b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [Nested] :: Boxes '[]
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: class BoxRules (t :: k) where type RestrictedTo t :: Maybe [k] type IsTopLevelBox t :: Bool type RequiredNestedBoxes t :: [k] type GetCardinality t (c :: k) :: Cardinality type RestrictedTo t = Just '[] type IsTopLevelBox t = True type RequiredNestedBoxes t = '[] type GetCardinality t any = ExactlyOnce where {
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: class (IsBoxContent (BoxContent t), BoxRules t) => IsBoxType' t where type BoxContent t type BoxContent t = () where {
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Box' b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Cardinality
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance forall k (bs :: [k]). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Boxes bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance forall k (cnt :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Box' cnt)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: mediaFile :: Boxes ts -> Builder
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: toBoxType' :: IsBoxType' t => proxy t -> BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type GetCardinality t any = ExactlyOnce;
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type IsSubSet base sub = Intersection base sub == sub
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type IsTopLevelBox t = True;
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type MissingRequired c r nested = ((((Text "Boxes of type: " :<>: ShowType c) :<>: Text " require these nested boxes: ") :<>: ShowType (RequiredNestedBoxes c)) :$$: (Text "but only these box types were nested: " :<>: ShowType nested)) :$$: (Text "e.g. this type is missing: " :<>: ShowType r)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type NotAllowedMsg c t = (((((Text "Boxes of type: " :<>: ShowType c) :<>: Text " may not contain boxes of type ") :<>: ShowType t) :$$: ((Text "Valid containers for " :<>: ShowType t) :<>: Text " boxes are: ")) :$$: ShowType (RestrictedTo t)) :$$: (ShowType t :<>: If (IsTopLevelBox c) (Text " boxes may appear top-level in a file.") (Text " boxes must be nested."))
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type NotTopLevenError c = ((Text "Boxes of type " :<>: ShowType c) :<>: Text " MUST be nested inside boxes of these types: ") :$$: ShowType (RestrictedTo c)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type RequiredNestedBoxes t = '[];
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type RestrictedTo t = Just '[];
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type ValidBoxes t ts = (AllAllowedIn t ts ~ True, HasAllRequiredBoxes t (RequiredNestedBoxes t) ts ~ True)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: (<+>) :: a -> b -> Extend a b
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: Extend :: a -> b -> Extend a b
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: data Extend a b
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent p, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent c) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Extend p c)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type (:+) a b = Extend a b
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: [V0] :: IsBoxContent v0 => v0 -> Versioned v0 v1 0
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: [V1] :: IsBoxContent v1 => v1 -> Versioned v0 v1 1
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: data Versioned v0 v1 (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.Versioned v0 v1 version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: mediaDataBox :: ByteString -> Box' MediaData
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: [MovieHeader] :: KnownNat version => ((((((Versioned MovieHeaderTimesV0 MovieHeaderTimesV1 version :+ Template (I32 "rate") 65536) :+ Template (I16 "volume") 256) :+ Constant (I16 "reserved") 0) :+ Constant (I32Arr "reserved" 2) '[0, 0]) :+ Constant (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]) :+ Template (U32Arr "pre_defined" 6) '[0, 0, 0, 0, 0, 0]) :+ U32 "next_track_ID" -> MovieHeader version
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: [TrackHeader] :: (((((((Versioned TrackHeaderTimesV0 TrackHeaderTimesV1 version :+ Constant (I32Arr "reserved" 2) '[0, 0]) :+ Template (I16 "layer") 0) :+ Template (I16 "alternate_group") 0) :+ Template (I16 "volume") 256) :+ Constant (I16 "reserved") 0) :+ Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]) :+ I32 "width") :+ I32 "height" -> TrackHeader version
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: data Movie (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: data MovieHeader (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: data Track (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: data TrackHeader (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.Movie version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.MovieHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.Track version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.TrackHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.MovieHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.TrackHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.Movie version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.Track version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance GHC.TypeLits.KnownNat version => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.MovieHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: instance GHC.TypeLits.KnownNat version => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' (Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox.TrackHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: movieBox :: ValidBoxes (Movie version) ts => Boxes ts -> Box' (Movie version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: movieHeaderBox :: KnownNat version => MovieHeader version -> Box' (MovieHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: track :: ValidBoxes (Track version) ts => Boxes ts -> Box' (Track version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: trackHeader :: KnownNat version => TrackHeader version -> Box' (TrackHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: type MovieHeaderTimes uint = ((uint "creation_time" :+ uint "modification_time") :+ U32 "timescale") :+ uint "duration"
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: type TrackHeaderTimes uint = (((uint "creation_time" :+ uint "modification_time") :+ U32 "track_ID") :+ Constant (U32 "reserved") 0) :+ uint "duration"
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox: type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64)
- Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation.ProgressiveDownload
- Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation.ProgressiveDownload
- Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxRules Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
- Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType' Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
+ Data.ByteString.IsoBaseFileFormat.Boxes: [MediaFile] :: (ValidTopLevel brand ts) => Boxes brand ts -> MediaFile brand
+ Data.ByteString.IsoBaseFileFormat.Boxes: data MediaFile brand
+ Data.ByteString.IsoBaseFileFormat.Boxes: packMediaFile :: MediaFile brand -> ByteString
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: ($:) :: (Boxes brand '[l] -> r) -> Box brand l -> r
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:<>] :: Boxes brand l -> Boxes brand r -> Boxes brand (l :++ r)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:|] :: Box brand l -> Box brand r -> Boxes brand '[l, r]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: [Box] :: (IsBoxType b, IsBrandConform brand (Just b) ts) => BoxContent b -> Boxes brand ts -> Box brand b
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: [NoBoxes] :: Boxes brand '[]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: class (IsBoxContent (BoxContent t)) => IsBoxType t where type BoxContent t type BoxContent t = () where {
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Box brand b
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: infixr 3 $:
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Box brand cnt)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Boxes brand bs)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.Text.Internal.Text
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: singletonBox :: Box brand l -> Boxes brand '[l]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: toBoxType :: IsBoxType t => proxy t -> BoxContent t -> BoxType
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: (:+) :: a -> b -> (:+) a b
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [fromScalar] :: Scalar scalartype -> scalartype
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: data (:+) a b
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent p, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent c) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (p Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.:+ c)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance (Data.Default.Class.Default a, Data.Default.Class.Default b) => Data.Default.Class.Default (a Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.:+ b)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance GHC.TypeLits.KnownSymbol str => Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit Data.Text.Internal.Text str
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k) (len :: GHC.Types.Nat) o. GHC.Classes.Eq o => GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k) (len :: GHC.Types.Nat) o. GHC.Show.Show o => GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k k1 (o :: k) (v :: k1). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Constant o v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (len :: GHC.Types.Nat) (label :: k). (Data.Default.Class.Default o, GHC.TypeLits.KnownNat len) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (v :: k). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Template o v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). Data.Default.Class.Default scalartype => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: relabelScalar :: Scalar t l -> Scalar t l'
+ Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: templateValue :: FromTypeLit o v => Template o v -> o
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: OnceMandatory :: Type -> BoxForrest -> BoxTree
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: OnceOptional :: Type -> BoxForrest -> BoxTree
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: SomeMandatory :: Type -> BoxForrest -> BoxTree
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: SomeOptional :: Type -> BoxForrest -> BoxTree
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: class KnownNat (GetVersion brand) => IsBrand brand where type BoxLayout brand :: BoxForrest type GetVersion brand :: Nat type BoxLayout brand = '[] type GetVersion brand = 0 where {
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: data BoxTree
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type BoxForrest = [BoxTree]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type BoxLayout brand = '[];
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type GetVersion brand = 0;
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type OM b bs = OnceMandatory b bs
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type OM_ b = OnceMandatory b '[]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type OO b bs = OnceOptional b bs
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type OO_ b = OnceOptional b '[]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type SM b bs = SomeMandatory b bs
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type SM_ b = SomeMandatory b '[]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type SO b bs = SomeOptional b bs
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type SO_ b = SomeOptional b '[]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type ValidBox b t = IsBrandConform b (Just t) '[]
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type ValidContainerBox b t ts = IsBrandConform b (Just t) ts
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type ValidTopLevel b ts = IsBrandConform b Nothing ts
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: type family GetVersion brand :: Nat;
+ Data.ByteString.IsoBaseFileFormat.Boxes.Brand: }
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
+ Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: [FullBox] :: BoxVersion version -> BoxFlags 24 -> t -> FullBox version t
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: AudioTrack :: HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: AuxilliaryVideoTrack :: HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: HintTrack :: HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: TimedMetadataTrack :: HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: VideoTrack :: HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: [Handler] :: Constant (U32 "pre_defined") 0 :+ (HandlerType :+ (Constant (U32Arr "reserved" 3) '[0, 0, 0] :+ Template Text "")) -> Handler
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: data HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: handler :: (ValidBox brand Handler) => Handler -> Box brand Handler
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: newtype Handler
+ Data.ByteString.IsoBaseFileFormat.Boxes.Language: data Language
+ Data.ByteString.IsoBaseFileFormat.Boxes.Language: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Language.Language
+ Data.ByteString.IsoBaseFileFormat.Boxes.Language: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.Language.Language
+ Data.ByteString.IsoBaseFileFormat.Boxes.Language: instance Data.String.IsString Data.ByteString.IsoBaseFileFormat.Boxes.Language.Language
+ Data.ByteString.IsoBaseFileFormat.Boxes.Language: mkLanguage :: String -> Language
+ Data.ByteString.IsoBaseFileFormat.Boxes.Media: data Media
+ Data.ByteString.IsoBaseFileFormat.Boxes.Media: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.Media.Media
+ Data.ByteString.IsoBaseFileFormat.Boxes.Media: media :: ValidContainerBox brand Media ts => Boxes brand ts -> Box brand Media
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: mediaData :: ValidBox b MediaData => ByteString -> Box b MediaData
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: [MediaHeader] :: KnownNat v => Timing v :+ (Language :+ Constant (I16 "pre_defined") 0) -> MediaHeader v
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: data MediaHeader (v :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader.MediaHeader v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: instance GHC.TypeLits.KnownNat v => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType (Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader.MediaHeader v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: mediaHeader :: (KnownNat v, ValidBox brand (MediaHeader v)) => MediaHeader v -> Box brand (MediaHeader v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation: data MediaInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation.MediaInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation: mediaInformation :: ValidContainerBox brand MediaInformation ts => Boxes brand ts -> Box brand MediaInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.Movie: data Movie
+ Data.ByteString.IsoBaseFileFormat.Boxes.Movie: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.Movie.Movie
+ Data.ByteString.IsoBaseFileFormat.Boxes.Movie: movie :: (ValidContainerBox brand Movie ts) => Boxes brand ts -> Box brand Movie
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: [MovieHeader] :: KnownNat version => Timing version :+ (Template (I32 "rate") 65536 :+ (Template (I16 "volume") 256 :+ (Constant (I16 "reserved") 0 :+ (Constant (I32Arr "reserved" 2) '[0, 0] :+ (Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] :+ (Template (U32Arr "pre_defined" 6) '[0, 0, 0, 0, 0, 0] :+ Template (U32 "next_track_ID") 4294967295)))))) -> MovieHeader version
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: data MovieHeader (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader.MovieHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: instance GHC.TypeLits.KnownNat version => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType (Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader.MovieHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: movieHeader :: (KnownNat version, ValidBox brand (MovieHeader version)) => MovieHeader version -> Box brand (MovieHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimes uint = uint "creation_time" :+ (uint "modification_time" :+ (TimeScale :+ uint "duration"))
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64)
+ Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation.ProgressiveDownload
+ Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: [HintMediaHeader] :: U16 "maxPDUsize" :+ (U16 "avgPDUsize" :+ (U16 "maxbitrate" :+ (U16 "avgbitrate" :+ U32 "reserved"))) -> SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: [NullMediaHeader] :: SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: [SoundMediaHeader] :: Template (I16 "balance") 0 :+ Constant (U16Arr "opcolor" 3) '[0, 0, 0] -> SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: [VideoMediaHeader] :: Template (U16 "graphicsmode") 0 :+ Template (U16 "reserved") 0 -> SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: data SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader.SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader.SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader: specificMediaHeader :: ValidBox brand SpecificMediaHeader => SpecificMediaHeader -> Box brand SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.Time: durationFromSeconds :: Num t => TimeScale -> Integer -> t
+ Data.ByteString.IsoBaseFileFormat.Boxes.Time: mp4CurrentTime :: Num t => IO t
+ Data.ByteString.IsoBaseFileFormat.Boxes.Time: referenceTime :: UTCTime
+ Data.ByteString.IsoBaseFileFormat.Boxes.Time: type TimeScale = Template (U32 "timescale") 90000
+ Data.ByteString.IsoBaseFileFormat.Boxes.Time: type Timing (version :: Nat) = Versioned TimingV0 TimingV1 version
+ Data.ByteString.IsoBaseFileFormat.Boxes.Time: utcToMp4 :: Num t => UTCTime -> t
+ Data.ByteString.IsoBaseFileFormat.Boxes.Track: data Track
+ Data.ByteString.IsoBaseFileFormat.Boxes.Track: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType Data.ByteString.IsoBaseFileFormat.Boxes.Track.Track
+ Data.ByteString.IsoBaseFileFormat.Boxes.Track: track :: (ValidContainerBox brand Track ts) => Boxes brand ts -> Box brand Track
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: [TrackHeader] :: Versioned TrackHeaderTimesV0 TrackHeaderTimesV1 version :+ (Constant (I32Arr "reserved" 2) '[0, 0] :+ (Template (I16 "layer") 0 :+ (Template (I16 "alternate_group") 0 :+ (Template (I16 "volume") 256 :+ (Constant (I16 "reserved") 0 :+ (Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] :+ (I32 "width" :+ I32 "height"))))))) -> TrackHeader version
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: data TrackHeader (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader.TrackHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: instance GHC.TypeLits.KnownNat version => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxType (Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader.TrackHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: trackHeader :: (ValidBox brand (TrackHeader version), version ~ GetVersion brand) => TrackHeader version -> Box brand (TrackHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimes uint = uint "creation_time" :+ (uint "modification_time" :+ (U32 "track_ID" :+ (Constant (U32 "reserved") 0 :+ uint "duration")))
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: [V0] :: IsBoxContent v0 => v0 -> Versioned v0 v1 0
+ Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: [V1] :: IsBoxContent v1 => v1 -> Versioned v0 v1 1
+ Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: data Versioned v0 v1 (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: instance (version ~ 0, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent v0, Data.Default.Class.Default v0) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.Versioned.Versioned v0 v1 version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Versioned.Versioned v0 v1 version)
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: SingleTrackInit :: MovieHeader 0 -> TrackHeader 0 -> MediaHeader 0 -> Handler -> SpecificMediaHeader -> SingleTrackInit
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: [_hdlr] :: SingleTrackInit -> Handler
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: [_mdhd] :: SingleTrackInit -> MediaHeader 0
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: [_mvhd] :: SingleTrackInit -> MovieHeader 0
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: [_tkhd] :: SingleTrackInit -> TrackHeader 0
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: [_xmhd] :: SingleTrackInit -> SpecificMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: data Dash (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: data SingleTrackInit
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: instance GHC.TypeLits.KnownNat v => Data.ByteString.IsoBaseFileFormat.Boxes.Brand.IsBrand (Data.ByteString.IsoBaseFileFormat.Brands.Dash.Dash v)
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: mkSingleTrackInit :: SingleTrackInit -> MediaFile (Dash 0)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:.] :: Boxes ts -> Box' t -> Boxes (t : ts)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:.] :: Box brand l -> Boxes brand r -> Boxes brand (l : r)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: closedBox :: (IsBoxType' t, ValidBoxes t '[]) => BoxContent t -> Box' t
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: closedBox :: (IsBoxType t, IsBrandConform brand (Just t) '[]) => BoxContent t -> Box brand t
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: containerBox :: (IsBoxType' t, ValidBoxes t ts, BoxContent t ~ ()) => Boxes ts -> Box' t
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: containerBox :: (IsBoxType t, IsBrandConform brand (Just t) ts, BoxContent t ~ ()) => Boxes brand ts -> Box brand t
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Boxes (boxTypes :: [k])
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Boxes brand (boxTypes :: [Type])
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type family GetCardinality t (c :: k) :: Cardinality;
+ Data.ByteString.IsoBaseFileFormat.Boxes.Box: type family BoxContent t;
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: fileTypeBox :: FileType -> Box' FileType
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: fileTypeBox :: (ValidBox b FileType) => FileType -> Box b FileType
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: closedFullBox :: (IsBoxType' t, ValidBoxes t '[], BoxContent t ~ FullBox version c) => BoxVersion version -> BoxFlags 24 -> c -> Box' t
+ Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: closedFullBox :: (IsBoxType t, ValidBox brand t, BoxContent t ~ FullBox version c) => BoxVersion version -> BoxFlags 24 -> c -> Box brand t
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: fullBox :: (IsBoxType' t, ValidBoxes t ts, BoxContent t ~ FullBox version c) => BoxVersion version -> BoxFlags 24 -> c -> Boxes ts -> Box' t
+ Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: fullBox :: (IsBoxType t, ValidContainerBox brand t ts, BoxContent t ~ FullBox version c) => BoxVersion version -> BoxFlags 24 -> c -> Boxes brand ts -> Box brand t
- Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: pdinBox :: ProgressiveDownloadContent -> Box' ProgressiveDownload
+ Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: pdinBox :: ValidBox brand ProgressiveDownload => ProgressiveDownloadContent -> Box brand ProgressiveDownload
- Data.ByteString.IsoBaseFileFormat.Boxes.Skip: skipBox :: Skip -> Box' Skip
+ Data.ByteString.IsoBaseFileFormat.Boxes.Skip: skipBox :: ValidBox brand Skip => Skip -> Box brand Skip

Files

isobmff-builder.cabal view
@@ -1,5 +1,5 @@ name:                isobmff-builder-version:             0.3.0.0+version:             0.9.0.0 synopsis:            A (bytestring-) builder for the ISO-14496-12 base media file format description:         Please see README.md homepage:            https://github.com/sheyll/isobmff-builder#readme@@ -15,21 +15,37 @@  library   hs-source-dirs:      src-  exposed-modules:     Data.ByteString.IsoBaseFileFormat.Builder+  exposed-modules:     Data.ByteString.IsoBaseFileFormat.Boxes                      , Data.ByteString.IsoBaseFileFormat.Boxes.Box                      , Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Brand                      , Data.ByteString.IsoBaseFileFormat.Boxes.FileType                      , Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Handler+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Media                      , Data.ByteString.IsoBaseFileFormat.Boxes.MediaData-                     , Data.ByteString.IsoBaseFileFormat.Boxes.Skip+                     , Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader+                     , Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Movie+                     , Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader                      , Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation-                     , Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Language+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Skip+                     , Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Time+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Track+                     , Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader+                     , Data.ByteString.IsoBaseFileFormat.Boxes.Versioned+                     , Data.ByteString.IsoBaseFileFormat.Brands.Dash   build-depends:       base >= 4.9 && < 5-                     , bytestring >= 0.10.8.1-                     , type-list >= 0.5.0.0-                     -- , mtl-                     , vector-sized >= 0.3.2.0-                     , singletons >= 2.2+                     , bytestring >= 0.10.8.1 && < 0.11+                     , type-list >= 0.5.0.0 && < 0.6+                     , data-default >= 0.7.1.1 && < 0.8+                     , vector-sized >= 0.3.2.0 && < 0.4+                     , singletons >= 2.2 && < 3+                     , lens >= 4.14 && < 5+                     , time >= 1.6.0.1 && < 2+                     , text >= 1.2.2.1 && < 2   default-language:    Haskell2010   ghc-options:       -Wall -funbox-strict-fields -fno-warn-unused-do-bind   default-extensions:  ConstraintKinds@@ -67,11 +83,13 @@   main-is:             Spec.hs   other-modules:       BoxFieldsSpec                      , BoxSpec+                     , DashSpec   build-depends:       base >= 4.9 && < 5                      , bytestring >= 0.10.8.1                      , hspec                      , isobmff-builder                      , binary+                     , text >= 1.2.2.1 && < 2   default-language:    Haskell2010   default-extensions:  ConstraintKinds                      , CPP
spec/BoxFieldsSpec.hs view
@@ -1,47 +1,80 @@ module BoxFieldsSpec (spec) where  import Test.Hspec-import Data.ByteString.IsoBaseFileFormat.Builder+import Data.ByteString.IsoBaseFileFormat.Boxes -- import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Lazy as BL -- import qualified Data.Binary.Get as Binary import Control.Exception (evaluate)+import qualified Data.Text as T  -- import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Lazy as BL import -- qualified Data.Binary.Get as Binary- spec :: Spec spec =-  describe "Scalar, Constant, Template and ScalarArry composition" $-  describe "IsBoxContent instances" $-  do describe "example1" $-       do it "boxSize reports the correct size" $-             boxSize example1 `shouldBe` (1 + 1 + (3 * 8) + (7 * 8))-          it "crashes during rendering because of the invalid number of array elements for \"baz\"" $-             evaluate (renderBox example1') `shouldThrow` anyException-     describe "example2" $-       do it "boxSize reports the correct size" $-             boxSize example2 `shouldBe` (2 * 4 + 2 + 2 + 2 + 2 + 9 * 4 + 4 + 4)-          it "it renders the expected content" $-             renderBox example2 `shouldBe` (BL.pack [0,0,0,0,-                                                     0,0,0,0,-                                                        0,65,-                                                        0,66,-                                                         1,0,-                                                         0,0,-                                                     0,0,0,67,-                                                     0,0,0,68,-                                                     0,0,0,69,-                                                     0,0,0,70,-                                                     0,0,0,71,-                                                     0,0,0,72,-                                                     0,0,0,73,-                                                     0,0,0,74,-                                                     0,0,0,75,-                                                     0,0,0,76,-                                                     0,0,0,77])+  do describe "boxSize of Data.Text.Text" $+       it "returns string length + 1 (for the null termination byte)" $ do+          boxSize (T.pack "") `shouldBe` 1+          boxSize (T.pack "Hello!") `shouldBe` 7+     describe "boxBuilder of Data.Text.Text" $ do+       it "appends the null termination byte" $+          let expected = [72,101,108,108,111,32,119,111,114,108,100,33,0]+              actual = BL.unpack $ toLazyByteString $ boxBuilder (T.pack "Hello world!")+              in actual `shouldBe` expected+       it "appends the null termination byte" $+          let expected = [72,101,108,108,111,32,119,111,114,108,100,33,0]+              actual = BL.unpack $ toLazyByteString $ boxBuilder (T.pack "Hello world!")+              in actual `shouldBe` expected+       it "replaces embeded NULL characters with a space (0x20)" $+          let expected = [72,101,108,108,111,32,119,111,114,108,100,33,0]+              actual = BL.unpack $ toLazyByteString $ boxBuilder (T.pack "Hello\0world!")+              in actual `shouldBe` expected+     describe "mkLanguage" $+       do it "throws runtime exceptions when the code is too short or too long" $+            do evaluate (mkLanguage "") `shouldThrow` anyException+               evaluate (mkLanguage "a") `shouldThrow` anyException+               evaluate (mkLanguage "aa") `shouldThrow` anyException+               evaluate (mkLanguage "bbbb") `shouldThrow` anyException+               evaluate (mkLanguage "bbbbb") `shouldThrow` anyException+          it "throws runtime exceptions when the code is not in aaa .. zzz" $+            do evaluate (mkLanguage "! 3") `shouldThrow` anyException+               evaluate (mkLanguage "AAA") `shouldThrow` anyException+          it "renders lower case three-letter strings correctly" $+            let actual =+                  BL.unpack (toLazyByteString (boxBuilder (mkLanguage "deu")))+                expected =+                  BL.unpack (toLazyByteString (word16BE (4 * 1024 + 5 * 32 + 21)))+            in actual `shouldBe` expected+     describe "Scalar, Constant, Template and ScalarArry composition" $+       describe "IsBoxContent instances" $+       do describe "example1" $+            do it "boxSize reports the correct size" $ boxSize example1 `shouldBe`+                 (1 + 1 + (3 * 8) + (7 * 8))+               it "crashes during rendering because of the invalid number of array elements for \"baz\"" $+                 evaluate (renderBox example1') `shouldThrow`+                 anyException+          describe "example2" $+            do it "boxSize reports the correct size" $ boxSize example2 `shouldBe`+                 (2 * 4 + 2 + 2 + 2 + 2 + 9 * 4 + 4 + 4)+               it "it renders the expected content" $ renderBox example2 `shouldBe`+                 (BL.pack [0 ,0 ,0 ,0+                          ,0 ,0 ,0 ,0+                          ,0 ,65 ,0 ,66+                          ,1 ,0 ,0 ,0+                          ,0 ,0 ,0 ,67+                          ,0 ,0 ,0 ,68+                          ,0 ,0 ,0 ,69+                          ,0 ,0 ,0 ,70+                          ,0 ,0 ,0 ,71+                          ,0 ,0 ,0 ,72+                          ,0 ,0 ,0 ,73+                          ,0 ,0 ,0 ,74+                          ,0 ,0 ,0 ,75+                          ,0 ,0 ,0 ,76+                          ,0 ,0 ,0 ,77]) -renderBox :: IsBoxContent c => c -> BL.ByteString+renderBox :: IsBoxContent c+          => c -> BL.ByteString renderBox = toLazyByteString . boxBuilder  type ExampleContent = Scalar Word8 "bla" :+ Constant (Scalar Word8 "blub") 123 :+ Template (ScalarArray "foos" 3 Int64) '[1, 2, 3] :+ ScalarArray "baz" 7 Word64@@ -49,28 +82,16 @@ type ExampleContentShort = U8 "bla" :+ Constant (U8 "blub") 123 :+ Template (I64Arr "foos" 3) '[1, 2, 3] :+ U64Arr "baz" 7  example1 :: ExampleContent-example1 = Scalar 100 <+> Constant <+> Default <+> u64Arr [1,2,3]+example1 = Scalar 100 :+ Constant :+ Default :+ u64Arr [1,2,3]  example1' :: ExampleContentShort example1' = example1 -type Example2 isAudio =-     Constant (I32Arr "reserved" 2) '[0, 0]-  :+ Template (I16 "layer") 0-  :+ Template (I16 "alternate_group") 0-  :+ Template (I16 "volume") (If isAudio 256 0)-  :+ Constant (I16 "reserved") 0-  :+ Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]-  :+ I32 "width"-  :+ I32 "height"+type Example2 isAudio = Constant (I32Arr "reserved" 2) '[0, 0] :+ Template (I16 "layer") 0 :+ Template (I16 "alternate_group") 0 :+ Template (I16 "volume") (If isAudio 256 0) :+ Constant (I16 "reserved") 0 :+ Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] :+ I32 "width" :+ I32 "height"  example2 :: Example2 'True example2 =-  Constant <+>-  Custom 65 <+>-  Custom 66 <+>-  Default <+>-  Constant <+>-  Custom (i32Arr [67 .. 75]) <+>-  i32 76 <+>+  Constant :+ Custom 65 :+ Custom 66 :+ Default :+ Constant :++  Custom (i32Arr [67 .. 75]) :++  i32 76 :+   i32 77
spec/BoxSpec.hs view
@@ -1,7 +1,8 @@ module BoxSpec (spec) where  import Test.Hspec-import Data.ByteString.IsoBaseFileFormat.Builder+import Data.ByteString.IsoBaseFileFormat.Boxes+ import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Lazy as BL import qualified Data.Binary.Get as Binary@@ -22,10 +23,10 @@             do describe "boxSize" $                  do describe "a box with one nested box" $                       do it "returns the sum of both boxSizes" $-                           boxSize (testParentBox1 $ Nested :. testBox1) `shouldBe`+                           boxSize (testParentBox1 $ singletonBox testBox1) `shouldBe`                            (2 * boxSize testBox1)                          it "returns the same value as written by boxBuilder" $-                           let b = testParentBox1 $ Nested :. testBox1+                           let b = testParentBox1 $ singletonBox testBox1                                writtenSize =                                  let out = toLazyByteString (boxBuilder b)                                      getSize = Binary.runGet Binary.getWord32be@@ -33,25 +34,26 @@                                reportedSize = boxSize b                            in writtenSize `shouldBe` reportedSize +data TestBrand -data TestBox1+instance IsBrand TestBrand where+  type BoxLayout TestBrand =+    '[ 'OnceMandatory TestParentBox1 '[ 'SomeOptional TestBox1 '[]] ] -instance BoxRules TestBox1 where-  type RestrictedTo TestBox1 = 'Nothing+data TestBox1 -instance IsBoxType' TestBox1 where-  toBoxType' _ = StdType "tst1"+instance IsBoxType TestBox1 where+  toBoxType _ _ = StdType "tst1" -testBox1 :: Box' TestBox1+testBox1 :: Box TestBrand TestBox1 testBox1 = closedBox () - data TestParentBox1 -instance BoxRules TestParentBox1--instance IsBoxType' TestParentBox1 where-  toBoxType' _ = StdType "par1"+instance IsBoxType TestParentBox1 where+  toBoxType _ _ = StdType "par1" -testParentBox1 :: (ValidBoxes TestParentBox1 ts) => Boxes ts -> Box' TestParentBox1+testParentBox1+  :: ValidContainerBox TestBrand TestParentBox1 ts+  => Boxes TestBrand ts -> Box TestBrand TestParentBox1 testParentBox1 = containerBox
+ spec/DashSpec.hs view
@@ -0,0 +1,297 @@+{-# LANGUAGE OverloadedStrings #-}+module DashSpec (spec) where++import Test.Hspec+import Data.ByteString.IsoBaseFileFormat.Brands.Dash+import qualified Data.ByteString.Lazy as BL+import Data.Text ()++spec :: Spec+spec =+  do describe "minimalIsobmff version 0" $+       do it "renders some output at all" $+            do createionTime <- mp4CurrentTime+               let ct :: Word32+                   ct = fromScalar createionTime+                   ct3 = (ct `shiftR` 24) .&. 255+                   ct2 = (ct `shiftR` 16) .&. 255+                   ct1 = (ct `shiftR` 8) .&. 255+                   ct0 = (ct `shiftR` 0) .&. 255+                   cts :: [Word8]+                   cts = fromIntegral <$> [ct3,ct2,ct1,ct0]+               let args = exampleSingleTrackInit createionTime+                   doc = mkSingleTrackInit args+                   rendered = BL.unpack $ packMediaFile doc+                   expected =+                     [0+                     ,0+                     ,0+                     ,32+                     ,102+                     ,116+                     ,121+                     ,112+                     ,105+                     ,115+                     ,111+                     ,53+                     ,0+                     ,0+                     ,0+                     ,0+                     ,105+                     ,115+                     ,111+                     ,109+                     ,105+                     ,115+                     ,111+                     ,53+                     ,100+                     ,97+                     ,115+                     ,104+                     ,109+                     ,112+                     ,52+                     ,50+                     ,0+                     ,0+                     ,1+                     ,73 -- Here+                     ,109+                     ,111+                     ,111+                     ,118+                     ,0+                     ,0+                     ,0+                     ,108+                     ,109+                     ,118+                     ,104+                     ,100+                     ,0+                     ,0+                     ,0+                     ,0] +++                     cts +++                     [0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,95+                     ,144+                     ,0+                     ,1+                     ,95+                     ,144+                     ,0+                     ,1+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,64+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,255+                     ,255+                     ,255+                     ,255+                     ,0+                     ,0+                     ,0+                     ,213 -- Here+                     ,116+                     ,114+                     ,97+                     ,107+                     ,0+                     ,0+                     ,0+                     ,92+                     ,116+                     ,107+                     ,104+                     ,100+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,95+                     ,144+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,1+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,64+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0+                     ,0,0,0,113 -- HERE+                     ,109,100,105,97+                     ,0,0,0,32,109,100,104,100,0,0,0,0+                     ,0,0,0,0,0,0,0,0,0,1,95,144,0,0,0,0,16,181,0,0+                     ,0,0,0,45 -- HERE+                     ,104,100,108,114+                     ,0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0+                     ,72,101,108,108,111,32,119,111,114,108,100,33,0+                     ,0,0,0,28 -- HERE+                     ,109,105,110,102+                     ,0,0,0,20 -- HERE+                     ,115,109,104,100,0,0,0,0,0,0,0,0,0,0,0,0]+               -- BL.writeFile "/tmp/xxx.mp4" (BL.pack rendered)+               rendered `shouldBe`+                 expected++exampleSingleTrackInit :: U32 "creation_time" -> SingleTrackInit+exampleSingleTrackInit creationTime =+  SingleTrackInit (MovieHeader $+                   V0 (creationTime :+ 0 :+ Default :+ durationFromSeconds Default 1) :++                   def)+                  (TrackHeader $+                   V0 (0 :+ 0 :+ 1 :+ Constant :+ durationFromSeconds Default 1) :++                   def)+                  (MediaHeader $ def)+                  (Handler $ def :+ AudioTrack :+ def :+ (Custom "Hello world!"))+                  (SoundMediaHeader def)
+ src/Data/ByteString/IsoBaseFileFormat/Boxes.hs view
@@ -0,0 +1,43 @@+-- | This module re-exports all modules needed to build /ISOBMFF/ documents.+module Data.ByteString.IsoBaseFileFormat.Boxes+  (module Data.ByteString.IsoBaseFileFormat.Boxes, module X)+  where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box as X+import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields as X+import Data.ByteString.IsoBaseFileFormat.Boxes.FileType as X+import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Handler as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Media as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MediaData as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Movie as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader as X+import Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Language as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Skip as X+import Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Time as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Track as X+import Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader as X+import Data.ByteString.IsoBaseFileFormat.Boxes.Versioned as X+import qualified Data.ByteString.Lazy as BL++import Data.Int as X+import Data.Kind as X  (Type, Constraint)+import Data.Maybe as X+import Data.Type.Bool as X+import Data.Type.Equality as X+import Text.Printf as X+import Data.Default as X++-- * MediaFiles++-- | The toplevel container for all boxes of a media file.+data MediaFile brand where+  MediaFile :: (ValidTopLevel brand ts) => Boxes brand ts -> MediaFile brand++-- | Generate a lazy 'ByteString' with the contents of a 'MediaFile'+packMediaFile :: MediaFile brand -> BL.ByteString+packMediaFile (MediaFile bs) = toLazyByteString (boxBuilder bs)
src/Data/ByteString/IsoBaseFileFormat/Boxes/Box.hs view
@@ -12,45 +12,26 @@        (module Data.ByteString.IsoBaseFileFormat.Boxes.Box, module X)        where +import Data.ByteString.IsoBaseFileFormat.Boxes.Brand as X import Data.Bits as X import Data.ByteString.Builder as X import Data.Monoid as X import Data.Proxy as X import Data.Word as X+import Data.Kind import GHC.TypeLits as X import Data.String-import Data.Type.Equality-import Data.Type.List-import Data.Type.Bool+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Data.Singletons.Prelude.List ((:++)) import qualified Data.ByteString as B --- * Basic Types and classes-+-- * Box Type Classes -- | Base class for all (abstract/phantom/normal-) types that represent boxes-class (IsBoxContent (BoxContent t), BoxRules t) => IsBoxType' t where+class (IsBoxContent (BoxContent t)) => IsBoxType t  where   type BoxContent t   type BoxContent t = ()-  toBoxType' :: proxy t -> BoxType---- | A class that describes (on the type level) how a box can be nested into--- other boxes (see 'Boxes).-class BoxRules (t :: k) where-  -- | List of boxes that this box can be nested into.-  type RestrictedTo t :: Maybe [k]-  type RestrictedTo t = 'Just '[]-  -- | If the box is also allowed 'top-level' i.e. in the file directly, not-  -- nested in an other box.-  type IsTopLevelBox t :: Bool-  type IsTopLevelBox t = 'True-  -- | Describes which nested boxes MUST be present in a box using 'boxes'.-  type RequiredNestedBoxes t :: [k]-  type RequiredNestedBoxes t = '[]-  -- | Describes how many times a box should be present in a container (-box).-  type GetCardinality t (c :: k) :: Cardinality-  type GetCardinality t any = 'ExactlyOnce---- | Describes how many times a box should be present in a container.-data Cardinality = AtMostOnce | ExactlyOnce | OnceOrMore+  toBoxType :: proxy t -> BoxContent t -> BoxType  -- | Types that go into a box. A box content is a piece of data that can be -- reused in different instances of 'IsBox'. It has no 'BoxType' and hence@@ -60,57 +41,72 @@   boxBuilder :: a -> Builder  -- * Data types- -- | A type that wraps the contents of a box and the box type.-data Box' b where-  Box' :: (IsBoxType' b, ValidBoxes b ts) => BoxContent b -> Boxes ts -> Box' b+data Box brand b where+        Box ::+            (IsBoxType b, IsBrandConform brand ('Just b) ts) =>+            BoxContent b -> Boxes brand ts -> Box brand b -instance IsBoxContent (Box' cnt) where-  boxBuilder b@(Box' cnt nested) = sB <> tB <> sExtB <> tExtB <> cntB <> nestedB-    where s       = boxSize    b-          t       = toBoxType' b-          sB      = boxBuilder s-          sExtB   = boxBuilder (BoxSizeExtension s)-          tB      = boxBuilder t-          tExtB   = boxBuilder (BoxTypeExtension t)-          cntB    = boxBuilder cnt+instance IsBoxContent (Box brand cnt) where+  boxBuilder b@(Box cnt nested) = sB <> tB <> sExtB <> tExtB <> cntB <> nestedB+    where s = boxSize b+          t = toBoxType b cnt+          sB = boxBuilder s+          sExtB = boxBuilder (BoxSizeExtension s)+          tB = boxBuilder t+          tExtB = boxBuilder (BoxTypeExtension t)+          cntB = boxBuilder cnt           nestedB = boxBuilder nested--  boxSize b@(Box' cnt nested) = sPayload + boxSize (BoxSizeExtension sPayload)-    where sPayload =   boxSize (BoxSize undefined)-                     + boxSize t-                     + boxSize cnt-                     + boxSize (BoxTypeExtension t)-                     + boxSize nested-          t        = toBoxType' b+  boxSize b@(Box cnt nested) = sPayload + boxSize (BoxSizeExtension sPayload)+    where sPayload =+            boxSize (BoxSize undefined) + boxSize t + boxSize cnt ++            boxSize (BoxTypeExtension t) ++            boxSize nested+          t = toBoxType b cnt  -- | A heterogenous collection of boxes.-data Boxes (boxTypes :: [k]) where-        Nested :: Boxes '[]-        (:.) :: Boxes ts -> Box' t -> Boxes (t ': ts)+data Boxes brand (boxTypes :: [Type]) where+        NoBoxes :: Boxes brand '[]+        (:.) :: Box brand l -> Boxes brand r -> Boxes brand (l ': r)+        -- | Create a 'Boxes' collection from two 'Box'es+        (:|) :: Box brand l -> Box brand r -> Boxes brand '[l, r]+        (:<>) :: Boxes brand l -> Boxes brand r -> Boxes brand (l :++ r) -infixl 2 :.+infixr 1 :<>+infixr 2 :.+infixr 2 :|+infixr 3 $: -instance IsBoxContent (Boxes bs) where-  boxSize Nested = 0-  boxSize (bs :. b) = boxSize bs + boxSize b-  boxBuilder Nested = mempty-  boxBuilder (bs :. b) = boxBuilder bs <> boxBuilder b+-- | Apply a function to a 'Boxes' collection containing only a single 'Box'.+($:) :: (Boxes brand '[l] -> r) -> Box brand l -> r+($:) f = f . singletonBox +-- | Create a 'Boxes' collection with a single 'Box'.+singletonBox :: Box brand l -> Boxes brand '[l]+singletonBox b = b :. NoBoxes+++instance IsBoxContent (Boxes brand bs) where+  boxSize NoBoxes = 0+  boxSize (l :. r) = boxSize l + boxSize r+  boxSize (l :| r) = boxSize l + boxSize r+  boxSize (l :<> r) = boxSize l + boxSize r+  boxBuilder NoBoxes = mempty+  boxBuilder (l :. r) = boxBuilder l <> boxBuilder r+  boxBuilder (l :| r) = boxBuilder l <> boxBuilder r+  boxBuilder (l :<> r) = boxBuilder l <> boxBuilder r+ -- | A box that contains no nested boxes.-closedBox :: (IsBoxType' t, ValidBoxes t '[]) => BoxContent t -> Box' t-closedBox c = Box' c Nested+closedBox :: (IsBoxType t, IsBrandConform brand ('Just t) '[])+          => BoxContent t -> Box brand t+closedBox c = Box c NoBoxes  -- | A box that contains no fields, but nested boxes.-containerBox :: (IsBoxType' t, ValidBoxes t ts, BoxContent t ~ ()) => Boxes ts -> Box' t-containerBox = Box' ()---- | A complete media file, consisting of top-level boxes.-mediaFile :: Boxes ts -> Builder-mediaFile = boxBuilder+containerBox :: (IsBoxType t,IsBrandConform brand ('Just t) ts,BoxContent t ~ ())+             => Boxes brand ts -> Box brand t+containerBox = Box ()  -- * Box Size and Type- -- | The size of the box. If the size is limited to a (fixed) value, it can be -- provided as a 'Word64' which will be represented as either a 32bit compact -- size or as 64 bit /largesize/. If 'UnlimitedSize' is used, the box extends to@@ -215,90 +211,7 @@                  (take (16 * 4) str) ++              repeat (word8 0)) --- * Type-safe box composition----- * Type level consistency checks---- | A type-level check that uses 'BoxRules' to check that the contained boxes--- are standard conform.-type ValidBoxes t ts =-  ( AllAllowedIn t ts ~ 'True-  , HasAllRequiredBoxes t (RequiredNestedBoxes t) ts ~ 'True )---- | A type function to check that all nested boxes are allowed in the--- container.-type family AllAllowedIn (container :: k) (boxes :: [k]) :: Bool-     where-        AllAllowedIn c '[] = 'True-        AllAllowedIn c (t ': ts) =-          If (CheckAllowedIn c t (RestrictedTo t))-             (AllAllowedIn c ts)-             (TypeError (NotAllowedMsg c t))--type family CheckAllowedIn (c :: k) (t :: k) (a :: Maybe [k]) :: Bool where-  CheckAllowedIn c t 'Nothing   = 'True-  CheckAllowedIn c t ('Just rs) = Find c rs----- | The custom (type-) error message for 'AllAllowedIn'.-type NotAllowedMsg c t =-  'Text "Boxes of type: "-  ':<>: 'ShowType c-  ':<>: 'Text " may not contain boxes of type "-  ':<>: 'ShowType t-  ':$$: 'Text "Valid containers for "-  ':<>: 'ShowType t-  ':<>: 'Text " boxes are: "-  ':$$: 'ShowType (RestrictedTo t)-  ':$$: 'ShowType t-  ':<>: If (IsTopLevelBox c)-          ('Text " boxes may appear top-level in a file.")-          ('Text " boxes must be nested.")----- | Check that all required boxes have been nested.-type family HasAllRequiredBoxes (c :: k) (req :: [k]) (nested :: [k]) :: Bool-     where-       HasAllRequiredBoxes c '[] nested = 'True-       HasAllRequiredBoxes c (r ': restReq) nested =-         If (Find r nested)-            (HasAllRequiredBoxes c restReq nested)-            (TypeError (MissingRequired c r nested))--type IsSubSet base sub = Intersection base sub == sub---- | The custom (type-) error message for 'HasAllRequiredBoxes.-type MissingRequired c r nested =-  'Text "Boxes of type: "-  ':<>: 'ShowType c-  ':<>: 'Text " require these nested boxes: "-  ':<>: 'ShowType (RequiredNestedBoxes c)-  ':$$: 'Text "but only these box types were nested: "-  ':<>: 'ShowType nested-  ':$$: 'Text "e.g. this type is missing: "-  ':<>: 'ShowType r---- | Check that all boxes may appear top-level.-type family CheckAllTopLevelOk (ts :: [k]) :: Bool where-   CheckAllTopLevelOk '[] = 'True-   CheckAllTopLevelOk (t ': rest) = CheckTopLevelOk t && CheckAllTopLevelOk rest---- | Check that the box may appear top-level.-type family CheckTopLevelOk (t :: k) :: Bool where-   CheckTopLevelOk t = IsTopLevelBox t || TypeError (NotTopLevenError t)----- | The custom (type-) error message indicating that a box may not appear--- top-level.-type NotTopLevenError c =-        'Text "Boxes of type "-  ':<>: 'ShowType c-  ':<>: 'Text " MUST be nested inside boxes of these types: "-  ':$$: 'ShowType (RestrictedTo c)- -- * 'IsBoxContent' instances- -- | An empty box content can by represented by @()@ (i.e. /unit/). instance IsBoxContent () where   boxSize _ = 0@@ -307,4 +220,13 @@ -- | Trivial instance for 'ByteString' instance IsBoxContent B.ByteString where   boxSize = fromIntegral . B.length-  boxBuilder = byteString+  boxBuilder = byteString-- -- | A list, a maybe, and every other 'Foldable' of contents is a content.+                         -- instance (Foldable f, IsBoxContent t) => IsBoxContent (f t) where+                         --   boxSize = foldr' (\e acc -> acc + boxSize e) 0+                         --   boxBuilder = foldMap boxBuilder++-- | This 'Text' instance writes a null terminated UTF-8 string.+instance IsBoxContent T.Text where+  boxSize = (1+) . fromIntegral . T.length+  boxBuilder txt = boxBuilder (T.encodeUtf8 txtNoNulls) <> word8 0+    where txtNoNulls = T.map (\c -> if c == '\0' then ' ' else c) txt
src/Data/ByteString/IsoBaseFileFormat/Boxes/BoxFields.hs view
@@ -4,12 +4,14 @@        where  import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.Default import Data.Int import Data.Maybe import Text.Printf import Data.Singletons import Data.Singletons.Prelude.List import qualified Data.Vector.Sized as Vec+import qualified Data.Text as T  -- * Scalar box fields @@ -59,8 +61,14 @@ -- smart constructors, e.g. 'u8','i8','u16','i16','u32','i32','u64','i64' or the -- 'Num' instance, whereas the constructors might give a bit more safety. newtype Scalar scalartype (label :: k) =-  Scalar scalartype deriving (Show, Read, Ord, Eq, Num)+  Scalar {fromScalar :: scalartype}+  deriving (Show, Read, Ord, Eq, Num, Default) +-- | Relabel a scalar value, e.g. convert a @Scalar U32 "foo"@ to a @Scalar U32+-- "bar"@.+relabelScalar :: Scalar t l -> Scalar t l'+relabelScalar (Scalar x) = (Scalar x)+ instance IsBoxContent (Scalar Word8 label) where   boxSize _ = 1   boxBuilder (Scalar v) = word8 v@@ -153,7 +161,11 @@ -- 'u8Arr','i8Arr','u16Arr','i16Arr','u32Arr','i32Arr','u64Arr','i64Arr' . newtype ScalarArray (label :: k) (len :: Nat) o where         ScalarArray :: Vec.Vector n o -> ScalarArray label n o+        deriving (Show,Eq) +instance (Default o,KnownNat (len :: Nat)) => Default (ScalarArray label len o) where+  def = ScalarArray $ Vec.replicate def+ instance (Num o,IsBoxContent (Scalar o label),KnownNat (len :: Nat)) => IsBoxContent (ScalarArray label len o) where   boxSize (ScalarArray vec) =     fromIntegral (Vec.length vec) * boxSize (Scalar 0 :: Scalar o label)@@ -182,7 +194,8 @@ -- * Constant fields  -- | Wrapper around a field, e.g. a 'Scalar' or 'ScalarArray', with a type level--- value. The wrapped content must implement 'FromTypeLit'.+-- value. The wrapped content must implement 'FromTypeLit'. To get the value of+-- a 'Constant'  use 'fromTypeLit'. data Constant o v where         Constant :: Constant o v @@ -190,6 +203,9 @@   boxSize = boxSize . fromTypeLit   boxBuilder = boxBuilder . fromTypeLit +instance Default (Constant o v) where+  def = Constant+ -- * Template Fields  -- | Fields with default values that can be overriden with custom value. Like@@ -200,10 +216,17 @@         Default :: Template o v         Custom :: o -> Template o v +instance Default (Template o v) where+  def = Default++-- | Get a value from a 'Template'.+templateValue :: FromTypeLit o v => Template o v -> o+templateValue d@Default = fromTypeLit d+templateValue (Custom v) = v+ instance (IsBoxContent o,FromTypeLit o v) => IsBoxContent (Template o v) where-  boxSize = boxSize . fromTypeLit-  boxBuilder d@Default = boxBuilder $ fromTypeLit d-  boxBuilder (Custom o) = boxBuilder o+  boxSize = boxSize . templateValue+  boxBuilder = boxBuilder . templateValue  -- * Conversion from type-level numbers and lists to values @@ -220,20 +243,19 @@         vs' = fromIntegral <$> vs     in ScalarArray (fromJust (Vec.fromList vs')) +instance KnownSymbol str => FromTypeLit T.Text (str :: Symbol) where+  fromTypeLit = T.pack . symbolVal+ -- * Box concatenation  -- | Box content composition-data Extend a b =-  Extend a-         b+data a :+ b = a :+ b --- | An operator for 'Extend'.-type a :+ b = Extend a b+infixr 3 :+ --- | An operator for 'Extend'.-(<+>) :: a -> b -> Extend a b-(<+>) = Extend+instance (IsBoxContent p,IsBoxContent c) => IsBoxContent (p :+ c) where+  boxSize (p :+ c) = boxSize p + boxSize c+  boxBuilder (p :+ c) = boxBuilder p <> boxBuilder c -instance (IsBoxContent p,IsBoxContent c) => IsBoxContent (Extend p c) where-  boxSize (Extend p c) = boxSize p + boxSize c-  boxBuilder (Extend p c) = boxBuilder p <> boxBuilder c+instance (Default a, Default b) => Default (a :+ b) where+  def = def :+ def
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Brand.hs view
@@ -0,0 +1,217 @@+-- | Brand/Box-validation+{-# LANGUAGE UndecidableInstances #-}+module Data.ByteString.IsoBaseFileFormat.Boxes.Brand+        (IsBrand(..), ValidBox, ValidContainerBox, ValidTopLevel,+        IsBrandConform, BoxTree(..), BoxForrest,+        OM,OM_,OO,OO_,SM,SM_,SO,SO_)+        where++import Data.Kind+import Data.Type.Bool+import GHC.TypeLits+-- import GHC.Exts+import Data.Singletons (Apply, type (~>))+import Data.Singletons.Prelude.List as S (Map, (:++))+import Data.Type.List (Find)++-- | A class that describes (on the type level) how a box can be nested into+-- other boxes (see 'Boxes).+class KnownNat (GetVersion brand) => IsBrand brand  where+  type BoxLayout brand :: BoxForrest+  type BoxLayout brand = '[]+  type GetVersion brand :: Nat+  type GetVersion brand = 0++-- | Mandatory, container box, exactly one+type OM b bs = 'OnceMandatory b bs+-- | Optional, container box, zero or one+type OO b bs = 'OnceOptional b bs+-- | Mandatory, container box, one or more+type SM b bs = 'SomeMandatory b bs+-- | Optional, container box, zero or more+type SO b bs = 'SomeOptional b bs++-- | Mandatory, exactly one, no children+type OM_ b = 'OnceMandatory b '[]+-- | Optional, zero or one, no children+type OO_ b = 'OnceOptional b '[]+-- | Mandatory, one or more, no children+type SM_ b = 'SomeMandatory b '[]+-- | Optional, zero or more, no children+type SO_ b = 'SomeOptional b '[]++-- | Boxes that valid according to the box structure defined in a 'IsBrand'+-- instance, i.e. where 'IsBrandConform' holds.+type family+  IsBrandConform (b :: Type) (parent :: Maybe Type) (ts :: [Type]) :: Constraint where+  IsBrandConform b 'Nothing ts =+    IsBrandConformImpl b (TopLevel b) ts (BoxLayout b)+  IsBrandConform b ('Just parent) ts =+    IsBrandConformImpl b parent ts (LookUpSubtrees parent (BoxLayout b))++-- | Convenience wrapper around @(IsBrandConform b ('Just t) '[])@+type ValidBox b t = IsBrandConform b ('Just t) '[]++-- | Convenience wrapper around @(IsBrandConform b ('Just t) ts)@+type ValidContainerBox b t ts = IsBrandConform b ('Just t) ts++-- | Convenience wrapper around @(IsBrandConform b 'Nothing ts)@+type ValidTopLevel b ts = IsBrandConform b 'Nothing ts+++-- | Define the cardinality and valid child boxes of a box.+data BoxTree+  = OnceOptional Type+        BoxForrest+  | OnceMandatory Type+        BoxForrest+  | SomeOptional Type+        BoxForrest+  | SomeMandatory Type+        BoxForrest++-- | A list of 'BoxTree's+type BoxForrest = [BoxTree]++-- * Implementation++-- | A type for marking top-level boxes in TypeError messages, in the+-- 'IsBrandConformImpl' constraint.+data TopLevel :: t -> Type+++type family+  LookUpSubtrees t (trees :: BoxForrest) :: BoxForrest where+    LookUpSubtrees t '[] = '[]+    LookUpSubtrees t ('OnceOptional t sub ': rest) = sub+    LookUpSubtrees t ('OnceOptional u sub ': rest) = LookUpSubtrees t (sub :++ rest)+    LookUpSubtrees t ('OnceMandatory t sub ': rest) = sub+    LookUpSubtrees t ('OnceMandatory u sub ': rest) = LookUpSubtrees t (sub :++ rest)+    LookUpSubtrees t ('SomeOptional t sub ': rest) = sub+    LookUpSubtrees t ('SomeOptional u sub ': rest) = LookUpSubtrees t (sub :++ rest)+    LookUpSubtrees t ('SomeMandatory t sub ': rest) = sub+    LookUpSubtrees t ('SomeMandatory u sub ': rest) = LookUpSubtrees t (sub :++ rest)++-- | A constraint that is solved if all 'Box'es layed out in accordance with the+-- 'BoxLayout' if an 'IsBrand' instance.+type IsBrandConformImpl b (info :: Type) (ts :: [Type]) (boxForrest :: BoxForrest) =+  ( IsBrand b+  , ReportIt '[AllRequiredBoxes+                 boxForrest+                 ts]+  , ReportIt '[OnlyValidBoxes info+                 boxForrest+                 ts]+  , ReportIt (Map (RuleAppliesFun info ts)+                  boxForrest))++type family+  ReportIt (es :: [Maybe ErrorMessage]) :: Constraint where+    ReportIt '[] = ()+    ReportIt ('Nothing ': rest) = ReportIt rest+    ReportIt ('Just e ': rest) = TypeError e++type family+  AllRequiredBoxes (f :: BoxForrest) (ts :: [t]) :: Maybe ErrorMessage where+    AllRequiredBoxes '[] children = 'Nothing++    AllRequiredBoxes ('OnceMandatory c sub ': rules) '[] =+      'Just ('Text "OnceMandatory box '"+             ':<>: 'ShowType c ':<>: 'Text "' missing, or out of order.")+    AllRequiredBoxes ('SomeMandatory c sub ': rules) '[] =+      'Just ('Text "SomeMandatory box '"+             ':<>: 'ShowType c ':<>: 'Text "' missing, or out of order.")++    AllRequiredBoxes ('OnceMandatory c sub ': rules) (c ': children) =+      AllRequiredBoxes rules children+    AllRequiredBoxes ('SomeMandatory c sub ': rules) (c ': children) =+      AllRequiredBoxes rules (RemoveNext c children)++    AllRequiredBoxes ('OnceMandatory c sub ': rules) children =+      AllRequiredBoxes rules children+    AllRequiredBoxes ('SomeMandatory c sub ': rules) children =+      AllRequiredBoxes rules children++    AllRequiredBoxes ('OnceOptional c sub ': rules) (c ': children) =+      AllRequiredBoxes rules children+    AllRequiredBoxes ('OnceOptional c sub ': rules) children =+      AllRequiredBoxes rules children+    AllRequiredBoxes ('SomeOptional c sub ': rules) children =+      AllRequiredBoxes rules (RemoveNext c children)++type family+  OnlyValidBoxes (r :: t) (f :: BoxForrest) (ts :: [t]) :: Maybe ErrorMessage where+    OnlyValidBoxes r rules (c ': children) =+      If (Find c (ExtractBoxes rules))+         (OnlyValidBoxes r rules children)+         ('Just ('Text "Invalid box '" ':<>: 'ShowType c+                 ':<>: 'Text "' in box '" ':<>: 'ShowType r ':<>: 'Text "'"))+    OnlyValidBoxes r rules '[] = 'Nothing++type family+  ExtractBoxes (f :: BoxForrest) :: [t] where+    ExtractBoxes '[] = '[]+    ExtractBoxes ('OnceMandatory c sub ': rules) =+      c ': ExtractBoxes rules+    ExtractBoxes ('SomeMandatory c sub ': rules) =+      c ': ExtractBoxes rules+    ExtractBoxes ('OnceOptional c sub ': rules) =+      c ': ExtractBoxes rules+    ExtractBoxes ('SomeOptional c sub ': rules) =+      c ': ExtractBoxes rules++type family+  RemoveNext (t :: k) (ts :: [k]) :: [k] where+    RemoveNext t (t ': ts) = RemoveNext t ts+    RemoveNext t ts = ts++data RuleAppliesFun :: t -> [t] -> BoxTree ~> Maybe ErrorMessage++type instance Apply (RuleAppliesFun parent childBoxes) rules =+  RuleApplies parent childBoxes rules++type family+  RuleApplies (parent :: t) (childBoxes :: [t]) (rules :: BoxTree) :: Maybe ErrorMessage where+  -- Zero or more+  RuleApplies parent children ('SomeOptional other sub) =+    'Nothing+  -- zero or one+  RuleApplies parent (child ': others) ('OnceOptional child sub) =+    If (Find child others)+       ('Just ('Text "It is not allowed to have more than one '"+               ':<>: 'ShowType child+               ':<>: 'Text "' in '"+               ':<>: 'ShowType parent+               ':<>: 'Text "'."))+      'Nothing+  RuleApplies parent (notChild ': others) ('OnceOptional child sub) =+    RuleApplies parent others ('OnceOptional child sub)+  RuleApplies parent '[] ('OnceOptional child sub) = 'Nothing+  -- exactly one+  RuleApplies parent (child ': others) ('OnceMandatory child sub) =+    If (Find child others)+       ('Just ('Text "It is not allowed to have more than one '"+               ':<>: 'ShowType child+               ':<>: 'Text "' in '"+               ':<>: 'ShowType parent+               ':<>: 'Text "'."))+      'Nothing+  RuleApplies parent (notChild ': others) ('OnceMandatory child sub) =+    RuleApplies parent others ('OnceMandatory child sub)+  RuleApplies parent '[] ('OnceMandatory child sub) =+    'Just ('Text "Need exactly one '"+           ':<>: 'ShowType child+           ':<>: 'Text "' in '"+           ':<>: 'ShowType parent+           ':<>: 'Text "'.")+  -- OnceMandatory or more+  RuleApplies parent (child ': others) ('SomeMandatory child sub) =+    'Nothing+  RuleApplies parent (notChild ': others) ('SomeMandatory child sub) =+    RuleApplies parent others ('SomeMandatory child sub)+  RuleApplies parent '[] ('SomeMandatory child sub) =+    'Just ('Text "Need at least one '"+           ':<>: 'ShowType child+           ':<>: 'Text "' in '"+           ':<>: 'ShowType parent+           ':<>: 'Text "'.")
src/Data/ByteString/IsoBaseFileFormat/Boxes/FileType.hs view
@@ -3,16 +3,14 @@ import Data.ByteString.IsoBaseFileFormat.Boxes.Box  -- | File Type Box--instance BoxRules FileType--instance IsBoxType' FileType where+instance IsBoxType FileType where   type BoxContent FileType = FileType-  toBoxType' _ = StdType "ftyp"+  toBoxType _ _ = StdType "ftyp"  -- | Create a 'FileTypeBox' from a major brand, a minor version and a list of -- compatible brands-fileTypeBox :: FileType -> Box' FileType+fileTypeBox :: (ValidBox b FileType)+            => FileType -> Box b FileType fileTypeBox = closedBox  -- | Contents of a 'ftyp' box are some 'FourCc' /brands/ and a version.@@ -22,7 +20,6 @@            ,compatibleBrands :: [FourCc]}  instance IsBoxContent FileType where-  boxSize (FileType maj _ver comps) =-    boxSize maj + 4 + sum (boxSize <$> comps)+  boxSize (FileType maj _ver comps) = boxSize maj + 4 + sum (boxSize <$> comps)   boxBuilder (FileType maj ver comps) =     boxBuilder maj <> word32BE ver <> mconcat (boxBuilder <$> comps)
src/Data/ByteString/IsoBaseFileFormat/Boxes/FullBox.hs view
@@ -1,6 +1,7 @@ -- | Full Boxes module Data.ByteString.IsoBaseFileFormat.Boxes.FullBox-       (FullBox(), fullBox, closedFullBox, BoxVersion, BoxFlags(..), Versioned(..)) where+       (FullBox(..), fullBox, closedFullBox, BoxVersion, BoxFlags(..))+       where  import Data.ByteString.IsoBaseFileFormat.Boxes.Box import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields@@ -19,30 +20,18 @@  -- | Create a 'FullBox' from a 'BoxVersion' and 'BoxFlags' fullBox-  :: (IsBoxType' t,ValidBoxes t ts,BoxContent t ~ FullBox version c)-  => BoxVersion version -> BoxFlags 24 -> c -> Boxes ts -> Box' t-fullBox version fs cnt = Box' (FullBox version fs cnt)+  :: (IsBoxType t,ValidContainerBox brand t ts,BoxContent t ~ FullBox version c)+  => BoxVersion version -> BoxFlags 24 -> c -> Boxes brand ts -> Box brand t+fullBox version fs cnt = Box (FullBox version fs cnt)  -- | Create a 'FullBox' from a 'BoxVersion' and 'BoxFlags' without nested boxes. closedFullBox-  :: (IsBoxType' t,ValidBoxes t '[],BoxContent t ~ FullBox version c)-  => BoxVersion version -> BoxFlags 24 -> c -> Box' t+  :: (IsBoxType t,ValidBox brand t,BoxContent t ~ FullBox version c)+  => BoxVersion version -> BoxFlags 24 -> c -> Box brand t closedFullBox version fs cnt = closedBox (FullBox version fs cnt)  -- | The box version (in a 'FullBox') is a single byte type BoxVersion v = Template (U8 "fullbox-version") v---- | Two alternative representations based on a /version/ index.---   Use this for box content that can be either 32 or 64 bit.-data Versioned v0 v1 (version :: Nat) where-  V0 :: IsBoxContent v0 => v0 -> Versioned v0 v1 0-  V1 :: IsBoxContent v1 => v1 -> Versioned v0 v1 1--instance IsBoxContent (Versioned v0 v1 version) where-  boxSize (V0 c) = boxSize c-  boxSize (V1 c) = boxSize c-  boxBuilder (V0 c) = boxBuilder c-  boxBuilder (V1 c) = boxBuilder c  -- | In addition to a 'BoxVersion' there can be 24 bits for custom flags etc in -- a 'FullBox'.
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Handler.hs view
@@ -0,0 +1,48 @@+-- | A 'Handler' box describes how a track is presentation and by which sensory+-- process it is perceived, e.g. audio, video, text, see 'HandlerType'+module Data.ByteString.IsoBaseFileFormat.Boxes.Handler where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.Default+import qualified Data.Text as T++-- | Handler box fields. A handler box may also contain a null terminated+-- description text in UTF-8.+newtype Handler where+  Handler :: Constant (U32 "pre_defined") 0+          :+ HandlerType+          :+ Constant (U32Arr "reserved" 3) '[0,0,0]+          :+ Template T.Text ""+          -> Handler+  deriving (IsBoxContent, Default)++-- | A 'Handler' can be exactly one of these.+data HandlerType =+    VideoTrack+  | AudioTrack+  | HintTrack+  | TimedMetadataTrack+  | AuxilliaryVideoTrack++-- | Create a 'MediaDataBox' from a strict 'ByteString'+handler+  :: (ValidBox brand Handler)+  => Handler -> Box brand Handler+handler = closedFullBox Default 0++instance IsBoxType Handler where+  type BoxContent Handler = FullBox 0 Handler+  toBoxType _ _ = StdType "hdlr"++instance Default HandlerType where+  def = AudioTrack++instance IsBoxContent HandlerType where+  boxSize    _                    = 4+  boxBuilder VideoTrack           = boxBuilder (FourCc ('v','i','d','e'))+  boxBuilder AudioTrack           = boxBuilder (FourCc ('s','o','u','n'))+  boxBuilder HintTrack            = boxBuilder (FourCc ('h','i','n','t'))+  boxBuilder TimedMetadataTrack   = boxBuilder (FourCc ('m','e','t','a'))+  boxBuilder AuxilliaryVideoTrack = boxBuilder (FourCc ('a','u','x','v'))
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Language.hs view
@@ -0,0 +1,40 @@+-- | Boxfield indicating an ISO 639-2 alpha-3 language code.+module Data.ByteString.IsoBaseFileFormat.Boxes.Language (Language, mkLanguage) where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.Default+import Data.String++-- | A Boxfield contains an ISO 639-2-T alpha-3 language code,  which is encoded+-- as a single bit followed by three 5 bit words, each representing the+-- lower-case character from the language code subtracted by 0x60.+-- If available, the code for /terminoligy/ purposes should be used (T-code).+data Language = Language Word16++-- | Create a 'Language', throw a runtime error when bad characters were given.+-- The characters must be in @a - z@ (lower-case!), there must be exactly three+-- characters.+mkLanguage :: String -> Language+mkLanguage  [c0,c1,c2] |+  (c0 > toEnum 0x60 && c0 < toEnum 0x7b &&+   c1 > toEnum 0x60 && c1 < toEnum 0x7b &&+   c2 > toEnum 0x60 && c2 < toEnum 0x7b) =+     let+         s :: Char -> Word16+         s c = fromIntegral (fromEnum c) - 0x60+         in Language (shiftL (s c0) 10 .|.  shiftL (s c1) 5 .|. s c2)++mkLanguage other =+  error $+    "Invalid ISO 639-2 language code: " ++ show other +++    ". The code must consist of three lower-case letters between 'a' .. 'z'."++instance IsString Language where+  fromString = mkLanguage++instance Default Language where+  def = mkLanguage "deu"++instance IsBoxContent Language where+  boxSize _ = 2+  boxBuilder (Language c) = word16BE c
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Media.hs view
@@ -0,0 +1,15 @@+-- | Track specific media information container box.+module Data.ByteString.IsoBaseFileFormat.Boxes.Media where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box++-- | Media data box+data Media++instance IsBoxType Media where+  toBoxType _ _ = StdType "mdia"++-- | Create a 'MediaDataBox' from a strict 'ByteString'+media :: ValidContainerBox brand Media ts+      => Boxes brand ts -> Box brand Media+media = containerBox
src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaData.hs view
@@ -1,18 +1,17 @@+-- | Media data box module Data.ByteString.IsoBaseFileFormat.Boxes.MediaData where  import Data.ByteString.IsoBaseFileFormat.Boxes.Box import qualified Data.ByteString as B --- | Media data box+-- | Media data box phantom type data MediaData -instance BoxRules MediaData--instance IsBoxType' MediaData where+instance IsBoxType MediaData where   -- | Contents of a 'mdat' box are just bytes from a strict 'ByteString'   type BoxContent MediaData = B.ByteString-  toBoxType' _ = StdType "mdat"+  toBoxType _ _ = StdType "mdat"  -- | Create a 'MediaDataBox' from a strict 'ByteString'-mediaDataBox :: B.ByteString -> Box' MediaData-mediaDataBox = closedBox+mediaData :: ValidBox b MediaData => B.ByteString -> Box b MediaData+mediaData = closedBox
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaHeader.hs view
@@ -0,0 +1,29 @@+-- | Media-independent properties of a tracks media content.+module Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Boxes.Language+import Data.ByteString.IsoBaseFileFormat.Boxes.Time++-- | Media header data box.+data MediaHeader (v :: Nat) where+  MediaHeader+   :: KnownNat v+   => Timing v :+ Language :+ Constant (I16 "pre_defined") 0+   -> MediaHeader v++-- | Create a 'MediaHeader' box.+mediaHeader+  :: (KnownNat v, ValidBox brand (MediaHeader v))+  => MediaHeader v -> Box brand (MediaHeader v)+mediaHeader = closedFullBox Default 0++instance (KnownNat v) => IsBoxType (MediaHeader v) where+  type BoxContent (MediaHeader v) = FullBox v (MediaHeader v)+  toBoxType _ _ = StdType "mdhd"++instance IsBoxContent (MediaHeader v) where+  boxSize (MediaHeader c) = boxSize c+  boxBuilder (MediaHeader c) = boxBuilder c
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaInformation.hs view
@@ -0,0 +1,17 @@+-- | Media information container for all boxes declaring the specific+-- technicalities of the media data associated with a 'Track'.+module Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box++-- | Media information box phantom type.+data MediaInformation++-- | Create a 'MediaInformation' from a strict 'ByteString'+mediaInformation+  :: ValidContainerBox brand MediaInformation ts+  => Boxes brand ts -> Box brand MediaInformation+mediaInformation = containerBox++instance IsBoxType MediaInformation where+  toBoxType _ _ = StdType "minf"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Movie.hs view
@@ -0,0 +1,17 @@+-- | Meta data for a presentation of a /movie/.+module Data.ByteString.IsoBaseFileFormat.Boxes.Movie where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box++-- | Compose a set of boxes into a 'Movie'+movie :: (ValidContainerBox brand Movie ts)+      => Boxes brand ts -> Box brand Movie+movie = containerBox++-- | The metadata for a presentation, a single 'Movie' which occurs only once+-- and top-level. It is pretty empty on it's own, but it contains nested boxes+-- with all the relevant meta data.+data Movie++instance IsBoxType Movie where+  toBoxType _ _ = StdType "moov"
− src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieBox.hs
@@ -1,156 +0,0 @@-{-# LANGUAGE UndecidableInstances #-}---- | Meta data for a presentation of a /movie/.-module Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox where--import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox---- | Compose a set of boxes into a 'MovieBox'------ Example:------ >  xxx :: Box' Movie--- >  xxx = movieBox $--- >         Nested (movieHeaderBox (...))--- >         :. (trackBox $--- >              Nested (trackHeaderBox (TrackHeader ...))--- >              :. trackReferenceBox (TrackReference ...)--- >              :. trackGroupingIndication (TrackGroupingInd ...))----movieBox :: ValidBoxes (Movie version) ts-         => Boxes ts -> Box' (Movie version)-movieBox = containerBox---- | The metadata for a presentation, a single 'Movie' which occurs only once--- and top-level. It is pretty empty on it's own, but it contains nested boxes--- with all the relevant meta data.-data Movie (version :: Nat)--instance IsBoxType' (Movie version) where-  toBoxType' _ = StdType "moov"--instance BoxRules (Movie version) where-  type RequiredNestedBoxes (Movie version) = '[MovieHeader version]---- * @mvhd@ Box---- | Construct a 'MovieHeader' box.-movieHeaderBox-  :: KnownNat version-  => MovieHeader version -> Box' (MovieHeader version)-movieHeaderBox = closedFullBox Default 0---- | Movie meta data, indexed by a version.-data MovieHeader (version :: Nat) where-        MovieHeader ::-            KnownNat version =>-               Versioned MovieHeaderTimesV0-                         MovieHeaderTimesV1-                         version-            :+ Template (I32 "rate") 0x00010000-            :+ Template (I16 "volume") 0x0100-            :+ Constant (I16 "reserved") 0-            :+ Constant (I32Arr "reserved" 2) '[0,0]-            :+ Constant (I32Arr "matrix" 9)-                        '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]-            :+ Template (U32Arr "pre_defined" 6) '[0,0,0,0,0,0]-            :+ U32 "next_track_ID"-            -> MovieHeader version---- | Time and timing information about a movie (32bit version).-type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32)---- | Time and timing information about a movie (64bit version).-type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64)---- | Time and timing information about a movie.-type MovieHeaderTimes uint =-      uint "creation_time"-   :+ uint "modification_time"-   :+ U32 "timescale"-   :+ uint "duration"--instance IsBoxContent (MovieHeader version) where-  boxSize (MovieHeader c) = boxSize c-  boxBuilder (MovieHeader c) = boxBuilder c--instance KnownNat version => IsBoxType' (MovieHeader version) where-  toBoxType' _ = StdType "mvhd"-  type BoxContent (MovieHeader version) = FullBox version (MovieHeader version)--instance BoxRules (MovieHeader version) where-  type IsTopLevelBox (MovieHeader version) = 'False-  type GetCardinality (MovieHeader version) any = 'ExactlyOnce-  type RestrictedTo (MovieHeader version) = 'Just '[Movie version]---- * @trak@ Box---- | Compose a 'Track' box from the given boxes.-track :: ValidBoxes (Track version) ts-      => Boxes ts -> Box' (Track version)-track = containerBox---- | Container box for tracks.-data Track (version :: Nat)--instance IsBoxType' (Track version) where-  toBoxType' _ = StdType "trak"--instance BoxRules (Track version) where-  type IsTopLevelBox (Track version) = 'False-  type GetCardinality (Track version) any = 'ExactlyOnce-  type RestrictedTo (Track version) = 'Just '[Movie version]---- * @tkhd@ Box----- | Create a 'TrackHeader' box.-trackHeader-  :: KnownNat version => TrackHeader version -> Box' (TrackHeader version)-trackHeader = closedFullBox Default 0---- | Track meta data, indexed by a version.-data TrackHeader (version :: Nat) where-        TrackHeader ::-               Versioned TrackHeaderTimesV0-                         TrackHeaderTimesV1-                         version-            :+ Constant (I32Arr "reserved" 2) '[0, 0]-            :+ Template (I16 "layer") 0-            :+ Template (I16 "alternate_group") 0-            :+ Template (I16 "volume") 256-            :+ Constant (I16 "reserved") 0-            :+ Template (I32Arr "matrix" 9)-                        '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]-            :+ I32 "width"-            :+ I32 "height"-            -> TrackHeader version---- | Time and timing information about a track (32bit version).-type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32)---- | Time and timing information about a track (64bit version).-type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64)---- | Time and timing information about a track.-type TrackHeaderTimes uint =-      uint "creation_time"-   :+ uint "modification_time"-   :+ U32 "track_ID"-   :+ Constant (U32 "reserved") 0-   :+ uint "duration"--instance IsBoxContent (TrackHeader version) where-  boxSize (TrackHeader c) = boxSize c-  boxBuilder (TrackHeader c) = boxBuilder c--instance KnownNat version => IsBoxType' (TrackHeader version) where-  type BoxContent (TrackHeader version) = FullBox version (TrackHeader version)-  toBoxType' _ = StdType "tkhd"--instance BoxRules (TrackHeader version) where-  type IsTopLevelBox (TrackHeader version) = 'False-  type GetCardinality (TrackHeader version) any = 'ExactlyOnce-  type RestrictedTo (TrackHeader version) = 'Just '[Track version]
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieHeader.hs view
@@ -0,0 +1,66 @@+-- | Meta data for a presentation of a /movie/.+module Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Boxes.Time++-- * @mvhd@ Box++-- | Construct a 'MovieHeader' box.+movieHeader+  :: (KnownNat version, ValidBox brand (MovieHeader version))+  => MovieHeader version -> Box brand (MovieHeader version)+movieHeader = closedFullBox Default 0++-- | Movie meta data, indexed by a version.+--+-- The @rate@ field is a 16.16 fix point number, 1.0 indicates the preferred+-- normal playback rate. @volume@ is also a fix point number, albeit smaller+-- with only 8.8. A volume of 1.0 is the full (loudest) volume. @matrix@ is the+-- video image transformation matrix. The @next_track_ID@  indicates the next+-- available track id, if the track ID is (0xFFFFFFFF) then the system must+-- search through all tracks associated with this presentation and figure it+-- out, 0 is not allowed.+data MovieHeader (version :: Nat) where+        MovieHeader ::+            KnownNat version =>+               Timing version+            :+ Template (I32 "rate") 0x00010000+            :+ Template (I16 "volume") 0x0100+            :+ Constant (I16 "reserved") 0+            :+ Constant (I32Arr "reserved" 2) '[0,0]+            :+ Template (I32Arr "matrix" 9)+                        '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]+            :+ Template (U32Arr "pre_defined" 6) '[0,0,0,0,0,0]+            :+ Template (U32 "next_track_ID") 0xFFFFFFFF+            -> MovieHeader version++-- | Time and timing information about a movie (32bit version).+type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32)++-- | Time and timing information about a movie (64bit version).+type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64)++-- | Time and timing information about a movie.+--+-- The creation/modification times are in seconds since midnight, Jan. 1, 1904,+-- in UTC time. Time scale declares the time coordinate system, it specifies the+-- number of time units that pass one second. The time coordinate system is used+-- by e.g. the duration field, which by the way contains the duration of the+-- longest track, if known, or simply the equivalent of 1s.+type MovieHeaderTimes uint =+      uint "creation_time"+   :+ uint "modification_time"+   :+ TimeScale+   :+ uint "duration"+++instance IsBoxContent (MovieHeader version) where+  boxSize (MovieHeader c) = boxSize c+  boxBuilder (MovieHeader c) = boxBuilder c++instance KnownNat version => IsBoxType (MovieHeader version) where+  toBoxType _ _ = StdType "mvhd"+  type BoxContent (MovieHeader version) = FullBox version (MovieHeader version)
src/Data/ByteString/IsoBaseFileFormat/Boxes/ProgressiveDownloadInformation.hs view
@@ -8,11 +8,9 @@ -- | A Box with progressive download information data ProgressiveDownload -instance BoxRules ProgressiveDownload--instance IsBoxType' ProgressiveDownload where+instance IsBoxType ProgressiveDownload where   type BoxContent ProgressiveDownload = FullBox 0 ProgressiveDownloadContent-  toBoxType' _ = StdType "pdin"+  toBoxType _ _ = StdType "pdin"  -- | Information for progressive media data download/playback encompasses the -- delay for initial playback and expected download bit rate.@@ -20,5 +18,6 @@  -- | Construct a @pdin@ box. pdinBox-  :: ProgressiveDownloadContent -> Box' ProgressiveDownload+  :: ValidBox brand ProgressiveDownload+  => ProgressiveDownloadContent -> Box brand ProgressiveDownload pdinBox = closedFullBox Default 0
src/Data/ByteString/IsoBaseFileFormat/Boxes/Skip.hs view
@@ -6,15 +6,12 @@ -- | Contents of a 'skip' box are just any number of filler bytes. newtype Skip = Skip Int -instance IsBoxType' Skip where+instance IsBoxType Skip where   type BoxContent Skip = Skip-  toBoxType' _ = StdType "skip"--instance BoxRules Skip where-  type RestrictedTo Skip = 'Nothing+  toBoxType _ _ = StdType "skip"  -- | Create a 'Skip' with a given size.-skipBox :: Skip -> Box' Skip+skipBox :: ValidBox brand Skip => Skip -> Box brand Skip skipBox = closedBox  instance IsBoxContent Skip where
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/SpecificMediaHeader.hs view
@@ -0,0 +1,51 @@+-- | Media-independent properties of a tracks media content.+module Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox++-- | Media header data box. The actual box type is determined by the claused+-- used to construct the record.+data SpecificMediaHeader where+  VideoMediaHeader+   :: Template (U16 "graphicsmode") 0+   :+ Template (U16 "reserved") 0+   -> SpecificMediaHeader+  SoundMediaHeader+   :: Template (I16 "balance") 0+   :+ Constant (U16Arr "opcolor" 3) '[0,0,0]+   -> SpecificMediaHeader+  HintMediaHeader+   :: U16 "maxPDUsize"+   :+ U16 "avgPDUsize"+   :+ U16 "maxbitrate"+   :+ U16 "avgbitrate"+   :+ U32 "reserved"+   -> SpecificMediaHeader+  NullMediaHeader+   :: SpecificMediaHeader++-- | Create a 'SpecificMediaHeader' box.+specificMediaHeader+  :: ValidBox brand SpecificMediaHeader+  => SpecificMediaHeader -> Box brand SpecificMediaHeader+specificMediaHeader h@(VideoMediaHeader _) = closedFullBox Default 1 h+specificMediaHeader h                      = closedFullBox Default 0 h++instance IsBoxType SpecificMediaHeader where+  type BoxContent SpecificMediaHeader = FullBox 0 SpecificMediaHeader+  toBoxType _ (FullBox _ _ (VideoMediaHeader _)) = StdType "vmhd"+  toBoxType _ (FullBox _ _ (SoundMediaHeader _)) = StdType "smhd"+  toBoxType _ (FullBox _ _ (HintMediaHeader  _)) = StdType "hmhd"+  toBoxType _ (FullBox _ _ NullMediaHeader)      = StdType "nmhd"++instance IsBoxContent SpecificMediaHeader where+  boxSize (VideoMediaHeader c) = boxSize c+  boxSize (SoundMediaHeader c) = boxSize c+  boxSize (HintMediaHeader  c) = boxSize c+  boxSize NullMediaHeader      = boxSize ()+  boxBuilder (VideoMediaHeader c) = boxBuilder c+  boxBuilder (SoundMediaHeader c) = boxBuilder c+  boxBuilder (HintMediaHeader  c) = boxBuilder c+  boxBuilder NullMediaHeader      = boxBuilder ()
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Time.hs view
@@ -0,0 +1,72 @@+-- | Time and timing utilities.+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++-- * Absolute Dates+-- | According to the standard, fields with absolute dates and times are in+-- seconds since 1904/01/01 at midnight (UTC). This is this reference time.+referenceTime :: UTCTime+referenceTime =+  let startDay = fromGregorian 1904 1 1+      startTime = 0+  in UTCTime startDay startTime++-- | Convert a 'UTCTime' to a number of seconds since 'referenceTime'.+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++-- | Get the current time as number of seconds since 'referenceTime'+mp4CurrentTime :: Num t+               => IO t+mp4CurrentTime = utcToMp4 <$> getCurrentTime++-- * Time-Scale and Durations+-- | Default time-scale value+--   Based on history and tradition this value is @90000@.+--   MPEG-2 TS defines a single clock for each program, running at 27MHz. The+--   timescale of MPEG-2 TS Hint Tracks should be divisable by 90000.+type TimeScale = Template (U32 "timescale") 90000++-- | Utility function to convert seconds (Integers) to any 'Num' using a+-- 'TimeScale', Since 'Scalar' has a 'Num' instance this can be used to generate+-- @duration@ fields.+durationFromSeconds :: Num t+                    => TimeScale -> Integer -> t+durationFromSeconds timeScale seconds =+  let timeScaleI = fromIntegral $ fromScalar $ templateValue timeScale+  in timeScaleI * fromInteger seconds++-- | Time and timing information about a movie.+--+-- The creation/modification times are in seconds since midnight, Jan. 1, 1904,+-- in UTC time. Time scale declares the time coordinate system, it specifies the+-- number of time units that pass one second. The time coordinate system is used+-- by e.g. the duration field, which by the way contains the duration of the+-- longest track, if known, or simply the equivalent of 1s.+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"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Track.hs view
@@ -0,0 +1,17 @@+-- | Meta data for a presentation of a /movie/.+module Data.ByteString.IsoBaseFileFormat.Boxes.Track where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box++-- * @trak@ Box+-- | Compose a 'Track' box from the given boxes.+track+  :: (ValidContainerBox brand Track ts)+  => Boxes brand ts -> Box brand Track+track = containerBox++-- | Container box for tracks.+data Track++instance IsBoxType Track where+  toBoxType _ _ = StdType "trak"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackHeader.hs view
@@ -0,0 +1,51 @@+-- | Track header box+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Boxes.Versioned++-- * @tkhd@ Box+-- | Create a 'TrackHeader' box.+trackHeader+  :: (ValidBox brand (TrackHeader version), version ~ GetVersion brand)+  => TrackHeader version -> Box brand (TrackHeader version)+trackHeader = closedFullBox Default 0++-- | Track meta data, indexed by a version.+data TrackHeader (version :: Nat) where+        TrackHeader ::+          Versioned TrackHeaderTimesV0 TrackHeaderTimesV1 version+            :+ Constant (I32Arr "reserved" 2) '[0, 0]+            :+ Template (I16 "layer") 0+            :+ Template (I16 "alternate_group") 0+            :+ Template (I16 "volume") 256+            :+ Constant (I16 "reserved") 0+            :+ Template (I32Arr "matrix" 9)+                        '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824]+            :+ I32 "width"+            :+ I32 "height"+            -> TrackHeader version++-- | Time and timing information about a track (32bit version).+type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32)++-- | Time and timing information about a track (64bit version).+type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64)++-- | Time and timing information about a track.+type TrackHeaderTimes uint =+     uint "creation_time"+  :+ uint "modification_time"+  :+ U32 "track_ID"+  :+ Constant (U32 "reserved") 0+  :+ uint "duration"++instance IsBoxContent (TrackHeader version) where+  boxSize (TrackHeader c) = boxSize c+  boxBuilder (TrackHeader c) = boxBuilder c++instance KnownNat version => IsBoxType (TrackHeader version) where+  type BoxContent (TrackHeader version) = FullBox version (TrackHeader version)+  toBoxType _ _ = StdType "tkhd"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/Versioned.hs view
@@ -0,0 +1,22 @@+-- | A binary version 0/1 field with seperate content for each version.+module Data.ByteString.IsoBaseFileFormat.Boxes.Versioned+       (Versioned(..))+       where++import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.Default++-- | Two alternative representations based on a /version/ index.+--   Use this for box content that can be either 32 or 64 bit.+data Versioned v0 v1 (version :: Nat) where+        V0 :: IsBoxContent v0 => v0 -> Versioned v0 v1 0+        V1 :: IsBoxContent v1 => v1 -> Versioned v0 v1 1++instance (version ~ 0,IsBoxContent v0,Default v0) => Default (Versioned v0 v1 (version :: Nat)) where+  def = V0 def++instance IsBoxContent (Versioned v0 v1 version) where+  boxSize (V0 c) = boxSize c+  boxSize (V1 c) = boxSize c+  boxBuilder (V0 c) = boxBuilder c+  boxBuilder (V1 c) = boxBuilder c
+ src/Data/ByteString/IsoBaseFileFormat/Brands/Dash.hs view
@@ -0,0 +1,80 @@+-- | Predefined Box composition matching the @dash@ brand. TODO this is an+-- incomplete,  special-purpose variant of this brand, serving my personal,+-- educational, current need.+-- This is a convenient way of building documents of that kind.+module Data.ByteString.IsoBaseFileFormat.Brands.Dash+       (Dash, SingleTrackInit(..), mkSingleTrackInit, module X) where++import Data.ByteString.IsoBaseFileFormat.Boxes as X+import Data.Kind (Type, Constraint)+import Control.Lens++-- | A phantom type to indicate this branding. Version can be 0 or 1 it is used+-- in some boxes to switch between 32/64 bits.+data Dash (version :: Nat)++-- | A 'BoxLayout' which contains the stuff needed for the 'dash' brand.+-- TODO incomplete+instance KnownNat v => IsBrand (Dash v) where+  type GetVersion (Dash v) = v+  type BoxLayout (Dash v) =+    '[OM_ FileType,+      OM Movie+        '[OM_ (MovieHeader v),+          SM Track+            '[OM_ (TrackHeader v),+              OM Media+                '[OM_ (MediaHeader v), OM_ Handler,+                  OM MediaInformation '[OO_ SpecificMediaHeader]]]],+      SO_ Skip]++-- Missing Boxes+-- START 17:47:+--  mdia+--  mdhd+--  hdlr+--  minf+--  smhd+--  dinf+--  dref+--  ??url+--  stbl+--  stsd+--  stts+--  stsc+--  stsz+--  stco+--  soun+--  mp4a+--  esds+--  mvex+--  trex+-- For media+-- styp+-- moof+-- mfhd+-- traf+-- tfhd+-- trun+-- | A record which contains the stuff needed for a single track initialization+-- document according to the 'Dash' brand. TODO incomplete+data SingleTrackInit =+  SingleTrackInit {_mvhd :: MovieHeader 0+                  ,_tkhd :: TrackHeader 0+                  ,_mdhd :: MediaHeader 0+                  ,_hdlr :: Handler+                  ,_xmhd :: SpecificMediaHeader}++makeLenses ''SingleTrackInit++-- | Convert a 'SingleTrackInit' record to a generic 'Boxes' collection.+mkSingleTrackInit+  :: SingleTrackInit -> MediaFile (Dash 0)+mkSingleTrackInit doc =+  MediaFile $+  fileTypeBox (FileType "iso5" 0 ["isom","iso5","dash","mp42"]) :|+  movie (movieHeader (doc ^. mvhd) :|+         track (trackHeader (doc ^. tkhd) :|+                media (mediaHeader (doc ^. mdhd) :. handler (doc ^. hdlr) :|+                       mediaInformation $:+                       specificMediaHeader (doc ^. xmhd))))
− src/Data/ByteString/IsoBaseFileFormat/Builder.hs
@@ -1,20 +0,0 @@--- | This module re-exports all modules needed to build /ISOBMFF/ documents.-module Data.ByteString.IsoBaseFileFormat.Builder-  (module X)-  where--import Data.ByteString.IsoBaseFileFormat.Boxes.Box as X-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields as X-import Data.ByteString.IsoBaseFileFormat.Boxes.FileType as X-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox as X-import Data.ByteString.IsoBaseFileFormat.Boxes.MediaData as X-import Data.ByteString.IsoBaseFileFormat.Boxes.MovieBox as X-import Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation as X-import Data.ByteString.IsoBaseFileFormat.Boxes.Skip as X--import Data.Int as X-import Data.Kind as X  (Type, Constraint)-import Data.Maybe as X-import Data.Type.Bool as X-import Data.Type.Equality as X-import Text.Printf as X