matroska

package module
v1.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2025 License: MIT Imports: 6 Imported by: 0

README

Pure Go Matroska Parser

A high-performance, pure Go implementation of a Matroska (MKV) container parser and demuxer.

Overview

This Go package provides a complete solution for parsing Matroska video files without CGO dependencies. It offers both high-level demuxing capabilities and low-level EBML parsing, making it suitable for applications ranging from simple media information extraction to full-featured media processing tools.

Features

  • Pure Go Implementation: No CGO dependencies, easy cross-compilation
  • Complete EBML/Matroska Support: Full parsing of EBML structure and Matroska-specific elements
  • Streaming Support: Works with both seekable files and non-seekable streams
  • Multi-track Demuxing: Support for video, audio, and subtitle tracks
  • Codec Integration: Handles codec private data and format conversion (AVCC to Annex B for H.264/H.265)
  • Subtitle Processing: Built-in SRT format conversion for subtitle tracks
  • Memory Efficient: Stream-based processing with minimal memory footprint

Installation

go get github.com/luispater/matroska-go

Quick Start

Basic Usage
package main

import (
    "fmt"
    "io"
    "os"
    "github.com/luispater/matroska-go"
)

func main() {
    file, err := os.Open("video.mkv")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // Create demuxer
    demuxer, err := matroska.NewDemuxer(file)
    if err != nil {
        panic(err)
    }
    defer demuxer.Close()

    // Get file information
    fileInfo, _ := demuxer.GetFileInfo()
    fmt.Printf("Duration: %d ms\n", fileInfo.Duration)

    // Get track information
    numTracks, _ := demuxer.GetNumTracks()
    for i := uint(0); i < numTracks; i++ {
        track, _ := demuxer.GetTrackInfo(i)
        fmt.Printf("Track %d: Type=%d, Codec=%s\n", i, track.Type, track.CodecID)
    }

    // Read packets
    for {
        packet, err := demuxer.ReadPacket()
        if err == io.EOF {
            break
        }
        if err != nil {
            panic(err)
        }
        fmt.Printf("Track %d: %d bytes at %d ms\n", 
            packet.Track, len(packet.Data), packet.StartTime)
    }
}
Streaming Support

For non-seekable streams (e.g., network streams):

// Use NewStreamingDemuxer for io.Reader streams
demuxer, err := matroska.NewStreamingDemuxer(networkStream)

Track Extraction Tool

A complete track extraction tool is included that demonstrates advanced usage:

go run ./example/extracter/main.go

This tool extracts all tracks from MKV files with:

  • Video tracks: Converts AVCC format to Annex B format with proper NAL unit handling
  • Audio tracks: Raw stream extraction
  • Subtitle tracks: Converts to SRT format with proper timing

Architecture

The library is structured in three layers:

  1. EBML Layer (ebml.go): Low-level EBML parsing
  2. Matroska Parser (parser.go): Matroska-specific structure parsing
  3. Demuxer API (matroska.go): High-level demuxing interface

Track Types

  • Video (Type 1): H.264, H.265, VP8, VP9, AV1
  • Audio (Type 2): AAC, AC-3, DTS, FLAC, Opus, Vorbis
  • Subtitle (Type 17): ASS, SRT, VobSub, PGS

API Reference

Core Types
type Packet struct {
    Track     uint8   // Track number
    StartTime uint64  // Start time in milliseconds
    EndTime   uint64  // End time in milliseconds
    Data      []byte  // Packet data
    Flags     uint32  // Packet flags (keyframe, etc.)
}

type TrackInfo struct {
    Number       uint8   // Track number
    Type         uint8   // Track type (1=video, 2=audio, 17=subtitle)
    CodecID      string  // Codec identifier
    CodecPrivate []byte  // Codec-specific data
    // ... additional fields
}
Main Functions
  • NewDemuxer(io.ReadSeeker) (*Demuxer, error) - Create demuxer for seekable streams
  • NewStreamingDemuxer(io.Reader) (*Demuxer, error) - Create demuxer for streaming
  • GetNumTracks() (uint, error) - Get number of tracks
  • GetTrackInfo(uint) (*TrackInfo, error) - Get track information
  • ReadPacket() (*Packet, error) - Read next packet
  • GetFileInfo() (*SegmentInfo, error) - Get file metadata

Requirements

  • Go 1.24 or later
  • No external dependencies

Performance

This pure Go implementation achieves 100% accuracy compared to reference implementations while maintaining high performance through:

  • Stream-based processing
  • Efficient EBML parsing
  • Minimal memory allocations
  • Optimized codec format conversions

License

Distributed under the MIT License. See the LICENSE file for details.

Documentation

Overview

Package matroska provides functionality for parsing Matroska/EBML (Extensible Binary Meta Language) files.

Matroska is a multimedia container format that can hold an unlimited number of video, audio, picture, or subtitle tracks in one file. It is based on EBML, which is a binary format similar to XML.

This package implements the core EBML parsing functionality, including:

  • Reading and parsing EBML elements
  • Handling variable-length integers (VINT)
  • Extracting different data types from elements
  • Reading and parsing the EBML header

The main types in this package are:

  • EBMLElement: Represents a single EBML element with ID, size, and data
  • EBMLReader: Provides methods for reading EBML data from a stream
  • EBMLHeader: Represents the EBML header containing metadata about the file

Example usage:

file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

reader := matroska.NewEBMLReader(file)
header, err := reader.ReadEBMLHeader()
if err != nil {
    log.Fatal(err)
}

fmt.Printf("DocType: %s, Version: %d\n", header.DocType, header.DocTypeVersion)

Package matroska provides a pure Go implementation for parsing and demuxing Matroska/EBML files.

Matroska is an open standard, free container format, a file format that can hold an unlimited number of video, audio, picture, or subtitle tracks in one file. It is intended to serve as a universal format for storing common multimedia content, like movies or TV shows.

This package provides a high-level API for reading Matroska files, extracting track information, and reading media packets. The main entry point is the Demuxer struct, which can be created using either NewDemuxer for seekable inputs or NewStreamingDemuxer for non-seekable streams.

Basic usage:

// Open a Matroska file
file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

// Create a new demuxer
demuxer, err := matroska.NewDemuxer(file)
if err != nil {
    log.Fatal(err)
}
defer demuxer.Close()

// Get file information
fileInfo, err := demuxer.GetFileInfo()
if err != nil {
    log.Fatal(err)
}

// Get track information
numTracks, err := demuxer.GetNumTracks()
if err != nil {
    log.Fatal(err)
}

for i := uint(0); i < numTracks; i++ {
    trackInfo, err := demuxer.GetTrackInfo(i)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Track %d: %s\n", i, trackInfo.Name)
}

// Read packets
for {
    packet, err := demuxer.ReadPacket()
    if err != nil {
        if err == io.EOF {
            break
        }
        log.Fatal(err)
    }
    // Process packet...
}

Package matroska implements a parser for Matroska and WebM media container formats.

Matroska is an open standard, free container format, a file format that can hold an unlimited number of video, audio, picture, or subtitle tracks in one file. It is intended to serve as a universal format for storing common multimedia content, like movies or TV shows.

This package provides functionality to parse Matroska files, extract metadata, and read media packets. It builds upon the EBML (Extensible Binary Meta Language) parsing functionality to implement Matroska-specific parsing logic.

The main entry point is the MatroskaParser type, which can be created using the NewMatroskaParser function. Once created, it can be used to read file information, track information, and media packets.

Example usage:

file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

parser, err := matroska.NewMatroskaParser(file, false)
if err != nil {
    log.Fatal(err)
}

// Get file information
fileInfo := parser.GetFileInfo()
fmt.Printf("Title: %s\n", fileInfo.Title)
fmt.Printf("Duration: %d\n", fileInfo.Duration)

// Get track information
numTracks := parser.GetNumTracks()
for i := uint(0); i < numTracks; i++ {
    track := parser.GetTrackInfo(i)
    fmt.Printf("Track %d: %s\n", track.Number, track.Name)
}

// Read packets
for {
    packet, err := parser.ReadPacket()
    if err != nil {
        if err == io.EOF {
            break
        }
        log.Fatal(err)
    }
    // Process packet...
}

