#!/usr/bin/env python3 """ Exporte tous les cue points de Mixxx vers des fichiers .mixxx (JSON) placés à côté de chaque fichier audio. Usage : python3 mixxx_export.py [chemin_db] """ import sqlite3 import json import sys import os from pathlib import Path DEFAULT_DB = Path.home() / ".mixxx" / "mixxxdb.sqlite" def export_cues(db_path: Path, output_dir: Path = None): con = sqlite3.connect(db_path) con.row_factory = sqlite3.Row rows = con.execute(""" SELECT tl.location AS audio_path, tl.filename AS filename, c.type AS type, c.position AS position, c.length AS length, c.hotcue AS hotcue, c.label AS label, c.color AS color FROM cues c JOIN library l ON l.id = c.track_id JOIN track_locations tl ON tl.id = l.location WHERE tl.fs_deleted = 0 ORDER BY tl.location, c.hotcue, c.type """).fetchall() by_file = {} for r in rows: path = r["audio_path"] by_file.setdefault(path, []).append({ "type": r["type"], "position": r["position"], "length": r["length"], "hotcue": r["hotcue"], "label": r["label"] or "", "color": r["color"], }) con.close() exported = 0 for audio_path, cues in by_file.items(): audio_file = Path(audio_path) if not audio_file.exists(): print(f"[SKIP] fichier introuvable : {audio_path}") continue # Déterminer où écrire le .mixxx if output_dir: out = output_dir / (audio_file.stem + audio_file.suffix + ".mixxx") else: out = audio_file.with_suffix(audio_file.suffix + ".mixxx") payload = { "version": 1, "filename": audio_file.name, "cues": cues, } try: out.parent.mkdir(parents=True, exist_ok=True) out.write_text(json.dumps(payload, indent=2, ensure_ascii=False)) print(f"[OK] {out.name}") exported += 1 except Exception as e: print(f"[ERR] {out.name} : {e}") print(f"\n{exported} fichier(s) .mixxx exporté(s).") if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("db_path", nargs="?", default=str(DEFAULT_DB), help="Chemin vers mixxxdb.sqlite") parser.add_argument("--output-dir", help="Dossier de sortie pour les .mixxx (par défaut : à côté de l'audio)") args = parser.parse_args() db_path = Path(args.db_path) if not db_path.exists(): print(f"DB introuvable : {db_path}") sys.exit(1) out_dir = Path(args.output_dir) if args.output_dir else None export_cues(db_path, out_dir)