Tracks API¶
Auto-generated reference for the track model: Tracks,
Track, and the media-specific subclasses. See
Service Architecture for how these fit together.
Attachment
¶
Create a new Attachment.
If providing a path, the file must already exist. If providing a URL, the file will be downloaded to the temp directory. Either path or url must be provided.
If name is not provided it will use the file name (without extension). If mime_type is not provided, it will try to guess it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[Path, str, None]
|
Path to an existing file. |
None
|
url
|
Optional[str]
|
URL to download the attachment from. |
None
|
name
|
Optional[str]
|
Name of the attachment. |
None
|
mime_type
|
Optional[str]
|
MIME type of the attachment. |
None
|
description
|
Optional[str]
|
Description of the attachment. |
None
|
session
|
Optional[Session]
|
Optional requests session to use for downloading. |
None
|
from_url
classmethod
¶
Create an attachment from a URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
URL to download the attachment from. |
required |
name
|
Optional[str]
|
Name of the attachment. |
None
|
mime_type
|
Optional[str]
|
MIME type of the attachment. |
None
|
description
|
Optional[str]
|
Description of the attachment. |
None
|
session
|
Optional[Session]
|
Optional requests session to use for downloading. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Attachment |
'Attachment'
|
A new attachment instance. |
Audio
¶
Bases: Track
Create a new Audio track object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
codec
|
Optional[Codec]
|
An Audio.Codec enum representing the audio codec. If not specified, MediaInfo will be used to retrieve the codec once the track has been downloaded. |
None
|
bitrate
|
Optional[Union[str, int, float]]
|
A number or float representing the average bandwidth in bytes/s. Float values are rounded up to the nearest integer. |
None
|
channels
|
Optional[Union[str, int, float]]
|
A number, float, or string representing the number of audio channels. Strings may represent numbers or floats. Expanded layouts like 7.1.1 is not supported. All numbers and strings will be cast to float. |
None
|
joc
|
Optional[int]
|
The number of Joint-Object-Coding Channels/Objects in the audio stream. |
None
|
descriptive
|
Union[bool, int]
|
Mark this audio as being descriptive audio for the blind. |
False
|
Note: If codec, bitrate, channels, or joc is not specified some checks may be skipped or assume a value. Specifying as much information as possible is highly recommended.
parse_channels
staticmethod
¶
Converts a Channel string to a float representing audio channel count and layout. E.g. "3" -> "3.0", "2.1" -> "2.1", ".1" -> "0.1".
This does not validate channel strings as genuine channel counts or valid layouts. It does not convert the value to assume a sub speaker channel layout, e.g. 5.1->6.0. It also does not support expanded surround sound channel layout strings like 7.1.2.
Chapter
¶
Create a new Chapter with a Timestamp and optional name.
The timestamp may be in the following formats:
- "HH:MM:SS" string, e.g., 25:05:23.
- "HH:MM:SS.mss" string, e.g., 25:05:23.120.
- a timecode integer in milliseconds, e.g., 90323120 is 25:05:23.120.
- a timecode float in seconds, e.g., 90323.12 is 25:05:23.120.
If you have a timecode integer in seconds, just multiply it by 1000. If you have a timecode float in milliseconds (no decimal value), just convert it to an integer.
Chapters
¶
Bases: SortedKeyList, ABC
dumps
¶
Return chapter data in OGM-based Simple Chapter format. https://mkvtoolnix.download/doc/mkvmerge.html#mkvmerge.chapters.simple
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fallback_name
|
str
|
Name used for Chapters without a Name set. |
''
|
The fallback name can use the following variables in f-string style:
- {i}: The Chapter number starting at 1.
E.g.,
"Chapter {i}": "Chapter 1", "Intro", "Chapter 3". - {j}: A number starting at 1 that increments any time a Chapter has no name.
E.g.,
"Chapter {j}": "Chapter 1", "Intro", "Chapter 2".
These are formatted with f-strings, directives are supported.
For example, "Chapter {i:02}" will result in "Chapter 01".
dump
¶
Write chapter data in OGM-based Simple Chapter format to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[Path, str]
|
The file path to write the Chapter data to, overwriting any existing data. |
required |
See Chapters.dumps for more parameter documentation.
Hybrid
¶
log
instance-attribute
¶
Takes the Dolby Vision and HDR10(+) streams out of the VideoTracks. It will then attempt to inject the Dolby Vision metadata layer to the HDR10(+) stream. If no DV track is available but HDR10+ is present, it will convert HDR10+ to DV.
level_5
¶
Generate Level 5 active area metadata via crop detection on the HDR10 stream.
This resolves mismatches where DV has no black bars but HDR10 does (or vice versa) by telling the display the correct active area.
sanitize_l6
staticmethod
¶
Clamp static L6 values to a valid relationship.
MaxCLL must not exceed the mastering-display peak (some sources, e.g. ATV HDR10+, ship MaxCLL 10000 on a 1000-nit master), and MaxFALL must not exceed MaxCLL. A value of 0 means "unknown" and is preserved as-is.
Subtitle
¶
Bases: Track
Create a new Subtitle track object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
codec
|
Optional[Codec]
|
A Subtitle.Codec enum representing the subtitle format. If not specified, MediaInfo will be used to retrieve the format once the track has been downloaded. |
None
|
cc
|
bool
|
Closed Caption. - Intended as if you couldn't hear the audio at all. - Can have Sound as well as Dialogue, but doesn't have to. - Original source would be from an EIA-CC encoded stream. Typically all upper-case characters. Indicators of it being CC without knowing original source: - Extracted with CCExtractor, or - >>> (or similar) being used at the start of some or all lines, or - All text is uppercase or at least the majority, or - Subtitles are Scrolling-text style (one line appears, oldest line then disappears). Just because you downloaded it as a SRT or VTT or such, doesn't mean it isn't from an EIA-CC stream. And I wouldn't take the streaming services (CC) as gospel either as they tend to get it wrong too. |
False
|
sdh
|
bool
|
Deaf or Hard-of-Hearing. Also known as HOH in the UK (EU?). - Intended as if you couldn't hear the audio at all. - MUST have Sound as well as Dialogue to be considered SDH. - It has no "syntax" or "format" but is not transmitted using archaic forms like EIA-CC streams, would be intended for transmission via SubRip (SRT), WebVTT (VTT), TTML, etc. If you can see important audio/sound transcriptions and not just dialogue and it doesn't have the indicators of CC, then it's most likely SDH. If it doesn't have important audio/sounds transcriptions it might just be regular subtitling (you wouldn't mark as CC or SDH). This would be the case for most translation subtitles. Like Anime for example. |
False
|
forced
|
bool
|
Typically used if there's important information at some point in time like watching Dubbed content and an important Sign or Letter is shown or someone talking in a different language. Forced tracks are recommended by the Matroska Spec to be played if the player's current playback audio language matches a subtitle marked as "forced". However, that doesn't mean every player works like this but there is no other way to reliably work with Forced subtitles where multiple forced subtitles may be in the output file. Just know what to expect with "forced" subtitles. |
False
|
Note: If codec is not specified some checks may be skipped or assume a value. Specifying as much information as possible is highly recommended.
Information on Subtitle Types
https://bit.ly/2Oe4fLC (3PlayMedia Blog on SUB vs CC vs SDH). However, I wouldn't pay much attention to the claims about SDH needing to be in the original source language. It's logically not true.
CC == Closed Captions. Source: Basically every site. SDH = Subtitles for the Deaf or Hard-of-Hearing. Source: Basically every site. HOH = Exact same as SDH. Is a term used in the UK. Source: https://bit.ly/2PGJatz (ICO UK)
More in-depth information, examples, and stuff to look for can be found in the Parameter explanation list above.
sanitize_webvtt_timestamps
staticmethod
¶
Fix invalid timestamps in WebVTT files, particularly negative timestamps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
str
|
Sanitized WebVTT content |
has_webvtt_cue_identifiers
staticmethod
¶
Check if WebVTT content has cue identifiers that need removal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if cue identifiers are detected, False otherwise |
sanitize_webvtt_cue_identifiers
staticmethod
¶
Remove WebVTT cue identifiers that can confuse subtitle parsers.
Some services use cue identifiers like "Q0", "Q1", etc. that appear on their own line before the timing line. These can be incorrectly parsed as part of the previous cue's text content by some parsers (like pysubs2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
str
|
Sanitized WebVTT content with cue identifiers removed |
has_overlapping_webvtt_cues
staticmethod
¶
Check if WebVTT content has overlapping cues that need merging.
Detects cues with start times within 50ms of each other and the same end time, which indicates multi-line subtitles split into separate cues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if overlapping cues are detected, False otherwise |
merge_overlapping_webvtt_cues
staticmethod
¶
Merge WebVTT cues that have overlapping/near-identical times but different line positions.
Some services use separate cues for each line of a multi-line subtitle, with slightly different start times (1ms apart) and different line: positions. This merges them into single cues with proper line ordering based on the line: position (lower percentage = higher on screen = first line).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
str
|
WebVTT content with overlapping cues merged |
sanitize_webvtt
staticmethod
¶
More thorough sanitization of WebVTT files to handle multiple potential issues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
str
|
Sanitized WebVTT content |
convert
¶
Convert this Subtitle to another format.
Backend selection is data-driven (see tracks/subtitle_convert.py): the best
available backend that supports source->target is used, falling back through the
capability chain on failure. The backend can be pinned via the conversion_method
config key (auto | subby | pysubs2 | subtitleedit | pycaption),
or nudged per-service via preferred_conversion_method; an explicit config value
always wins.
forced marks an explicit user request (--sub-format). Lossy downconverts of
styled formats (SSA/ASS -> SRT) are skipped unless forced is True.
extract_fonts
staticmethod
¶
Font names referenced by an ASS/SSA subtitle.
Covers both sources that need attaching for correct rendering:
- the Fontname column of every Style: line in [V4+ Styles]/[V4 Styles]
(column located from the section's Format: line, not assumed by index), and
- inline \fn font overrides inside Dialogue override blocks.
Leading @ (vertical-writing prefix) is stripped and names are de-duplicated
case-insensitively, preferring a mixed-case spelling over an all-lowercase one.
sanitize_broken_webvtt
staticmethod
¶
Remove or fix corrupted WebVTT lines, particularly those with invalid timestamps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The WebVTT content as string |
required |
Returns:
| Type | Description |
|---|---|
str
|
Sanitized WebVTT content with corrupted lines removed |
space_webvtt_headers
staticmethod
¶
Space out the WEBVTT Headers from Captions.
Segmented VTT when merged may have the WEBVTT headers part of the next caption as they were not separated far enough from the previous caption and ended up being considered as caption text rather than the header for the next segment.
merge_same_cues
staticmethod
¶
Merge captions with the same timecodes and text as one in-place.
filter_unwanted_cues
staticmethod
¶
Filter out subtitle cues containing only or whitespace.
merge_segmented_wvtt
staticmethod
¶
Convert Segmented DASH WebVTT cues into a pycaption Caption List. Also returns an ISO 639-2 alpha-3 language code if available.
Code ported originally by xhlove to Python from shaka-player. Has since been improved upon by rlaphoenix using pymp4 and pycaption functions.
strip_hearing_impaired
¶
Strip captions for hearing impaired (SDH).
The SDH stripping method is determined by the 'sdh_method' setting in config: - 'auto' (default): Tries subby first, then SubtitleEdit, then filter-subs - 'subby': Uses subby's SDHStripper - 'subtitleedit': Uses SubtitleEdit when available - 'filter-subs': Uses subtitle-filter library
reverse_rtl
¶
Reverse RTL (Right to Left) Start/End on Captions. This can be used to fix the positioning of sentence-ending characters.
DownloadContext
dataclass
¶
DownloadContext(
save_path,
save_dir,
progress,
session=None,
proxy=None,
max_workers=None,
license_widevine=None,
cdm=None,
)
Shared arguments passed to each manifest's download_track.
Track
¶
Track(
url,
language,
is_original_lang=False,
descriptor=URL,
needs_repack=False,
name=None,
drm=None,
edition=None,
session=None,
downloader=None,
downloader_args=None,
from_file=None,
data=None,
id_=None,
extra=None,
)
data
property
writable
¶
Arbitrary track data dictionary.
A defaultdict is used with a dict as the factory for easier nested saving and safer exists-checks.
Reserved keys:
- "hls" used by the HLS class.
- playlist: m3u8.model.Playlist - The primary track information.
- media: m3u8.model.Media - The audio/subtitle track information.
- segment_durations: list[int] - A list of each segment's duration.
- "dash" used by the DASH class.
- manifest: lxml.ElementTree - DASH MPD manifest.
- period: lxml.Element - The period of this track.
- adaptation_set: lxml.Element - The adaptation set of this track.
- representation: lxml.Element - The representation of this track.
- timescale: int - The timescale of the track's segments.
- segment_durations: list[int] - A list of each segment's duration.
You should not add, change, or remove any data within reserved keys. You may use their data but do note that the values of them may change or be removed at any point.
download
¶
download(
session,
prepare_drm,
max_workers=None,
progress=None,
*,
cdm=None,
no_proxy_download=False,
)
Download and optionally Decrypt this Track.
move
¶
Move the Track's file from current location, to target location. This will overwrite anything at the target path.
Raises:
| Type | Description |
|---|---|
TypeError
|
If the target argument is not the expected type. |
ValueError
|
If track has no file to move, or the target does not exist. |
OSError
|
If the file somehow failed to move. |
Returns the new location of the track.
to_dict
¶
Serialise the track for export/import (identity/URL/descriptor/language).
DRM is not serialised here; the export writer attaches the licensed DRM + keys. Subclasses add their own codec/quality fields.
base_kwargs_from_dict
staticmethod
¶
Build the shared Track constructor kwargs from a to_dict() payload.
DRM is not reconstructed here — to_dict does not serialise it, and the import
flow attaches the licensed DRM + content keys separately.
from_dict
classmethod
¶
Reconstruct the correct Track subclass from a to_dict() payload.
get_key_id
¶
Probe the DRM encryption Key ID (KID) for this specific track.
It currently supports finding the Key ID by probing the track's stream
with ffprobe for enc_key_id data, as well as for mp4 tenc (Track
Encryption) boxes.
It explicitly ignores PSSH information like the PSSH box, as the box
is likely to contain multiple Key IDs that may or may not be for this
specific track.
To retrieve the initialization segment, this method calls :meth:get_init_segment
with the positional and keyword arguments. The return value of get_init_segment
is then used to determine the Key ID.
Returns:
| Type | Description |
|---|---|
Optional[UUID]
|
The Key ID as a UUID object, or None if the Key ID could not be determined. |
load_drm_if_needed
¶
Load DRM information for this track if it was deferred during parsing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service
|
Service instance that can fetch track-specific DRM info |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
True if DRM was loaded or already present, False if failed |
load_drm_from_playlist
¶
Fallback method to load DRM by fetching this track's individual playlist.
get_init_segment
¶
Get the Track's Initial Segment Data Stream.
HLS and DASH tracks must explicitly provide a URL to the init segment or file. Providing the byte-range for the init segment is recommended where possible.
If byte_range is not set, it will make a HEAD request and check the size of
the file. If the size could not be determined, it will download up to the first
20KB only, which should contain the entirety of the init segment. You may
override this by changing the maximum_size.
The default maximum_size of 20000 (20KB) is a tried-and-tested value that seems to work well across the board.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
maximum_size
|
int
|
Size to assume as the content length if byte-range is not used, the content size could not be determined, or the content size is larger than it. A value of 20000 (20KB) or higher is recommended. |
20000
|
url
|
Optional[str]
|
Explicit init map or file URL to probe from. |
None
|
byte_range
|
Optional[str]
|
Range of bytes to download from the explicit or implicit URL. |
None
|
session
|
Optional[Session]
|
Session context, e.g., authorization and headers. |
None
|
Tracks
¶
Video, Audio, Subtitle, Chapter, and Attachment Track Store. It provides convenience functions for listing, sorting, and selecting tracks.
add
¶
Add a provided track to its appropriate array and ensuring it's not a duplicate.
sort_videos
¶
Sort video tracks by resolution then bitrate, and optionally language.
sort_audio
¶
Sort audio tracks by bitrate, codec priority, Atmos, descriptive, and optionally language.
sort_subtitles
¶
Sort subtitle tracks by various track attributes to a common P2P standard. You may optionally provide a sequence of languages to prioritize to the top.
Section Order
- by_language groups prioritized to top, and ascending alphabetically
- then rest ascending alphabetically after the prioritized groups (Each section ascending alphabetically, but separated)
Language Group Order
- Forced
- Normal
- Hard of Hearing (SDH/CC) (Least to most captions expected in the subtitle)
type_priority overrides the Language Group Order with an explicit ranking of "forced", "normal", and "sdh" (cc counts as sdh); unlisted types fall to the end. The first track after sorting receives the default flag at mux time, so this also controls which subtitle type becomes default.
filter
¶
Return a new Tracks with tracks filtered by predicate, preserving metadata.
merge_video_selections
staticmethod
¶
Concatenate video selections, dropping duplicates (by track id, order-preserving).
A DV track can be chosen as both the hybrid ingredient (lowest) and an explicit deliverable; without dedup the same track would be muxed/downloaded twice.
partition_hybrid_videos
staticmethod
¶
Split videos into hybrid-ingredient candidates and the standalone-deliverable pool.
HDR10/HDR10+/DV tracks are hybrid ingredients; they only enter the standalone
pool when their range was explicitly requested alongside HYBRID, so e.g.
-r HYBRID muxes only the hybrid while -r HYBRID,HDR10P also delivers HDR10+.
flag_hybrid_ingredients
staticmethod
¶
Mark tracks selected only as hybrid ingredients so the standalone mux loop skips them.
A track that was also picked as an explicit deliverable (same track in both selections) stays unflagged and is muxed standalone alongside the hybrid.
mux
¶
mux(
title,
delete=True,
progress=None,
audio_expected=True,
title_language=None,
skip_subtitles=False,
)
Multiplex all the Tracks into a Matroska Container file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Set the Matroska Container file title. Usually displayed in players instead of the filename if set. |
required |
delete
|
bool
|
Delete all track files after multiplexing. |
True
|
progress
|
Optional[partial]
|
Update a rich progress bar via |
None
|
audio_expected
|
bool
|
Whether audio is expected in the output. Used to determine if embedded audio metadata should be added. |
True
|
title_language
|
Optional[Language]
|
The title's intended language. Used to select the best video track for audio metadata when multiple video tracks exist. |
None
|
skip_subtitles
|
bool
|
Skip muxing subtitle tracks into the container. |
False
|
Video
¶
Video(
*args,
codec=None,
range_=None,
bitrate=None,
width=None,
height=None,
fps=None,
scan_type=None,
closed_captions=None,
dv_compatible_bitstream=False,
**kwargs,
)
Bases: Track
Create a new Video track object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
codec
|
Optional[Codec]
|
A Video.Codec enum representing the video codec. If not specified, MediaInfo will be used to retrieve the codec once the track has been downloaded. |
None
|
range_
|
Optional[Range]
|
A Video.Range enum representing the video color range. Defaults to SDR if not specified. |
None
|
bitrate
|
Optional[Union[str, int, float]]
|
A number or float representing the average bandwidth in bytes/s. Float values are rounded up to the nearest integer. |
None
|
width
|
Optional[int]
|
The horizontal resolution of the video. |
None
|
height
|
Optional[int]
|
The vertical resolution of the video. |
None
|
fps
|
Optional[Union[str, int, float]]
|
A number, float, or string representing the frames/s of the video. Strings may represent numbers, floats, or a fraction (num/den). All strings will be cast to either a number or float. |
None
|
Note: If codec, bitrate, width, height, or fps is not specified some checks may be skipped or assume a value. Specifying as much information as possible is highly recommended.
Range
¶
Bases: str, Enum
from_cicp
staticmethod
¶
Convert CICP (Coding-Independent Code Points) values to Video Range.
CICP is defined in ITU-T H.273 and ISO/IEC 23091-2 for signaling video color properties independently of the compression codec. These values are used across AVC (H.264), HEVC (H.265), VVC, AV1, and other modern codecs.
The enum values (Primaries, Transfer, Matrix) match the official specifications: - ITU-T H.273: Coding-independent code points for video signal type identification - ISO/IEC 23091-2: Information technology — Coding-independent code points — Part 2: Video - H.264 Table E-3 (Colour Primaries) and Table E-4 (Transfer Characteristics) - H.265 Table E.3 and E.4 (identical to H.264)
Note: Value 0 = "Reserved" and Value 2 = "Unspecified" per specification. While both effectively mean "unknown" in practice, the distinction matters for spec compliance. Value 2 was added based on user feedback (GitHub issue) and verified against FFmpeg's AVColorPrimaries/AVColorTransferCharacteristic enums.
Sources: - https://www.itu.int/rec/T-REC-H.273 - https://www.itu.int/rec/T-REC-H.Sup19-202104-I - https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/pixfmt.h
change_color_range
¶
Change the Video's Color Range to Limited (0) or Full (1).
normalize_vui
¶
Rewrite SPS VUI colour metadata to match self.range.
Some services ship HDR10/HLG bitstreams with stale BT.709 VUI, which makes downstream tools mis-classify the file. The manifest-derived range is the source of truth. Skips SDR, DV, and HYBRID. Returns True if the bitstream was rewritten.
ccextractor
¶
Return a TextTrack object representing CC track extracted by CCExtractor.
extract_c608
¶
Extract Apple-Style c608 box (CEA-608) subtitle using ccextractor.
This isn't much more than a wrapper to the track.ccextractor function. All this does, is actually check if a c608 box exists and only if so does it actually call ccextractor.
Even though there is a possibility of more than one c608 box, only one can actually be extracted. Not only that but it's very possible this needs to be done before any decryption as the decryption may destroy some of the metadata.
Need a test file with more than one c608 box to add support for
more than one CEA-608 extraction.
remove_eia_cc
¶
Remove EIA-CC data from Bitstream while keeping SEI data.
This works by removing all NAL Unit's with the Type of 6 from the bistream and then re-adding SEI data (effectively a new NAL Unit with just the SEI data). Only bitstreams with x264 encoding information is currently supported due to the obscurity on the MDAT mp4 box structure. Therefore, we need to use hacky regex.