Package matroska defines all the data structures and constants used in the Matroska/EBML project.

Matroska is an extensible open standard Audio/video container format. This package provides the core types and constants needed to parse, create, and manipulate Matroska files.

The package includes definitions for:

  • Compression types used in Matroska tracks
  • Track types (video, audio, subtitle)
  • Tag target types
  • Seek types for navigation
  • Packet flags for demuxed data
  • Core data structures like Packet, TrackInfo, SegmentInfo, Attachment, Chapter, Cue, and Tag

These types are used throughout the project to represent different aspects of Matroska files and serve as the central location for all data type definitions used by other files in the project.

Package matroska provides utilities for working with Matroska/EBML format. This file contains auxiliary utility functions and types that support the main functionality of the Matroska/EBML parser.

Index

Constants

View Source
const (
	// EBML Header elements
	IDEBMLHeader             = 0x1A45DFA3 // The EBML header element
	IDEBMLVersion            = 0x4286     // The version of EBML parser used to create the file
	IDEBMLReadVersion        = 0x42F7     // The minimum EBML version needed to parse this file
	IDEBMLMaxIDLength        = 0x42F2     // The maximum length of an EBML ID in bytes
	IDEBMLMaxSizeLength      = 0x42F3     // The maximum length of an EBML size in bytes
	IDEBMLDocType            = 0x4282     // A string that describes the type of document (e.g., "matroska")
	IDEBMLDocTypeVersion     = 0x4287     // The version of the document type
	IDEBMLDocTypeReadVersion = 0x4285     // The minimum version of the document type parser needed to read this file

	// Segment elements
	IDSegment = 0x18538067 // The root element that contains all other top-level elements

	// Meta Seek Information elements
	IDSeekHead = 0x114D9B74 // Contains a list of seek points to other EBML elements
	IDSeek     = 0x4DBB     // A single seek point to an EBML element
	IDSeekID   = 0x53AB     // The ID of the element to seek to
	IDSeekPos  = 0x53AC     // The position of the element in the segment

	// Segment Information elements
	IDSegmentInfo      = 0x1549A966 // Contains general information about the segment
	IDSegmentUID       = 0x73A4     // A unique identifier for the segment
	IDSegmentFilename  = 0x7384     // The filename corresponding to this segment
	IDPrevUID          = 0x3CB923   // The UID of the previous segment
	IDPrevFilename     = 0x3C83AB   // The filename of the previous segment
	IDNextUID          = 0x3EB923   // The UID of the next segment
	IDNextFilename     = 0x3E83BB   // The filename of the next segment
	IDSegmentFamily    = 0x4444     // A family of segments this segment belongs to
	IDChapterTranslate = 0x6924     // Contains information for translating chapter numbers
	IDTimestampScale   = 0x2AD7B1   // The scale factor for all timestamps in the segment
	IDDuration         = 0x4489     // The duration of the segment in timestamp units
	IDDateUTC          = 0x4461     // The date and time the segment was created in UTC
	IDTitle            = 0x7BA9     // The title of the segment
	IDMuxingApp        = 0x4D80     // The name of the application used to mux the file
	IDWritingApp       = 0x5741     // The name of the application used to write the file

	// Track elements
	IDTracks     = 0x1654AE6B // A top-level element containing all track entries
	IDTrackEntry = 0xAE       // A single track entry containing information about a track
	IDTrackNum   = 0xD7       // The track number as used in the Block header
	IDTrackUID   = 0x73C5     // A unique identifier for the track
	IDTrackType  = 0x83       // The type of the track (video, audio, etc.)
	IDTrackName  = 0x536E     // The name of the track
	IDLanguage   = 0x22B59C   // The language of the track
	IDCodecID    = 0x86       // The ID of the codec used for this track
	IDCodecPriv  = 0x63A2     // Private data specific to the codec
	IDCodecName  = 0x258688   // The name of the codec used for this track
	IDVideo      = 0xE0       // Video settings specific to this track
	IDAudio      = 0xE1       // Audio settings specific to this track

	// Video elements
	IDFlagInterlaced = 0x9A   // Flag indicating whether the video is interlaced
	IDPixelWidth     = 0xB0   // The width of the encoded video frames in pixels
	IDPixelHeight    = 0xBA   // The height of the encoded video frames in pixels
	IDDisplayWidth   = 0x54B0 // The width of the video frames when displayed
	IDDisplayHeight  = 0x54BA // The height of the video frames when displayed

	// Audio elements
	IDSamplingFrequency       = 0xB5   // The sampling frequency of the audio in Hz
	IDOutputSamplingFrequency = 0x78B5 // The output sampling frequency of the audio in Hz
	IDChannels                = 0x9F   // The number of audio channels
	IDBitDepth                = 0x6264 // The number of bits per audio sample

	// Cluster elements
	IDCluster     = 0x1F43B675 // A cluster contains blocks of data for a specific timestamp
	IDTimestamp   = 0xE7       // The timestamp of the cluster
	IDSimpleBlock = 0xA3       // A block containing raw data without additional metadata
	IDBlockGroup  = 0xA0       // A group of blocks with additional metadata
	IDBlock       = 0xA1       // A block containing raw data

	// Cues elements
	IDCues             = 0x1C53BB6B // A top-level element containing all cue points
	IDCuePoint         = 0xBB       // A single cue point pointing to a specific timestamp
	IDCueTime          = 0xB3       // The timestamp of the cue point
	IDCueTrackPosition = 0xB7       // Contains positions for a single track.
	IDCueTrack         = 0xF7       // The track for this cue point.
	IDCueClusterPos    = 0xF1       // The position of the Cluster containing the referenced Block.
	IDCueRelativePos   = 0xF0       // The relative position of the Block within the Cluster.
	IDCueBlockNum      = 0x5378     // The Block number of the referenced Block.
	IDCueDuration      = 0x9B       // The duration of the block.

	// Chapters elements
	IDChapters                 = 0x1043A770 // A top-level element containing all chapter entries
	IDEditionEntry             = 0x45B9
	IDEditionUID               = 0x45BC
	IDEditionFlagHidden        = 0x45BD
	IDEditionFlagDefault       = 0x45DB
	IDEditionFlagOrdered       = 0x45DD
	IDChapterAtom              = 0xB6
	IDChapterUID               = 0x73C4
	IDChapterStringUID         = 0x5654
	IDChapterTimeStart         = 0x91
	IDChapterTimeEnd           = 0x92
	IDChapterHidden            = 0x98
	IDChapterEnabled           = 0x4598
	IDChapterSegmentUID        = 0x6E67
	IDChapterSegmentEditionUID = 0x6EBC
	IDChapterPhysicalEquiv     = 0x63C3
	IDChapterTrack             = 0x8F
	IDChapterTrackUID          = 0x89
	IDChapterDisplay           = 0x80
	IDChapterString            = 0x85
	IDChapterLanguage          = 0x437C
	IDChapterCountry           = 0x437E

	// Tags elements
	IDTags             = 0x1254C367 // A top-level element containing all tags
	IDTag              = 0x7373     // A single tag
	IDTargets          = 0x63C0     // Specifies which other elements the metadata represented by the Tag applies to
	IDTargetType       = 0x63CA     // An informational string that can be used to display the logical level of the target
	IDTargetTypeValue  = 0x68CA     // A number to indicate the logical level of the target
	IDTagTrackUID      = 0x63C5     // A unique ID to identify the Track(s) the tags belong to
	IDTagEditionUID    = 0x63C9     // A unique ID to identify the EditionEntry(s) the tags belong to
	IDTagChapterUID    = 0x63C4     // A unique ID to identify the Chapter(s) the tags belong to
	IDTagAttachmentUID = 0x63C6     // A unique ID to identify the Attachment(s) the tags belong to
	IDSimpleTag        = 0x67C8     // Contains general information about the target
	IDTagName          = 0x45A3     // The name of the Tag that is going to be stored
	IDTagString        = 0x4487     // The value of the Tag
	IDTagLanguage      = 0x447A     // Specifies the language of the tag specified
	IDTagDefault       = 0x4484     // Indication to know if this is the default/original language to use for the given tag
	IDTagBinary        = 0x4485     // The values of the Tag if it is binary

	// Attachments elements
	IDAttachments     = 0x1941A469 // A top-level element containing all attached files
	IDAttachedFile    = 0x61A7     // An attached file
	IDFileDescription = 0x467E     // A human-friendly name for the attached file
	IDFileName        = 0x466E     // Filename of the attached file
	IDFileMimeType    = 0x4660     // MIME type of the file
	IDFileData        = 0x465C     // The data of the file
	IDFileUID         = 0x46AE     // Unique ID representing the file
)

