Chapters

The pymkv.chapters module provides a programmatic way to create and manage Matroska chapters. It uses a structured approach with msgspec to ensure that the chapter hierarchy (EditionEntry -> ChapterAtom -> ChapterDisplay) is correctly maintained and can be easily exported to the XML format required by mkvmerge.

Overview

Matroska chapters are organized into Editions, which contain one or more Chapter Atoms. Each Chapter Atom can have multiple Displays (for different languages) and can also contain nested sub-chapters.

Using Chapters

There are two primary ways to work with chapters in pymkv.

Simple Chapters

For basic use cases, you can use the add_simple_chapter helper method. This is the easiest way to add a sequence of chapters to a file.

from pymkv.chapters import Chapters, ChapterAtom

# Create and export
chapters = Chapters()
chapters.add_simple_chapter("00:00:00.000", "Intro")
xml = export_to_xml(chapters)

You can also add chapters directly to an MKVFile object:

from pymkv import MKVFile
from pymkv.chapters import ChapterAtom, ChapterDisplay

mkv = MKVFile()

# Add simple chapter directly
atom = ChapterAtom(
    time_start="00:00:00.000",
    displays=[ChapterDisplay(string="Intro")]
)
mkv.add_chapter(atom)

Complex Nested Chapters

For more advanced scenarios, such as nested chapters, you can build the structure manually.

from pymkv.chapters import Chapters, ChapterAtom, ChapterDisplay, EditionEntry

# Create the container
chapters = Chapters()

# Create complex nested chapters
display = ChapterDisplay(string="Nested Chapter", language="eng")
atom = ChapterAtom(time_start="00:05:00.000", displays=[display])

parent = ChapterAtom(time_start="00:01:00.000", atoms=[atom])

# Add to manually created edition
edition = EditionEntry(atoms=[parent])
chapters.editions.append(edition)

API Reference

This module provides classes for creating and managing Matroska chapters programmatically.

It uses msgspec structs to represent the hierarchical structure of chapters (EditionEntry -> ChapterAtom -> ChapterDisplay) and provides functionality to export these structures to the XML format required by mkvmerge.

Examples

>>> from pymkv.chapters import Chapters, ChapterAtom, ChapterDisplay
>>>
>>> # Create the container
>>> chapters = Chapters()
>>>
>>> # Method 1: Use helper for simple chapters
>>> chapters.add_simple_chapter("00:00:00.000", "Intro")
>>>
>>> # Method 2: Create complex nested chapters
>>> display = ChapterDisplay(string="Nested Chapter", language="eng")
>>> atom = ChapterAtom(time_start="00:05:00.000", displays=[display])
>>>
>>> parent = ChapterAtom(time_start="00:01:00.000", atoms=[atom])
>>>
>>> # Add to manually created edition
>>> from pymkv.chapters import EditionEntry
>>> edition = EditionEntry(atoms=[parent])
>>> chapters.editions.append(edition)
>>>
>>> # Export to XML
>>> xml_content = export_to_xml(chapters)
class pymkv.chapters.Chapters(editions: list[~pymkv.chapters.EditionEntry] = <factory>)

Root container for chapters.

Examples

>>> from pymkv.chapters import Chapters, ChapterAtom
>>>
>>> # Create and export
>>> chapters = Chapters()
>>> chapters.add_simple_chapter("00:00:00.000", "Intro")
>>> xml = export_to_xml(chapters)
add_simple_chapter(time_start: str, title: str, language: str = 'eng') None

Helper to add a simple chapter to the first edition (creates one if needed).

editions : list[EditionEntry]
class pymkv.chapters.ChapterAtom(time_start: str, time_end: str | None = None, uid: int | None = None, hidden: bool | None = None, enabled: bool | None = None, displays: list[~pymkv.chapters.ChapterDisplay] = <factory>, atoms: list[~pymkv.chapters.ChapterAtom] = <factory>)

A single chapter atom.

Examples

>>> from pymkv.chapters import ChapterAtom, ChapterDisplay
>>>
>>> # Simple chapter with title
>>> atom = ChapterAtom(
...     time_start="00:00:10.000",
...     displays=[ChapterDisplay(string="Chapter 1")]
... )
>>>
>>> # Nested chapters
>>> parent = ChapterAtom(
...     time_start="00:00:00.000",
...     atoms=[
...         ChapterAtom(time_start="00:05:00.000")
...     ]
... )
atoms : list[ChapterAtom]
displays : list[ChapterDisplay]
enabled : bool | None
hidden : bool | None
time_end : str | None
time_start : str
uid : int | None
class pymkv.chapters.ChapterDisplay(string: str, language: str = 'eng', country: str | None = None)

Display properties for a chapter.

country : str | None
language : str
string : str
class pymkv.chapters.EditionEntry(uid: int | None = None, hidden: bool | None = None, default: bool | None = None, ordered: bool | None = None, atoms: list[~pymkv.chapters.ChapterAtom] = <factory>)

An edition entry containing chapters.

atoms : list[ChapterAtom]
default : bool | None
hidden : bool | None
ordered : bool | None
uid : int | None

Module Functions

pymkv.chapters.export_to_xml(chapters: Chapters) str

Export Chapters object to XML string.