Expand description

This library provides access to metadata and libraries written by the Serato DJ software.


Serato’s formats are pretty complex and store redundant data which might lead to situation where that data contradicts each other (e.g. if the data was edited by hand).


To make it straightforward to access the metadata, this library provides the TagContainer struct, which provides access to all important attributes and implements the same conflict resolution strategies that the Serato DJ software uses.

use triseratops::tag::{TagContainer, TagFormat};

fn parse_and_print_cues(markers_data: &[u8], markers2_data: &[u8]) {
    let mut tags = TagContainer::new();
    tags.parse_markers(markers_data, TagFormat::ID3).expect("Failed to parse Markers data!");
    tags.parse_markers2(markers2_data, TagFormat::ID3).expect("Failed to parse Markers2 data!");

    for cue in tags.cues() {
        println!("{:?}", cue);

If you’d rather parse the tag data representation yourself, you can do that by using the individual tag structs directly:

use triseratops::tag::{Markers, format::id3::ID3Tag};

fn parse_and_print_markers(data: &[u8]) {
    let markers = Markers::parse_id3(data).expect("Failed to parse data!");
    println!("{:?}", markers);

Note: This library does not provide means to read the metadata from music files directly, so you need to use other libraries (e.g. id3 to do that. You can check the examples/ directory for some toy examples.


This library aims to provide support for lossless data roundtripping, i.e. parsing and then serializing data results in the exact same bytes as the original input (except for FLAC/MP4 data, see last bullet point in the Caveats section below).

use std::io::Write;
use triseratops::tag::{Markers, format::id3::ID3Tag};

fn write(mut writer: impl Write, markers: &Markers) {
    let bytes_written = markers.write_id3(&mut writer).expect("Failed to serialize data!");
    println!("Wrote {} bytes", bytes_written);

Supported File Types

Support for the following tags has already been implemented:

TagID3FLACMP4/M4AOgg VorbisXML (e.g. AAC)Description
AnalysisYesYesYesYesNoSerato Analysis version
AutotagsYesYesYesNoNoBPM and Gain values
BeatGridYesYesYesNoNoBeatgrid Markers
Markers_Yesn/aYesNoNoHotcues, Saved Loops, etc.
Markers2YesYesYesYesNoHotcues, Saved Loops, etc.
OverviewYesYesYesNoNoOverview Waveform data
RelVoln/aPartialPartialn/aNoRelative Volume Adjument data (?)
VideoAssocn/aPartialPartialn/aNoVideo Association data (?)


  • Most Ogg tags are currently not supported. Their format is completely different from the other tag types and need to be reverse-engineered first.
  • The Serato Offsets_ tag haven’t been reverse engineed yet, and no support has been implemented.
  • The Serato RelVolAd and the Serato VidAssoc tags haven’t been reverse engineed yet, but preliminary support has been added. For now, they just return a tag version and a byte vector.
  • AAC files (among others) do not store metadata in tags, and use XML files in the _Serato_/Metadata directory instead. No support has been added yet.
  • The cue colors stored in the metadata are not the same as displayed in Serato DJ Pro. Instead, they uses the color palette from Serato DJ Into. Serato then maps them to a new color palette. Support for converting between the two is currently missing.
  • The track colors stores in the metadata are those from the color picker, not those shown in the library table. Support for converting between the two is currently missing.
  • Unfortunately, full lossless roundtrips aren’t possible for FLAC and MP4, because the data is wrapped in base64-encoding where the decoded last byte seems to be random junk that change when writing tags from Serato DJ even if no actual changes were made (possibly an out-of-bounds read or uninitialized data in Serato DJ). For parsing and using this in Serato that doesn’t make a difference, but the roundtrip tests will ignore those last two bytes.


Parsing the Serato library (e.g. the database V2 file in the _Serato_ directory) is also possible, but since this feature is still under development, the API is not stable yet and might change in the future.


Error types and helper functions.

Parsers for the Serato library database and crates

Parsers for Serato’s file tags