EBML element IDs for Matroska

These constants define the standard element IDs used in Matroska/EBML files. Each ID is a unique identifier for a specific element type in the EBML structure.

View Source
const (
	// CompZlib indicates zlib compression (RFC 1950).
	CompZlib = 0
	// CompBzip indicates bzip2 compression.
	CompBzip = 1
	// CompLZO1X indicates LZO1X compression.
	CompLZO1X = 2
	// CompPrepend indicates header stripping compression where data is prepended during decompression.
	CompPrepend = 3
)

Matroska compression types

These constants define the compression algorithms that can be applied to Matroska tracks.

View Source
const (
	// TypeVideo indicates a video track.
	TypeVideo = 1
	// TypeAudio indicates an audio track.
	TypeAudio = 2
	// TypeSubtitle indicates a subtitle track.
	TypeSubtitle = 17
)

Track types

These constants define the different types of tracks that can be present in a Matroska file.

View Source
const (
	// TargetTrack indicates that the tag applies to a specific track.
	TargetTrack = 0
	// TargetChapter indicates that the tag applies to a specific chapter.
	TargetChapter = 1
	// TargetAttachment indicates that the tag applies to a specific attachment.
	TargetAttachment = 2
	// TargetEdition indicates that the tag applies to a specific edition.
	TargetEdition = 3
)

Tag target types

These constants define the different types of targets that Matroska tags can be applied to.

View Source
const (
	// SeekToPrevKeyFrame seeks to the previous key frame before the requested position.
	SeekToPrevKeyFrame = 1
	// SeekToPrevKeyFrameStrict seeks to the previous key frame before the requested position,
	// but does not allow going beyond that point even if it means displaying nothing.
	SeekToPrevKeyFrameStrict = 2
)

Seek types

These constants define the different seeking behaviors that can be used when navigating through a Matroska file. They control how the player handles seeking operations.

View Source
const (
	// UnknownStart indicates that the packet starts at an unknown position.
	UnknownStart = 0x00000001
	// UnknownEnd indicates that the packet ends at an unknown position.
	UnknownEnd = 0x00000002
	// KF indicates that the packet is a key frame.
	KF = 0x00000004
	// GAP indicates that the packet is a gap packet, which should be skipped during playback.
	GAP = 0x00800000
	// StreamMask is a bitmask used to extract the stream number from the Flags field.
	StreamMask = 0xff000000
	// StreamShift is the number of bits to shift right to extract the stream number from the Flags field.
	StreamShift = 24
)

Packet flags

These constants define flags that can be returned with a matroska.Packet in its Flags member. They provide additional information about the packet's properties and characteristics.

Variables

This section is empty.

Functions

This section is empty.

Types

type Attachment

type Attachment struct {
	// Position is the attachment's position within the stream.
	// This is the byte offset where the attachment data begins.
	Position uint64
	// Length is the attachment's length in bytes.
	// This is the size of the attachment data.
	Length uint64
	// UID is the attachment's unique identifier.
	// This allows the attachment to be referenced by other elements.
	UID uint64
	// Name is the name of the attachment.
	// This is a human-readable name for the attached file.
	Name string
	// Description is a description of the attachment.
	// This provides additional information about the attached file.
	Description string
	// MimeType is the attachment's MIME type.
	// This identifies the type of the attached file, such as "font/ttf" or "image/jpeg".
	MimeType string
}

Attachment contains information about a Matroska attachment.

Matroska files can contain attached files, such as fonts, images, or other metadata. The Attachment structure holds information about these attached files, including their location, size, and metadata.

type Chapter

type Chapter struct {
	// UID is the chapter's unique identifier.
	// This allows chapters to be referenced by other elements.
	UID uint64
	// Start is the start time for the chapter in nanoseconds.
	// This is relative to the beginning of the segment.
	Start uint64
	// End is the end time for the chapter in nanoseconds.
	// This is relative to the beginning of the segment.
	End uint64

	// Tracks contains the list of track UIDs this chapter pertains to.
	// If empty, the chapter applies to all tracks.
	Tracks []uint64
	// Display contains display information for this chapter.
	// This allows the chapter to be displayed in multiple languages.
	Display []ChapterDisplay
	// Children contains any child chapters for this chapter.
	// This allows for a hierarchical chapter structure.
	Children []*Chapter
	// Process contains the set of processes for this chapter.
	// These processes can be used for special chapter handling.
	Process []ChapterProcess

	// SegmentUID is the segment UID this chapter relates to.
	// This allows chapters to reference specific segments.
	SegmentUID [16]byte

	// Hidden indicates whether this chapter is hidden.
	// Hidden chapters are not displayed in chapter lists.
	Hidden bool
	// Enabled indicates whether this chapter is enabled.
	// Disabled chapters are ignored during playback.
	Enabled bool

	// Default indicates whether this Edition is the default.
	// If true, this chapter edition should be used by default.
	Default bool
	// Ordered indicates whether this chapter is ordered.
	// Ordered chapters must be played in a specific sequence.
	Ordered bool
}

Chapter contains all information about a Matroska chapter.

A Chapter structure represents a chapter or section within a Matroska file. Chapters can be nested to create a hierarchical structure, and can contain display information, processing commands, and timing information.

type ChapterCommand

type ChapterCommand struct {
	// Time is the time when the command should be executed.
	// This is relative to the start of the chapter.
	Time uint32
	// Command contains the actual command data.
	// The format and meaning of this data depends on the chapter codec.
	Command []byte
}

ChapterCommand represents a command associated with a chapter.

Chapter commands are used to execute specific actions at certain times during chapter playback. This can be used for interactive content or special effects.

type ChapterDisplay

type ChapterDisplay struct {
	// String is the display string for the chapter, usually the chapter name.
	// This is the human-readable text that will be displayed to users.
	String string
	// Language is the language code for this chapter display.
	// This follows the ISO 639-2 language codes (e.g., "eng" for English).
	Language string
	// Country is the country this chapter is associated with.
	// This is used when there may be language dialects that vary by country.
	Country string
}

ChapterDisplay contains display information for a given Chapter.

A ChapterDisplay structure holds the human-readable information for a chapter, including its name, language, and country association. This allows chapters to be displayed in multiple languages and with country-specific variations.

type ChapterProcess

type ChapterProcess struct {
	// CodecID is the identifier for the codec used by this process.
	// This determines how the process data should be interpreted.
	CodecID uint32
	// CodecPrivate contains any private data for this process.
	// This is codec-specific data that may be needed for processing.
	CodecPrivate []byte
	// Commands contains all associated commands for this process.
	// These commands will be executed as part of the chapter processing.
	Commands []ChapterCommand
}

ChapterProcess contains processing information for a chapter.

Chapter processes are used to apply special processing to chapters, such as codec-specific processing or command execution.

type Cue

type Cue struct {
	// Time is the cue's start time in nanoseconds.
	// This is the timestamp of the cue point.
	Time uint64
	// Duration is the cue's duration in nanoseconds.
	// This may be 0 if the duration is unknown.
	Duration uint64
	// Position is the cue's position in the stream.
	// This is the byte offset of the cluster containing the cue.
	Position uint64
	// RelativePosition is the cue's position relative to the cluster.
	// This is the byte offset within the cluster.
	RelativePosition uint64
	// Block is the block number within the cluster.
	// This identifies the specific block containing the cue.
	Block uint64
	// Track is the track which this cue covers.
	// This identifies which track the cue point belongs to.
	Track uint8
}

Cue contains all information about a Matroska cue.

Cues are indexing points in a Matroska file that allow for efficient seeking. A Cue structure contains the timing and position information needed to locate specific points in the media stream.

type Demuxer

