Skip to content

Instantly share code, notes, and snippets.

@jaynetics
Created December 20, 2025 22:41
Show Gist options
  • Select an option

  • Save jaynetics/efece74fb66f2d2d84af65836617bf01 to your computer and use it in GitHub Desktop.

Select an option

Save jaynetics/efece74fb66f2d2d84af65836617bf01 to your computer and use it in GitHub Desktop.
copy recordbox message (DeliveryComment) from rekordbox db to mp3 id3 tag on the track file
#!/usr/bin/env python3
"""
Sync Rekordbox 'Message' field to ID3 comments.
Reads all tracks from the Rekordbox 6 database that have a DeliveryComment
(displayed as 'Message' in Rekordbox UI) and writes the value to the
standard ID3 COMM frame.
"""
import sys
from pathlib import Path
from mutagen.id3 import ID3, COMM, ID3NoHeaderError
from mutagen.mp3 import MP3
from pyrekordbox import Rekordbox6Database
def sync_messages(dry_run: bool = False):
"""Sync Rekordbox Message fields to ID3 comments."""
print("Opening Rekordbox database...")
db = Rekordbox6Database()
tracks = db.get_content()
updated = 0
skipped = 0
errors = 0
for track in tracks:
message = track.DeliveryComment
if not message:
continue
file_path = Path(track.FolderPath)
if not file_path.exists():
print(f" [SKIP] File not found: {file_path}")
skipped += 1
continue
if file_path.suffix.lower() != ".mp3":
print(f" [SKIP] Not an MP3: {file_path}")
skipped += 1
continue
try:
# Load or create ID3 tags
try:
tags = ID3(file_path)
except ID3NoHeaderError:
tags = ID3()
# Check existing comment
existing_comment = None
for key in tags.keys():
if key.startswith("COMM"):
existing_comment = str(tags[key])
break
if existing_comment == message:
print(f" [OK] Already set: {track.Title} - {track.ArtistName}")
continue
if dry_run:
print(f" [DRY-RUN] Would update: {track.Title} - {track.ArtistName}")
print(f" Message: {message}")
if existing_comment:
print(f" (Existing comment: {existing_comment})")
updated += 1
continue
# Add/update COMM frame
tags.delall("COMM")
tags.add(COMM(
encoding=3, # UTF-8
lang="eng",
desc="",
text=message
))
tags.save(file_path)
print(f" [UPDATED] {track.Title} - {track.ArtistName}: {message}")
updated += 1
except Exception as e:
print(f" [ERROR] {file_path}: {e}")
errors += 1
db.close()
print()
print(f"Summary: {updated} updated, {skipped} skipped, {errors} errors")
if __name__ == "__main__":
dry_run = "--dry-run" in sys.argv or "-n" in sys.argv
if dry_run:
print("=== DRY RUN MODE (no changes will be made) ===")
print()
sync_messages(dry_run=dry_run)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment