nim-nestegg - a portable, statically linked WebM format demuxer for Nim
wraps the popular and portable nestegg C library from mozilla in Nim goodness (expressiveness and memory safety)
Types
AudioCodec = enum acVorbis = (1, "vorbis"), acOpus = (3, "opus"), acUnknown = (127, "unkown")
- Allowed codecs for WebM audio, or flag unknown
VideoCodec = enum vcVp8 = (0, "vp8"), vcVp9 = (2, "vp9"), vcAv1 = (4, "av1"), ## av1 is de-facto part of webm and assumed to become official vcUnknown = (127, "unkown")
- Allowed codecs for WebM video, or flag unknown
TrackKind = enum tkVideo = (0, "video"), tkAudio = (1, "audio"), tkUnknown = (127, "unknown")
- Track types, audio or video
InitError = object of IOError
- An error that happens during setting up of the demuxer
DemuxError = object of IOError
- An error that happens during the demuxing process itself
TrackObj = object case kind*: TrackKind of tkVideo: videoCodec*: VideoCodec videoParams*: video_params duration*: culonglong fps*: float of tkAudio: audioCodec*: AudioCodec audioParams*: audio_params of tkUnknown: nil num*: cuint codecData*: seq[Chunk]
- Contains initialization data and metadata about one of the tracks multiplexed in the WebM file
Track = ref TrackObj
Chunk = object len*: int data*: ptr UncheckedArray[byte]
- A chunk of data. Each multiplexed packet contains a series of these chunks that make up the actual encoded data to be sent to the decoder
PacketObj = object raw*: ptr cpacket length*: cuint timestamp*: culonglong track*: Track chunks*: seq[Chunk]
- An individual data packet. A stream of these is sent over a file or a network, each track's packets interspersed with each other. That's what makes it a multiplexed stream. Each Packet contains one or more Chunks of raw data.
Packet = ref PacketObj
SourceObj = object io*: io
- A data source interface that is mapped to a file by default, but other data sources such as network streams can be implemented.
Source = ref SourceObj
DemuxerObj = object file*: File context*: ptr nestegg duration*: uint64 source*: Source tracks*: seq[Track] firstVideo*: Track firstAudio*: Track
- The demuxer object that wraps the actual demux process. Can be iterated over to retrieve packets.
Demuxer = ref DemuxerObj
Procs
proc newTrack(context: ptr nestegg; trackNum: cuint): Track {...}{. raises: [InitError, ValueError], tags: [].}
proc newDemuxer(source: Source): Demuxer {...}{.raises: [InitError, ValueError], tags: [].}
- Initialize a demuxer object from a data source. Reads all the initialization data and metadata and presents them in an object. Can be iterated over in order to retrieve data packets from the stream.
proc seek(demuxer: Demuxer; timestamp: uint64) {...}{. raises: [DemuxError, ValueError], tags: [].}
- Seek to specified nestegg timestamp Note that some decoders require their own seek calls as well
Iterators
iterator items(demuxer: Demuxer): Packet {...}{.raises: [DemuxError, ValueError], tags: [].}
- The iterater that retrieves packets from the demuxer. Note that a packet can be from various tracks, no guarantees are made in which order packets arrive in. Within the iterator, select codecs to handle the data and perform buffering as needed.
iterator items(packet: Packet): Chunk {...}{.raises: [], tags: [].}
Templates
template newDemuxer(file: File): Demuxer
- Convenience template to create a demuxer from a file objcet If other sources are created, adding one of these keeps the interface friendly
template newDemuxer(filename: string): Demuxer
- Convenience template to create a demuxer from a file name. The file is kept open and can be left open on termination. If the file needs to be closed within the program, it can be done manually like so: demuxer.file.close
template toOpenArray(chunk: Chunk; first, last: int): openArray[byte]
- Allows passing a chunk of data to various collection functions that take an openArray for data analysis or processing. This is always a copy operation.