type Demuxer struct {
	// contains filtered or unexported fields
}

Demuxer is a Matroska demuxer using pure Go implementation.

The Demuxer struct provides the main interface for parsing and reading Matroska files. It encapsulates the underlying parser and provides methods for accessing track information, file metadata, and reading media packets. The Demuxer can work with both seekable and non-seekable input streams.

For seekable inputs, use NewDemuxer. For non-seekable streams (like network streams), use NewStreamingDemuxer.

func NewDemuxer

func NewDemuxer(r io.ReadSeeker) (*Demuxer, error)

NewDemuxer creates a new Matroska demuxer from r.

NewDemuxer creates a new Matroska demuxer from a seekable input stream. The input reader must implement both io.Reader and io.Seeker interfaces to allow random access to the file content, which is necessary for operations like seeking and accessing cues.

This function initializes the underlying Matroska parser and returns a Demuxer instance that can be used to extract track information, file metadata, and read media packets from the Matroska file.

Example:

file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

demuxer, err := matroska.NewDemuxer(file)
if err != nil {
    log.Fatal(err)
}
defer demuxer.Close()

Parameters:

  • r: An io.ReadSeeker that provides access to the Matroska file data.

Returns:

  • *Demuxer: A new Demuxer instance for the given input.
  • error: An error if the demuxer could not be created.

func NewStreamingDemuxer

func NewStreamingDemuxer(r io.Reader) (*Demuxer, error)

NewStreamingDemuxer creates a new Matroska demuxer from an io.Reader that has no ability to seek on the input stream.

NewStreamingDemuxer creates a new Matroska demuxer from a non-seekable input stream. This function is designed for streaming scenarios where the input reader only implements the io.Reader interface and cannot seek backwards in the stream, such as network streams or pipes.

The function wraps the non-seekable reader with a fakeSeeker that provides a minimal seeking interface, allowing the Matroska parser to work with streams that don't support random access. Note that some operations, like seeking to specific timecodes or accessing cues, may not work as efficiently or may not be available when using a streaming demuxer.

Example:

resp, err := http.Get("http://example.com/video.mkv")
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

demuxer, err := matroska.NewStreamingDemuxer(resp.Body)
if err != nil {
    log.Fatal(err)
}
defer demuxer.Close()

Parameters:

  • r: An io.Reader that provides access to the Matroska stream data.

Returns:

  • *Demuxer: A new Demuxer instance for the given input stream.
  • error: An error if the demuxer could not be created.

func (*Demuxer) Close

func (d *Demuxer) Close()

Close closes a demuxer.

Close releases any resources associated with the Demuxer. In this pure Go implementation, no explicit cleanup is required as Go's garbage collector handles memory management automatically. However, calling Close is still recommended for consistency and to allow for future implementations that might require cleanup.

Example:

demuxer, err := matroska.NewDemuxer(file)
if err != nil {
    log.Fatal(err)
}
defer demuxer.Close()

// Use demuxer...

func (*Demuxer) GetAttachments

func (d *Demuxer) GetAttachments() []*Attachment

GetAttachments returns information on all available attachments for a given demuxer. The returned slice may be of length 0.

This function retrieves information about any attachments embedded in the Matroska file, such as fonts, images, or other files. Attachments are typically used for fonts required by subtitle tracks or cover art.

Example:

attachments := demuxer.GetAttachments()
for _, attachment := range attachments {
    fmt.Printf("Attachment: %s (%s)\n", attachment.Name, attachment.MimeType)
}

Returns:

  • []*Attachment: A slice of attachment information. May be empty if no attachments are present.

func (*Demuxer) GetChapters

func (d *Demuxer) GetChapters() []*Chapter

GetChapters returns all chapters for a given demuxer. The returned slice may be of length 0.

This function retrieves information about the chapter structure of the Matroska file. Chapters can be used to navigate through the content, similar to DVD chapters. The returned chapters may include nested chapters (editions).

Example:

chapters := demuxer.GetChapters()
for _, chapter := range chapters {
    fmt.Printf("Chapter: %s (%d-%d)\n", chapter.Display.String, chapter.Start, chapter.End)
}

Returns:

  • []*Chapter: A slice of chapter information. May be empty if no chapters are present.

func (*Demuxer) GetCues

func (d *Demuxer) GetCues() []*Cue

GetCues returns all cues for a given demuxer. The returned slice may be of length 0.

This function retrieves cue points from the Matroska file. Cues are indexing information that allows for efficient seeking to specific timecodes in the file. They contain mappings between timecodes and their positions in the file.

Example:

cues := demuxer.GetCues()
for _, cue := range cues {
    fmt.Printf("Cue at time %d, position %d\n", cue.Time, cue.Position)
}

Returns:

  • []*Cue: A slice of cue information. May be empty if no cues are present.

func (*Demuxer) GetCuesPos

func (d *Demuxer) GetCuesPos() uint64

GetCuesPos returns the position of the cues in the stream.

This function returns the file position (offset) where the cues element begins in the Matroska file. The cues element contains indexing information that allows for efficient seeking.

Example:

cuesPos := demuxer.GetCuesPos()
fmt.Printf("Cues element at position %d\n", cuesPos)

Returns:

  • uint64: The file position where the cues element begins.

func (*Demuxer) GetCuesTopPos

func (d *Demuxer) GetCuesTopPos() uint64

GetCuesTopPos returns the position of the byte after the end of the cues.

This function returns the file position (offset) immediately after the end of the cues element. This can be useful for determining the size of the cues element.

Example:

cuesStart := demuxer.GetCuesPos()
cuesEnd := demuxer.GetCuesTopPos()
cuesSize := cuesEnd - cuesStart
fmt.Printf("Cues element size: %d bytes\n", cuesSize)

Returns:

  • uint64: The file position after the end of the cues element.

func (*Demuxer) GetFileInfo

func (d *Demuxer) GetFileInfo() (*SegmentInfo, error)

GetFileInfo gets all top-level (whole file) info available for a given demuxer.

This function retrieves metadata about the Matroska file itself, including title, duration, muxing application, writing application, and other file-level information. This information is stored in the SegmentInfo structure.

Example:

fileInfo, err := demuxer.GetFileInfo()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Title: %s\n", fileInfo.Title)
fmt.Printf("Duration: %f seconds\n", float64(fileInfo.Duration)/1000000000)
fmt.Printf("Muxing App: %s\n", fileInfo.MuxingApp)

Returns:

  • *SegmentInfo: File-level metadata about the Matroska file.
  • error: An error if the file information could not be retrieved.

func (*Demuxer) GetLowestQTimecode

func (d *Demuxer) GetLowestQTimecode() uint64

GetLowestQTimecode returns the lowest queued timecode in the demuxer.

This function returns the timecode of the earliest packet that is currently queued in the demuxer. This can be useful for buffering and synchronization purposes.

Returns:

  • uint64: The timecode of the lowest queued packet.

func (*Demuxer) GetNumTracks

func (d *Demuxer) GetNumTracks() (uint, error)

GetNumTracks gets the number of tracks available to a given demuxer.

This function returns the total number of tracks (video, audio, subtitle, etc.) contained in the Matroska file. Track indices range from 0 to the returned value minus one, and can be used with GetTrackInfo to retrieve detailed information about each track.

Example:

numTracks, err := demuxer.GetNumTracks()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("File contains %d tracks\n", numTracks)

Returns:

  • uint: The number of tracks in the Matroska file.
  • error: An error if the track count could not be retrieved.

func (*Demuxer) GetSegment

func (d *Demuxer) GetSegment() uint64

GetSegment returns the position of the segment.

This function returns the file position (offset) where the Matroska segment begins. The segment is the main container for all tracks, chapters, tags, and other metadata in the file.

Example:

segmentPos := demuxer.GetSegment()
fmt.Printf("Segment starts at position %d\n", segmentPos)

Returns:

  • uint64: The file position where the segment begins.

func (*Demuxer) GetSegmentTop

func (d *Demuxer) GetSegmentTop() uint64

GetSegmentTop returns the position of the next byte after the segment.

This function returns the file position (offset) immediately after the end of the Matroska segment. This can be useful for determining the size of the segment or for locating other elements that may follow it in the file.

