93 lines
2.8 KiB
Python
Executable File
93 lines
2.8 KiB
Python
Executable File
#!/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) |