Füge Unterstützung für die Erstellung von Tracklisten hinzu und verbessere Duplikat-Filterung in Audacity-Labels
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| *.cue | ||||
| *.txt | ||||
							
								
								
									
										41
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,15 +1,21 @@ | ||||
| # CUE to Audacity Label Converter | ||||
|  | ||||
| Ein Python-Script, das CUE-Dateien (von rekordbox DJ oder anderen Quellen) in Audacity-Label-Dateien umwandelt. | ||||
| Ein Python-Script, das CUE-Dateien (von rekordbox DJ oder anderen Quellen) in Audacity-Label-Dateien und schöne Tracklists umwandelt. | ||||
|  | ||||
| ## Beschreibung | ||||
|  | ||||
| Dieses Tool liest CUE-Dateien und erstellt daraus Textdateien mit Zeitstempeln und Track-Titeln, die direkt in Audacity als Label-Track importiert werden können. Besonders nützlich für DJ-Sets oder lange Audio-Aufnahmen, die in einzelne Tracks unterteilt werden sollen. | ||||
| Dieses Tool liest CUE-Dateien und erstellt daraus zwei Ausgabe-Dateien: | ||||
| 1. **Audacity-Labels**: Textdateien mit Zeitstempeln für den Import in Audacity | ||||
| 2. **Tracklist**: Professionell formatierte Trackliste zum Teilen | ||||
|  | ||||
| Besonders nützlich für DJ-Sets oder lange Audio-Aufnahmen, die in einzelne Tracks unterteilt werden sollen. | ||||
|  | ||||
| ## Features | ||||
|  | ||||
| - Unterstützt rekordbox CUE-Dateien im HH:MM:SS Format | ||||
| - Automatische Erkennung von Standard CUE-Formaten (MM:SS:FF mit CD-Frames) | ||||
| - **Intelligente Duplikat-Filterung**: Entfernt Tracks, die innerhalb der letzten 2 Tracks bereits vorkamen | ||||
| - **Zwei Ausgabe-Formate**: Audacity-Labels und professionelle Tracklist | ||||
| - Flexible Regex-Pattern für verschiedene Einrückungen (Tabs/Leerzeichen) | ||||
| - UTF-8 Encoding für internationale Zeichen | ||||
| - Plattformübergreifend (Windows, macOS, Linux) | ||||
| @@ -57,6 +63,12 @@ TRACK 01 AUDIO | ||||
| 150.000000    150.000000    Song Title | ||||
| ``` | ||||
|  | ||||
| ### Ausgabe (Tracklist-Datei) | ||||
| ``` | ||||
| 01. Artist Name - Song Title (02:30) | ||||
| 02. Another Artist - Another Song (05:15) | ||||
| ``` | ||||
|  | ||||
| ## Unterstützte CUE-Formate | ||||
|  | ||||
| 1. **rekordbox Format**: `HH:MM:SS` (Stunden:Minuten:Sekunden) | ||||
| @@ -68,21 +80,32 @@ Das Script erkennt automatisch das Format basierend auf den Zeitwerten. | ||||
|  | ||||
| 1. Öffnen Sie Ihre Audio-Datei in Audacity | ||||
| 2. Gehen Sie zu `Datei` → `Importieren` → `Labels...` | ||||
| 3. Wählen Sie die generierte `.txt` Datei aus | ||||
| 3. Wählen Sie die generierte `*_audacity.txt` Datei aus | ||||
| 4. Die Zeitmarken erscheinen als Label-Track | ||||
|  | ||||
| ## Dateien | ||||
| ## Ausgabedateien | ||||
|  | ||||
| - `cue2auda.py` - Hauptscript | ||||
| - `requirements.txt` - Python-Abhängigkeiten (leer, da nur Standard-Bibliotheken verwendet werden) | ||||
| - `README.md` - Diese Datei | ||||
| Das Script erstellt automatisch zwei Dateien: | ||||
|  | ||||
| - `filename_audacity.txt` - Audacity-Label-Datei für den Import | ||||
| - `filename_tracklist.txt` - Professionelle Tracklist zum Teilen | ||||
|  | ||||
| ## Beispiel-Workflow | ||||
|  | ||||
| 1. Exportieren Sie ein DJ-Set aus rekordbox mit CUE-Datei | ||||
| 2. Führen Sie das Script aus: `python cue2auda.py /pfad/zu/cue/dateien` | ||||
| 3. Importieren Sie die generierte `.txt` Datei in Audacity | ||||
| 4. Nutzen Sie die Labels zum Schneiden oder Navigieren | ||||
| 3. **Zwei Dateien werden erstellt:** | ||||
|    - `filename_audacity.txt` → Importieren Sie diese in Audacity als Labels | ||||
|    - `filename_tracklist.txt` → Teilen Sie diese schöne Tracklist | ||||
| 4. Nutzen Sie die Labels zum Schneiden oder Navigieren in Audacity | ||||
|  | ||||
| ## Duplikat-Filterung | ||||
|  | ||||
| Das Script erkennt automatisch Duplikate in DJ-Mixes und filtert Tracks heraus, die innerhalb der letzten 2 Tracks bereits vorkamen. Dies ist besonders nützlich bei: | ||||
|  | ||||
| - **Blend-Übergängen**: Wenn Tracks überlappend gespielt werden | ||||
| - **Loop-Rolls**: Wenn derselbe Track kurz wiederholt wird | ||||
| - **DJ-Techniken**: Drop-outs, Cuts und Re-Entries | ||||
|  | ||||
| ## Technische Details | ||||
|  | ||||
|   | ||||
							
								
								
									
										48
									
								
								cue2auda.py
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								cue2auda.py
									
									
									
									
									
								
							| @@ -23,13 +23,19 @@ for cueFileName in glob.glob(os.path.join(thePath, "*.cue")): | ||||
|     #print(cueFileContent) | ||||
|  | ||||
|     # Create label file | ||||
|     labelFileName = os.path.splitext(cueFileName)[0] + ".txt" | ||||
|     with open(labelFileName, "w", encoding="utf-8") as labelFile: | ||||
|     labelFileName = os.path.splitext(cueFileName)[0] + "_audacity.txt" | ||||
|     tracklistFileName = os.path.splitext(cueFileName)[0] + "_tracklist.txt" | ||||
|      | ||||
|     with open(labelFileName, "w", encoding="utf-8") as labelFile, \ | ||||
|          open(tracklistFileName, "w", encoding="utf-8") as tracklistFile: | ||||
|         #print ("###" + labelFileName + "###") | ||||
|  | ||||
|         # Process file | ||||
|         theTitle = "" # initialize title now in order to keep it available when scanning subsequent INDEX line | ||||
|         thePerformer = "" # initialize performer | ||||
|         trackCount = 0 | ||||
|         lastTitles = []  # Track the last few titles to avoid duplicates within a few tracks | ||||
|         maxTrackDistance = 2  # Filter duplicates within this many tracks | ||||
|          | ||||
|         for lineNum, line in enumerate(cueFileContent, 1): | ||||
|             originalLine = line | ||||
| @@ -40,6 +46,11 @@ for cueFileName in glob.glob(os.path.join(thePath, "*.cue")): | ||||
|             if theMatchTitle is not None: | ||||
|                 theTitle = theMatchTitle.group(1) | ||||
|  | ||||
|             # Match PERFORMER - try multiple patterns for different indentation (tabs or spaces) | ||||
|             theMatchPerformer = re.search(r'PERFORMER\s+"([^"]+)"', line)  | ||||
|             if theMatchPerformer is not None: | ||||
|                 thePerformer = theMatchPerformer.group(1) | ||||
|  | ||||
|             # Match INDEX 01 - try multiple patterns for different formats (tabs or spaces) | ||||
|             theMatchIndex = re.search(r'INDEX\s+01\s+(\d{1,2}):(\d{2}):(\d{2})', line)  | ||||
|             if theMatchIndex is not None: | ||||
| @@ -47,18 +58,39 @@ for cueFileName in glob.glob(os.path.join(thePath, "*.cue")): | ||||
|                 theMinutes = int(theMatchIndex.group(2))    # Minutes | ||||
|                 theSeconds = int(theMatchIndex.group(3))    # Seconds | ||||
|                  | ||||
|                 trackCount += 1 | ||||
|                  | ||||
|                 # Convert HH:MM:SS to total seconds | ||||
|                 theStartTime = (theHours * 3600) + (theMinutes * 60) + theSeconds | ||||
|                  | ||||
|                 # format theStartTime | ||||
|                 theStartTime = "{:.6f}".format(theStartTime) | ||||
|                 # Check for duplicates: skip if same title appears within the last few tracks | ||||
|                 isDuplicate = theTitle in lastTitles[-maxTrackDistance:] | ||||
|                  | ||||
|                 # Write time and title to label file | ||||
|                 labelFile.write(theStartTime + "\t" + theStartTime + "\t" + theTitle + "\n") | ||||
|                 if not isDuplicate: | ||||
|                     trackCount += 1 | ||||
|                      | ||||
|                     # format theStartTime | ||||
|                     theStartTimeFormatted = "{:.6f}".format(theStartTime) | ||||
|                      | ||||
|                     # Format time for tracklist (MM:SS) | ||||
|                     timeMinutes = theStartTime // 60 | ||||
|                     timeSeconds = theStartTime % 60 | ||||
|                     timeFormatted = f"{int(timeMinutes):02d}:{int(timeSeconds):02d}" | ||||
|                      | ||||
|                     # Write time and title to Audacity label file | ||||
|                     labelFile.write(theStartTimeFormatted + "\t" + theStartTimeFormatted + "\t" + theTitle + "\n") | ||||
|                      | ||||
|                     # Write to tracklist file: TrackNr. Artist - Track (Time) | ||||
|                     if thePerformer: | ||||
|                         tracklistFile.write(f"{trackCount:02d}. {thePerformer} - {theTitle} ({timeFormatted})\n") | ||||
|                     else: | ||||
|                         tracklistFile.write(f"{trackCount:02d}. {theTitle} ({timeFormatted})\n") | ||||
|                      | ||||
|                     # Add to title history | ||||
|                     lastTitles.append(theTitle) | ||||
|                 else: | ||||
|                     print(f"Skipping duplicate: '{theTitle}' at {theHours:02d}:{theMinutes:02d}:{theSeconds:02d} (appeared within last {maxTrackDistance} tracks)") | ||||
|          | ||||
|         print(f"Created {trackCount} labels in {labelFileName}") | ||||
|         print(f"Created tracklist in {tracklistFileName}") | ||||
|  | ||||
|         # end for line in cueFileContent | ||||
|      | ||||
|   | ||||
		Reference in New Issue
	
	Block a user