Example:

segmentStart := demuxer.GetSegment()
segmentEnd := demuxer.GetSegmentTop()
segmentSize := segmentEnd - segmentStart
fmt.Printf("Segment size: %d bytes\n", segmentSize)

Returns:

  • uint64: The file position after the end of the segment.

func (*Demuxer) GetTags

func (d *Demuxer) GetTags() []*Tag

GetTags returns all tags for a given demuxer. The returned slice may be of length 0.

This function retrieves metadata tags associated with the Matroska file or specific tracks within the file. Tags can contain information such as title, artist, album, genre, and other descriptive metadata.

Example:

tags := demuxer.GetTags()
for _, tag := range tags {
    for _, simpleTag := range tag.SimpleTags {
        fmt.Printf("Tag: %s = %s\n", simpleTag.Name, simpleTag.Value)
    }
}

Returns:

  • []*Tag: A slice of tag information. May be empty if no tags are present.

func (*Demuxer) GetTrackInfo

func (d *Demuxer) GetTrackInfo(track uint) (*TrackInfo, error)

GetTrackInfo returns all track-level information available for a given track, where track is less than what is returned by GetNumTracks.

This function retrieves detailed information about a specific track, including its type (video, audio, subtitle), codec, language, and other metadata. The track parameter must be a valid track index between 0 and GetNumTracks()-1.

Example:

numTracks, err := demuxer.GetNumTracks()
if err != nil {
    log.Fatal(err)
}

for i := uint(0); i < numTracks; i++ {
    trackInfo, err := demuxer.GetTrackInfo(i)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Track %d: %s (%s)\n", i, trackInfo.Name, trackInfo.CodecID)
}

Parameters:

  • track: The index of the track to retrieve information for.

Returns:

  • *TrackInfo: Detailed information about the track.
  • error: An error if the track information could not be retrieved or if the track index is invalid.

func (*Demuxer) ReadPacket

func (d *Demuxer) ReadPacket() (*Packet, error)

ReadPacket returns the next packet from a demuxer.

This function reads and returns the next media packet from the Matroska file. Packets contain the actual media data (video frames, audio samples, etc.) along with metadata such as the track number, timecode, and flags.

Example:

for {
    packet, err := demuxer.ReadPacket()
    if err != nil {
        if err == io.EOF {
            break
        }
        log.Fatal(err)
    }
    fmt.Printf("Packet: track=%d, time=%d, size=%d\n",
        packet.Track, packet.StartTime, len(packet.Data))
    // Process packet data...
}

Returns:

  • *Packet: The next packet from the demuxer.
  • error: An error if a packet could not be read, or io.EOF if the end of the file has been reached.

func (*Demuxer) ReadPacketMask

func (d *Demuxer) ReadPacketMask(mask uint64) (*Packet, error)

ReadPacketMask is the same as ReadPacket except with a track mask.

This function is intended to read the next packet from the demuxer while respecting the track mask specified by the mask parameter. Currently, the mask parameter is ignored and the function behaves identically to ReadPacket.

Parameters:

  • mask: A bitmask specifying which tracks to ignore. Currently ignored.

Returns:

  • *Packet: The next packet from the demuxer.
  • error: An error if a packet could not be read.

func (*Demuxer) Seek

func (d *Demuxer) Seek(timecode uint64, flags uint32)

Seek seeks to a given timecode.

Flags here may be: 0 (normal seek), matroska.SeekToPrevKeyFrame, or matoska.SeekToPrevKeyFrameStrict

This function moves the playback position to the specified timecode in the Matroska file. The flags parameter can be used to control the seeking behavior, such as whether to seek to the previous keyframe or to perform a strict seek.

Parameters:

  • timecode: The target timecode to seek to, in nanoseconds.
  • flags: Seek behavior flags. May be 0 (normal seek), SeekToPrevKeyFrame, or SeekToPrevKeyFrameStrict.

func (*Demuxer) SeekCueAware

func (d *Demuxer) SeekCueAware(timecode uint64, flags uint32, fuzzy bool)

SeekCueAware seeks to a given timecode while taking cues into account

Flags here may be: 0 (normal seek), matroska.SeekToPrevKeyFrame, or matoska.SeekToPrevKeyFrameStrict

fuzzy defines whether a fuzzy seek will be used or not.

This function moves the playback position to the specified timecode in the Matroska file, using the cue information for more accurate seeking. The fuzzy parameter controls whether a fuzzy seek (approximate position) is acceptable if an exact match cannot be found.

Parameters:

  • timecode: The target timecode to seek to, in nanoseconds.
  • flags: Seek behavior flags. May be 0 (normal seek), SeekToPrevKeyFrame, or SeekToPrevKeyFrameStrict.
  • fuzzy: Whether to allow fuzzy seeking (approximate positions).

func (*Demuxer) SetTrackMask

func (d *Demuxer) SetTrackMask(mask uint64)

SetTrackMask sets the demuxer's track mask; that is, it tells the demuxer which tracks to skip, and which to use. Any tracks with ones in their bit positions will be ignored.

Calling this withh cause all parsed and queued frames to be discarded.

This function allows filtering of tracks during playback or processing. The mask is a bitmask where each bit corresponds to a track index. Setting a bit to 1 will cause that track to be ignored.

Parameters:

  • mask: A bitmask specifying which tracks to ignore. A bit set to 1 at position N will cause track N to be ignored.

func (*Demuxer) SkipToKeyframe

func (d *Demuxer) SkipToKeyframe()

SkipToKeyframe skips to the next keyframe in a stream.

This function advances the playback position to the next keyframe in the current track. Keyframes are frames that can be decoded without reference to previous frames, making them ideal starting points for seeking or resuming playback.

type EBMLElement

type EBMLElement struct {
	ID   uint32 // The element ID that identifies the type of element
	Size uint64 // The size of the element's data in bytes
	Data []byte // The raw data contained within the element
}

EBMLElement represents an EBML element with its ID, size, and data.

An EBML element is the basic building block of EBML files. Each element consists of:

  • ID: A variable-length integer that identifies the type of element
  • Size: A variable-length integer that specifies the size of the element's data
  • Data: The actual data contained within the element

The EBMLElement struct provides methods to extract different types of data from the element, such as integers, floats, strings, and raw bytes.

func (*EBMLElement) ReadBytes

func (el *EBMLElement) ReadBytes() []byte

ReadBytes returns the raw byte slice of the element's data.

This method provides direct access to the uninterpreted byte data contained within the EBML element.

Returns:

  • A byte slice containing the raw data of the element.

func (*EBMLElement) ReadFloat

func (el *EBMLElement) ReadFloat() float64

ReadFloat reads a floating-point number from the element's data.

This method interprets the element's data as a big-endian floating-point number (either 32-bit or 64-bit) and returns its value. If the element's data is empty or its length is not 4 or 8 bytes, it returns 0.0.

Returns:

  • The floating-point value stored in the element's data.

func (*EBMLElement) ReadInt

func (el *EBMLElement) ReadInt() int64

ReadInt reads a signed integer from element data

func (*EBMLElement) ReadString

func (el *EBMLElement) ReadString() string

ReadString reads a UTF-8 string from the element's data.

This method interprets the element's data as a UTF-8 encoded string. It removes any null terminator if present at the end of the data.

Returns:

  • The string value stored in the element's data.

func (*EBMLElement) ReadUInt

func (el *EBMLElement) ReadUInt() uint64

ReadUInt reads an unsigned integer from the element's data.

This method interprets the element's data as a big-endian unsigned integer and returns its value. If the element's data is empty, it returns 0.

Returns:

  • The unsigned integer value stored in the element's data

Example usage:

value := element.ReadUInt()
fmt.Printf("Value: %d\n", value)

type EBMLHeader

type EBMLHeader struct {
	Version            uint64 // The version of EBML parser used to create the file
	ReadVersion        uint64 // The minimum EBML version needed to parse this file
	MaxIDLength        uint64 // The maximum length of an EBML ID in bytes
	MaxSizeLength      uint64 // The maximum length of an EBML size in bytes
	DocType            string // A string that describes the type of document (e.g., "matroska")
	DocTypeVersion     uint64 // The version of the document type
	DocTypeReadVersion uint64 // The minimum version of the document type parser needed to read this file
}

