Created
December 20, 2025 22:41
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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