A fast, portable and lightweight library for engraving Music Encoding Initiative (MEI) music scores into SVG
npx @tessl/cli install tessl/pypi-verovio@5.6.0Verovio is a fast, portable and lightweight library for engraving Music Encoding Initiative (MEI) digital scores into SVG images. It provides on-the-fly converters to render multiple music notation formats including Plaine & Easie Code, Humdrum, Musedata, MusicXML, EsAC, and ABC.
The library is written in C++20 and provides Python bindings via SWIG, enabling professional-quality music notation rendering in Python applications.
pip install verovioimport verovio
# Create a toolkit instance
tk = verovio.toolkit()
# Access constants
mei_format = verovio.MEI
log_warning = verovio.LOG_WARNINGimport verovio
# Create toolkit instance with default font initialization
tk = verovio.toolkit()
# Load MEI file
tk.loadFile("score.mei")
# Get number of pages
page_count = tk.getPageCount()
print(f"Document has {page_count} pages")
# Render first page to SVG
svg_output = tk.renderToSVG(pageNo=1)
# Save SVG to file
with open("output.svg", "w") as f:
f.write(svg_output)
# Render to MIDI
midi_base64 = tk.renderToMIDI()
# Save MIDI to file
tk.renderToMIDIFile("output.mid")Verovio uses a toolkit-based architecture where each toolkit instance maintains:
The library supports multiple music notation fonts compliant with the Standard Music Font Layout (SMuFL) specification, allowing for customized visual output.
Load music notation files, configure rendering options, validate input data, and manage the toolkit's resource paths and settings.
class toolkit:
def __init__(self, initFont: bool = True) -> None: ...
def loadFile(self, filename: str) -> bool: ...
def loadData(self, data: str) -> bool: ...
def setOptions(self, json_options: dict) -> bool: ...
def getOptions(self) -> dict: ...
def setResourcePath(self, path: str) -> None: ...Render loaded music notation to various output formats including SVG, MIDI, Plaine & Easie Code, timemaps, and expansion maps.
class toolkit:
def renderToSVG(self, pageNo: int = 1, xmlDeclaration: bool = False) -> str: ...
def renderToSVGFile(self, filename: str, pageNo: int = 1) -> bool: ...
def renderToMIDI(self) -> str: ...
def renderToMIDIFile(self, filename: str) -> bool: ...
def renderToTimemap(self, options: dict | None = None) -> list: ...Query element attributes, timing information, MIDI values, and page locations within the loaded music notation document.
class toolkit:
def getPageCount(self) -> int: ...
def getElementAttr(self, xmlId: str) -> dict: ...
def getElementsAtTime(self, millisec: int) -> dict: ...
def getPageWithElement(self, xmlId: str) -> int: ...
def getTimesForElement(self, xmlId: str) -> dict: ...
def getMIDIValuesForElement(self, xmlId: str) -> dict: ...Convert between music notation formats including MEI, Humdrum, MIDI, and Plaine & Easie Code.
class toolkit:
def convertMEIToHumdrum(self, meiData: str) -> str: ...
def convertHumdrumToHumdrum(self, humdrumData: str) -> str: ...
def convertHumdrumToMIDI(self, humdrumData: str) -> str: ...
def getMEI(self, options: dict | None = None) -> str: ...
def renderToPAE(self) -> str: ...Advanced functionality including experimental editor features, layout redoing, locale management, runtime measurement, and Humdrum buffer operations.
class toolkit:
def edit(self, editor_action: dict) -> bool: ...
def editInfo(self) -> dict: ...
def redoLayout(self, options: dict | None = None) -> None: ...
def getDescriptiveFeatures(self, options: dict | None = None) -> dict: ...def setDefaultResourcePath(path: str) -> None:
"""
Set the default resource path for all toolkit instances.
Args:
path: Path to the resource directory containing fonts and data
"""
def enableLog(level: int) -> None:
"""
Enable logging at the specified level.
Args:
level: Log level (LOG_OFF, LOG_ERROR, LOG_WARNING, LOG_INFO, LOG_DEBUG)
"""UNKNOWN: int # Unknown file format
AUTO: int # Auto-detect file format
MEI: int # Music Encoding Initiative format
HUMDRUM: int # Humdrum format
HUMMEI: int # Humdrum to MEI conversion
HUMMIDI: int # Humdrum to MIDI conversion
PAE: int # Plaine & Easie Code format
ABC: int # ABC notation format
CMME: int # CMME format
DARMS: int # DARMS format
VOLPIANO: int # Volpiano format
MUSICXML: int # MusicXML format
MUSICXMLHUM: int # MusicXML via Humdrum
MEIHUM: int # MEI via Humdrum
MUSEDATAHUM: int # Musedata via Humdrum
ESAC: int # EsAC format
MIDI: int # MIDI format
TIMEMAP: int # Timemap format
EXPANSIONMAP: int # Expansion map format
SERIALIZATION: int # Serialization formatLOG_OFF: int # Logging disabled
LOG_ERROR: int # Error level logging
LOG_WARNING: int # Warning level logging
LOG_INFO: int # Info level logging
LOG_DEBUG: int # Debug level loggingimport verovio
tk = verovio.toolkit()
# Configure page dimensions and appearance
options = {
'pageHeight': 2970,
'pageWidth': 2100,
'scale': 40,
'adjustPageHeight': True,
'breaks': 'auto',
'spacingStaff': 4
}
tk.setOptions(options)
tk.loadFile("score.mei")
svg = tk.renderToSVG()import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
# Render to MIDI first (required for timing queries)
tk.renderToMIDI()
# Get timing information for a specific element
element_id = "note-123"
times = tk.getTimesForElement(element_id)
print(f"Score time onset: {times['scoreTimeOnset']}")
print(f"Real time onset: {times['realTimeOnsetMilliseconds']} ms")import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
# Render to SVG
svg = tk.renderToSVG()
with open("score.svg", "w") as f:
f.write(svg)
# Render to MIDI
tk.renderToMIDIFile("score.mid")
# Export to Plaine & Easie Code
pae = tk.renderToPAE()
with open("score.pae", "w") as f:
f.write(pae)
# Generate timemap for playback synchronization
timemap = tk.renderToTimemap()