EBMLHeader represents the EBML header containing metadata about the file.

The EBML header is the first element in an EBML file and contains information about how to parse the rest of the file. It includes the EBML version, document type, and other metadata that helps parsers understand the structure of the file.

Example usage:

reader := NewEBMLReader(file)
header, err := reader.ReadEBMLHeader()
if err != nil {
    log.Fatal(err)
}

fmt.Printf("DocType: %s, Version: %d\n", header.DocType, header.DocTypeVersion)

type EBMLReader

type EBMLReader struct {
	// contains filtered or unexported fields
}

EBMLReader provides methods for reading EBML data from a stream.

EBMLReader is the main type used for parsing EBML data. It wraps an io.ReadSeeker and provides methods to read EBML elements, variable-length integers, and other EBML-specific data structures.

Example usage:

file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

reader := NewEBMLReader(file)
element, err := reader.ReadElement()
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Element ID: 0x%X, Size: %d\n", element.ID, element.Size)

func NewEBMLReader

func NewEBMLReader(r io.ReadSeeker) *EBMLReader

NewEBMLReader creates a new EBML reader from an io.ReadSeeker.

This function initializes a new EBMLReader with the provided io.ReadSeeker. The reader is used to read EBML data from a stream, such as a file or network connection.

Parameters:

  • r: An io.ReadSeeker that provides the EBML data stream

Returns:

  • A pointer to the newly created EBMLReader

Example usage:

file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

reader := NewEBMLReader(file)

func (*EBMLReader) Position

func (er *EBMLReader) Position() int64

Position returns the current position in the stream.

This method returns the current position of the reader in the stream, which is tracked internally and updated after each read or seek operation.

Returns:

  • The current position in the stream as a byte offset from the beginning

func (*EBMLReader) ReadEBMLHeader

func (er *EBMLReader) ReadEBMLHeader() (*EBMLHeader, error)

ReadEBMLHeader reads and parses the EBML header from the stream.

This method expects the next element in the stream to be the EBML header (IDEBMLHeader). It reads the header element and then parses its child elements to populate the EBMLHeader struct.

Returns:

  • A pointer to the parsed EBMLHeader.
  • An error if reading the header fails or if the first element is not an EBML header.

func (*EBMLReader) ReadElement

func (er *EBMLReader) ReadElement() (*EBMLElement, error)

ReadElement reads a complete EBML element from the stream.

This method reads an EBML element, which consists of an ID, a size, and the element data. It first reads the element ID using ReadVIntID, then reads the element size using ReadVInt, and finally reads the element data based on the size.

Returns:

  • A pointer to the EBMLElement that was read
  • An error if the read operation failed or the element is invalid

Example usage:

element, err := reader.ReadElement()
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Element ID: 0x%X, Size: %d\n", element.ID, element.Size)

func (*EBMLReader) ReadElementHeader

func (er *EBMLReader) ReadElementHeader() (uint32, uint64, error)

ReadElementHeader reads only the element ID and size from the stream, without reading the actual data.

This method is useful when you only need to inspect the type and size of an element before deciding whether to read its full content or skip it.

Returns:

  • The ID of the element.
  • The size of the element's data.
  • An error if the read operation failed.

func (*EBMLReader) ReadVInt

func (er *EBMLReader) ReadVInt() (uint64, error)

ReadVInt reads a variable-length integer from the stream.

Variable-length integers (VINT) are used in EBML to store element sizes and other values. This method reads a VINT and removes the length marker, returning only the value.

Returns:

  • The value of the variable-length integer
  • An error if the read operation failed or the VINT is invalid

func (*EBMLReader) ReadVIntID

func (er *EBMLReader) ReadVIntID() (uint64, error)

ReadVIntID reads a variable-length integer for element IDs, keeping the length marker.

This method is similar to ReadVInt, but it preserves the length marker in the returned value. It is used specifically for reading EBML element IDs, which require the length marker to be preserved.

Returns:

  • The value of the variable-length integer including the length marker
  • An error if the read operation failed or the VINT is invalid

func (*EBMLReader) Seek

func (er *EBMLReader) Seek(offset int64, whence int) (int64, error)

Seek moves the reader to the specified position in the stream.

This method implements the io.Seeker interface, allowing random access to the EBML data. It delegates to the underlying io.ReadSeeker and updates the internal position tracker.

Parameters:

  • offset: The offset to seek to, relative to the whence parameter
  • whence: The reference point for the offset (0 = beginning, 1 = current, 2 = end)

Returns:

  • The new position relative to the beginning of the stream
  • An error if the seek operation failed

func (*EBMLReader) Skip added in v1.2.0

func (er *EBMLReader) Skip(n int64) (int64, error)

Skip reads and discards the next n bytes from the underlying reader.

func (*EBMLReader) SkipElement

func (er *EBMLReader) SkipElement(element *EBMLElement) error

SkipElement skips the current element by seeking past its data in the stream.

This method is useful for efficiently moving past elements whose content is not needed for current processing. It updates the reader's internal position tracker.

Parameters:

  • element: The EBMLElement to skip.

Returns:

  • An error if the seek operation failed.

type MatroskaParser

type MatroskaParser struct {
	// contains filtered or unexported fields
}

MatroskaParser represents a parser for Matroska and WebM files.

It provides functionality to parse Matroska container files, extract metadata, and read media packets. The parser maintains state information about the file structure, including the EBML header, segment information, tracks, and other metadata elements.

The parser can operate in two modes:

  • With seeking enabled (avoidSeeks=false): Allows for more efficient parsing by seeking to specific positions in the file when needed.
  • With seeking disabled (avoidSeeks=true): Parses the file sequentially, which is useful for streaming or non-seekable input sources.

After creating a parser with NewMatroskaParser, you can access file information, track information, and read media packets using the provided methods.

func NewMatroskaParser

func NewMatroskaParser(r io.ReadSeeker, avoidSeeks bool) (*MatroskaParser, error)

NewMatroskaParser creates a new Matroska parser for the given ReadSeeker.

This function initializes a MatroskaParser and parses the EBML header and main segment of the Matroska file. It validates that the file is a valid Matroska or WebM file by checking the document type in the EBML header.

Parameters:

  • r: An io.ReadSeeker that provides access to the Matroska file data. This can be a file, network stream, or any other source that supports both reading and seeking operations.
  • avoidSeeks: A boolean flag that controls whether the parser should avoid seeking operations. When set to true, the parser will parse the file sequentially, which is useful for streaming or non-seekable input sources. When set to false, the parser can seek to specific positions in the file for more efficient parsing.

Returns:

  • *MatroskaParser: A pointer to the initialized MatroskaParser.
  • error: An error if the parser could not be created or if the file is not a valid Matroska or WebM file.

Example:

file, err := os.Open("video.mkv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

parser, err := matroska.NewMatroskaParser(file, false)
if err != nil {
    log.Fatal(err)
}

func (*MatroskaParser) GetAttachments

func (mp *MatroskaParser) GetAttachments() []*Attachment

GetAttachments returns all attachments

func (*MatroskaParser) GetChapters

func (mp *MatroskaParser) GetChapters() []*Chapter

GetChapters returns all chapters

func (*MatroskaParser) GetCues

func (mp *MatroskaParser) GetCues() []*Cue

GetCues returns all cues

func (*MatroskaParser) GetCuesPos

func (mp *MatroskaParser) GetCuesPos() uint64

GetCuesPos returns the cues position

func (*MatroskaParser) GetCuesTopPos

func (mp *MatroskaParser) GetCuesTopPos() uint64

GetCuesTopPos returns the cues top position

func (*MatroskaParser) GetFileInfo

func (mp *MatroskaParser) GetFileInfo() *SegmentInfo

GetFileInfo returns file-level information

func (*MatroskaParser) GetNumTracks

func (mp *MatroskaParser) GetNumTracks() uint

GetNumTracks returns the number of tracks

func (*MatroskaParser) GetSegment

func (mp *MatroskaParser) GetSegment() uint64

GetSegment returns the segment position

func (*MatroskaParser) GetSegmentTop

func (mp *MatroskaParser) GetSegmentTop() uint64

GetSegmentTop returns the segment top position

func (*MatroskaParser) GetTags

func (mp *MatroskaParser) GetTags() []*Tag

GetTags returns all tags

func (*MatroskaParser) GetTrackInfo

func (mp *MatroskaParser) GetTrackInfo(track uint) *TrackInfo

GetTrackInfo returns information about a specific track

func (*MatroskaParser) ReadPacket

func (mp *MatroskaParser) ReadPacket() (*Packet, error)

ReadPacket reads the next packet from the Matroska stream.

This method reads and parses the next media packet from the Matroska file. A packet represents a unit of media data, such as a video frame or audio samples, along with metadata about the packet, such as the track number, timestamp, and flags.

The method iterates through the elements in the file, looking for Cluster, SimpleBlock, and BlockGroup elements, which contain the actual media data. When it encounters a Cluster element, it parses the cluster header to update the cluster timestamp. When it encounters a SimpleBlock or BlockGroup element, it parses the block and returns a Packet struct containing the media data and metadata.

If the method encounters a Timestamp element within a cluster, it updates the cluster timestamp accordingly. Unknown elements are skipped.

Returns:

  • *Packet: A pointer to the parsed Packet struct containing the media data and metadata. Returns nil when the end of the file is reached.
  • error: An error if a packet could not be read or parsed. When the end of the file is reached, the error will be io.EOF.

Example:

for {
    packet, err := parser.ReadPacket()
    if err != nil {
        if err == io.EOF {
            break
        }
        log.Fatal(err)
    }
    // Process packet...
    fmt.Printf("Track: %d, Timestamp: %d\n", packet.Track, packet.StartTime)
}

func (*MatroskaParser) Seek added in v1.2.0

func (mp *MatroskaParser) Seek(timecode uint64, flags uint32) error

func (*MatroskaParser) SetTrackMask added in v1.2.0

func (mp *MatroskaParser) SetTrackMask(mask uint64)

func (*MatroskaParser) SkipToKeyframe added in v1.2.0

func (mp *MatroskaParser) SkipToKeyframe()

type Packet

type Packet struct {
	// Track is the track number this packet belongs to.
	// This corresponds to the TrackInfo.Number of the track.
	Track uint8
	// StartTime is the start time of this packet in nanoseconds.
	// This is the timestamp when the packet should be presented.
	StartTime uint64
	// EndTime is the end time of this packet in nanoseconds.
	// This is the timestamp when the packet should stop being presented.
	EndTime uint64
	// FilePos is the position in the input stream where this packet is located.
	// This can be useful for seeking or debugging purposes.
	FilePos uint64
	// Data contains the actual packet data.
	// This is the raw media data that needs to be decoded by the appropriate codec.
	Data []byte
	// Flags contains any packet flags. See the packet flag constants for details.
	// These flags provide additional information about the packet's properties.
	Flags uint32
	// Discard indicates whether this packet can be discarded.
	// A non-zero value suggests that the packet can be safely discarded without affecting playback.
	Discard int64
}

Packet contains a demuxed packet from a Matroska file.

A Packet represents a single unit of media data that has been extracted (demuxed) from a Matroska container. It contains all the necessary information to process the media data, including timing information, track association, and the actual data payload.

type SegmentElement

type SegmentElement struct {
	Position uint64
	Size     uint64
}

SegmentElement represents the main segment element in a Matroska file.

The segment is the top-level element in a Matroska file that contains all the actual data, including metadata, tracks, clusters, and other elements. It is the largest element in the file and contains all other elements except for the EBML header.

The Position field indicates the byte offset from the beginning of the file where the segment element starts, and the Size field indicates the total size of the segment element in bytes.

type SegmentInfo

type SegmentInfo struct {
	// UID is the top-level unique identifier for this segment.
	// This is a 128-bit UUID that uniquely identifies this segment.
	UID [16]byte
	// PrevUID is the UID of any files which should be played back before this one.
	// This is used to create a sequence of related files.
	PrevUID [16]byte
	// NextUID is the UID of any files which should be played back after this one.
	// This is used to create a sequence of related files.
	NextUID [16]byte
	// Filename is the filename of this segment.
	// This is a human-readable name for the file.
	Filename string
	// PrevFilename is the filename of any files which should be played back before this one.
	// This corresponds to the file with UID equal to PrevUID.
	PrevFilename string
	// NextFilename is the filename of any files which should be played back after this one.
	// This corresponds to the file with UID equal to NextUID.
	NextFilename string
	// Title is the title of the segment.
	// This is a human-readable title for the content.
	Title string
	// MuxingApp is the name of the application that muxed this file.
	// This is useful for debugging and compatibility purposes.
	MuxingApp string
	// WritingApp is the name of the library that muxed this file.
	// This is useful for debugging and compatibility purposes.
	WritingApp string
	// TimecodeScale is the timescale of any timecodes in the segment.
	// This is used to convert timecodes to nanoseconds. The default is 1000000.
	TimecodeScale uint64
	// Duration is the file's duration in nanoseconds. May be 0 if unknown.
	Duration uint64
	// DateUTC is the date the file was created on, in nanoseconds since the Unix epoch.
	// This can be used to determine when the file was created.
	DateUTC int64
	// DateUTCValid indicates whether or not DateUTC can be considered valid.
	// If false, the DateUTC value should not be used.
	DateUTCValid bool
}

SegmentInfo contains file-level (segment) information about a Matroska stream.

A SegmentInfo structure holds metadata about the entire Matroska file or segment. This includes general information like title, duration, creation date, and relationships to other files in a sequence.

type SimpleTag

type SimpleTag struct {
	// Name is the tag name.
	// This is the key part of the key-value pair.
	Name string
	// Value is the tag value.
	// This is the value part of the key-value pair.
	Value string
	// Language is the tag language.
	// This follows the ISO 639-2 language codes (e.g., "eng" for English).
	Language string
	// Default indicates whether this tag is applied by default.
	// If true, this tag should be used unless the user explicitly selects another language.
	Default bool
}

SimpleTag contains a simple Matroska tag.

A SimpleTag structure represents a single key-value metadata tag. These tags can be used to store information like title, artist, album, etc.

type Tag

type Tag struct {
	// Targets is a list of associated targets.
	// This specifies what elements in the file the tags apply to.
	Targets []Target
	// SimpleTags is a list of associated simple tags.
	// These are the actual key-value metadata pairs.
	SimpleTags []SimpleTag
}

Tag contains all information relating to a Matroska tag.

A Tag structure represents a collection of metadata tags that can be applied to various targets within a Matroska file. Tags are used to store metadata like titles, descriptions, and other information about the content.

type Target

type Target struct {
	// UID is the target's unique identifier.
	// This identifies the specific element that the tag applies to.
	UID uint64
	// Type is the target type. See the tag target type constants.
	// This determines what kind of element the tag applies to.
	Type uint32
}

Target contains information about a tag's target.

A Target structure identifies what a Matroska tag applies to. Tags can be applied to tracks, chapters, attachments, or editions.

type TrackInfo

type TrackInfo struct {
	// Number is the track number used to identify this track within the Matroska file.
	// Track numbers are unique within a segment and are used to associate packets with tracks.
	Number uint8
	// Type is the track type. See the track type constants (TypeVideo, TypeAudio, TypeSubtitle).
	Type uint8
	// TrackOverlay specifies whether this track should be overlaid on another track.
	// This is typically used for subtitle or menu tracks that need to be displayed over video.
	TrackOverlay uint8
	// UID is a unique identifier for this track.
	// This allows tracks to be referenced even if their numbers change.
	UID uint64
	// MinCache is the minimum amount of frames a player should keep around to
	// be able to play back this file properly, e.g. the min DPB (Decoded Picture Buffer) size.
	MinCache uint64
	// MaxCache is the largest possible size a player could need for its cache
	// in order to play back this file smoothly.
	MaxCache uint64
	// DefaultDuration is the track's default duration in nanoseconds, which can be used,
	// for example, to calculate the duration of the last packet.
	DefaultDuration uint64
	// CodecDelay is any inherent delay required by the codec in nanoseconds.
	// This is used to ensure proper audio/video synchronization.
	CodecDelay uint64
	// SeekPreRoll is any pre-roll that must be applied after seeking for this codec.
	// This ensures that the decoder has enough data to start playback correctly after a seek.
	SeekPreRoll uint64
	// TimecodeScale is the timescale for this track's timecodes.
	// This is used to convert between the track's internal timecode and actual time.
	TimecodeScale float64
	// CodecPrivate contains codec-specific private data that should be passed to decoders.
	// This typically includes initialization data required by the codec.
	CodecPrivate []byte
	// CompMethod is the track compression method. See the compression method constants.
	CompMethod uint32
	// CompMethodPrivate contains any private data that should be passed to the decompressor
	// used to decompress the track.
	CompMethodPrivate []byte
	// MaxBlockAdditionID is the maximum ID of the BlockAdditional elements for this track.
	// This is used to identify additional data blocks associated with the track.
	MaxBlockAdditionID uint32

	// Enabled indicates whether this track is enabled and should be played.
	Enabled bool
	// Default indicates whether this track is on by default.
	// If true, the track should be enabled unless the user explicitly disables it.
	Default bool
	// Forced indicates whether this track is forced on.
	// Forced tracks are typically used for subtitles that must be displayed regardless of user preferences.
	Forced bool
	// Lacing indicates whether this track uses lacing.
	// Lacing is a method of reducing overhead by storing multiple small blocks in a single frame.
	Lacing bool
	// DecodeAll indicates whether this track has Error Resilience capabilities.
	// If true, the player should attempt to decode all frames even if some are corrupted.
	DecodeAll bool
	// CompEnabled indicates whether this track has compression enabled.
	CompEnabled bool

	// Video contains video-specific information. Only valid if the track is a video track.
	Video struct {
		// StereoMode is the stereo 3D mode used, if any.
		// This defines how the video should be displayed for 3D playback.
		StereoMode uint8
		// DisplayUnit is the unit used for DisplayWidth and DisplayHeight.
		// This defines whether the display dimensions are in pixels, centimeters, or inches.
		DisplayUnit uint8
		// AspectRatioType defines what type of resizing is needed for the aspect ratio:
		//     0 = free resizing
		//     1 = keep aspect ratio
		//     2 = fixed
		AspectRatioType uint8
		// PixelWidth is the width of the video in pixels.
		PixelWidth uint32
		// PixelHeight is the height of the video in pixels.
		PixelHeight uint32
		// DisplayWidth is the width at which the video should be displayed.
		// This may differ from PixelWidth if the video needs to be scaled.
		DisplayWidth uint32
		// DisplayHeight is the height at which the video should be displayed.
		// This may differ from PixelHeight if the video needs to be scaled.
		DisplayHeight uint32
		// CropL is the number of pixels to crop from the left side of the video.
		CropL uint32
		// CropT is the number of pixels to crop from the top of the video.
		CropT uint32
		// CropR is the number of pixels to crop from the right side of the video.
		CropR uint32
		// CropB is the number of pixels to crop from the bottom of the video.
		CropB uint32
		// ColourSpace is the colorspace of the video, similar to biCompression from BITMAPINFOHEADER.
		ColourSpace uint32
		// GammaValue is the gamma value to use for color adjustment.
		GammaValue float64
		// Colour contains detailed color information for the video.
		Colour struct {
			// MatrixCoefficients defines the matrix coefficients used for the video.
			// See: ISO/IEC 23091-4/ITU-T H.273 for standard values.
			MatrixCoefficients uint32
			// BitsPerChannel is the number of bits per color channel.
			BitsPerChannel uint32
			// ChromaSubsamplingHorz is the base 2 logarithm of horizontal chroma subsampling.
			ChromaSubsamplingHorz uint32
			// ChromaSubsamplingVert is the base 2 logarithm of vertical chroma subsampling.
			ChromaSubsamplingVert uint32
			// CbSubsamplingHorz is the amount of pixels to remove in the Cb channel for every pixel
			// not removed horizontally. This is additive with ChromaSubsamplingHorz.
			CbSubsamplingHorz uint32
			// CbSubsamplingVert is the amount of pixels to remove in the Cb channel for every pixel
			// not removed vertically. This is additive with ChromaSubsamplingVert.
			CbSubsamplingVert uint32
			// ChromaSitingHorz is the horizontal chroma position:
			//     0 = unspecified,
			//     1 = left collocated
			//     2 = half
			ChromaSitingHorz uint32
			// ChromaSitingVert is the vertical chroma position:
			//     0 = unspecified
			//     1 = left collocated
			//     2 = half
			ChromaSitingVert uint32
			// Range defines the color range:
			//     0 = unspecified
			//     1 = broadcast range (16-235)
			//     2 = full range (0-255)
			//     3 = defined by MatrixCoefficients / TransferCharacteristics
			Range uint32
			// TransferCharacteristics defines the transfer characteristics of the video.
			// See: ISO/IEC 23091-4/ITU-T H.273 for standard values.
			TransferCharacteristics uint32
			// Primaries defines the color primaries of the video.
			// See: ISO/IEC 23091-4/ITU-T H.273 for standard values.
			Primaries uint32
			// MaxCLL is the maximum content light level in nits.
			// This is used for HDR content to indicate the brightest point in the content.
			MaxCLL uint32
			// MaxFALL is the maximum frame-average light level in nits.
			// This is used for HDR content to indicate the average brightness of the brightest frame.
			MaxFALL uint32
			// MasteringMetadata contains mastering display metadata for HDR content.
			MasteringMetadata struct {
				// PrimaryRChromaticityX is the X chromaticity coordinate of the red primary.
				PrimaryRChromaticityX float32
				// PrimaryRChromaticityY is the Y chromaticity coordinate of the red primary.
				PrimaryRChromaticityY float32
				// PrimaryGChromaticityX is the X chromaticity coordinate of the green primary.
				PrimaryGChromaticityX float32
				// PrimaryGChromaticityY is the Y chromaticity coordinate of the green primary.
				PrimaryGChromaticityY float32
				// PrimaryBChromaticityX is the X chromaticity coordinate of the blue primary.
				PrimaryBChromaticityX float32
				// PrimaryBChromaticityY is the Y chromaticity coordinate of the blue primary.
				PrimaryBChromaticityY float32
				// WhitePointChromaticityX is the X chromaticity coordinate of the white point.
				WhitePointChromaticityX float32
				// WhitePointChromaticityY is the Y chromaticity coordinate of the white point.
				WhitePointChromaticityY float32
				// LuminanceMax is the maximum luminance of the display in nits.
				LuminanceMax float32
				// LuminanceMin is the minimum luminance of the display in nits.
				LuminanceMin float32
			}
		}
		// Interlaced indicates whether the video is interlaced.
		// If true, the video consists of interlaced fields rather than progressive frames.
		Interlaced bool
	}
	// Audio contains audio-specific information. Only valid if the track is an audio track.
	Audio struct {
		// SamplingFreq is the sampling frequency of the audio in Hz.
		SamplingFreq float64
		// OutputSamplingFreq is the sampling frequency to output during playback in Hz.
		// This may differ from SamplingFreq if resampling is required.
		OutputSamplingFreq float64
		// Channels is the number of audio channels.
		Channels uint8
		// BitDepth is the bit depth of the audio samples.
		BitDepth uint8
	}

	// Name is the human-readable name of the track.
	// This can be displayed to users to identify the track.
	Name string
	// Language is the language code of the track.
	// This follows the ISO 639-2 language codes (e.g., "eng" for English).
	Language string
	// CodecID is the identifier for the codec used by this track.
	// This is a string that identifies the codec, such as "V_MPEG4/ISO/AVC" for H.264 video.
	CodecID string
}

TrackInfo contains information about a track in a Matroska file.

A TrackInfo structure holds all metadata and configuration information for a single track within a Matroska file. This includes general track properties, codec information, and type-specific settings for video, audio, or subtitle tracks.

Directories

Path Synopsis
example
extracter command
Package main demonstrates how to use the Matroska/EBML library to extract tracks from Matroska files.
Package main demonstrates how to use the Matroska/EBML library to extract tracks from Matroska files.
seeker command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL