
The problem
I have a mixed MP3 liveset of a DJ and I need to burn it on a CD. Yes, the question will pop up: "OMG! CD?! Do they still exist?". Sure, everybody is using iPod, MP3 player, etc, etc, ... now, but I really need to burn it to disc.
I have a tracklist which tells me how long the individual tracks last. So based on this information, I could build a CUE file. This CUE file can be delivered to "whatever" burning software. It will burn the MP3 file to disc, but it will make indexes when a new individual track starts. More information about CUE files: http://en.wikipedia.org/wiki/Cue_sheet_(computing)"
Seems great, and I'm lucky, because there are a lot of CUE generators on the web:
But, the problem with each of these generators, is the timing input. You have to manually add the time of track 1 on track 2, track 2 on track 3, etc, etc, ...
Example:
Track 01 takes 06:42
Track 02 takes 04:12
I just want to provide the above numbers into the generator, but according to the CUE definition, I have to input:
TRACK 01 AUDIO
TITLE "Reverence"
PERFORMER "Faithless"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "She's My Baby"
PERFORMER "Faithless"
INDEX 01 06:42:00
TRACK 03 AUDIO
TITLE "Take the Long Way Home"
PERFORMER "Faithless"
INDEX 01 10:54:00
Of course, you can do this quickly yourself or by Excel, but I'm a software engineer, so I developed my own application ;-)!
The solution
- Create a CSV file, having the following format:
##GENRE##
##DATE##
##PERFORMER##
##TITLE##
##FILE##
##TRACK_01_ARTIST##;##TRACK01_TITLE##;##TRACK_01_MINUTES##;##TRACK_01_SECONDS##
##TRACK_02_ARTIST##;##TRACK02_TITLE##;##TRACK_02_MINUTES##;##TRACK_02_SECONDS##
...
- Download the following pom.xml and source file src/main/java/be/jochusonline/cuegenerator:
<project> <modelVersion>4.0.0</modelVersion> <groupId>be.jochusonline</groupId> <artifactId>cuegenerator</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>net.sf.opencsv</groupId> <artifactId>opencsv</artifactId> <version>2.3</version> </dependency> </dependencies> </project>
package be.jochusonline.cuegenerator; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.text.DecimalFormat; import au.com.bytecode.opencsv.CSVReader; public class CueGenerator { private static final String FILE = "/Users/jochen/Documents/Tmp/armin01.csv"; public static void main(String[] args) { File csvFile = new File(FILE); CSVReader reader = null; if (!csvFile.exists()) { System.err.println("File '" + FILE + "' does not exist."); } else { try { /** INIT **/ int i = 1; int minutes = 0; int seconds = 0; DecimalFormat formatter = new DecimalFormat("00"); reader = new CSVReader(new FileReader(FILE), ';'); String[] nextLine; /** START OUTPUT **/ // Genre nextLine = reader.readNext(); System.out.println("REM GENRE \"" + nextLine[0] + "\""); // Date nextLine = reader.readNext(); System.out.println("REM DATE \"" + nextLine[0] + "\""); // Performer nextLine = reader.readNext(); System.out.println("PERFORMER \"" + nextLine[0] + "\""); // Title nextLine = reader.readNext(); System.out.println("TITLE \"" + nextLine[0] + "\""); // File nextLine = reader.readNext(); System.out.println("FILE \"" + nextLine[0] + "\" MP3"); // Tracks while ((nextLine = reader.readNext()) != null) { // Track System.out.println(" TRACK " + formatter.format(i) + " AUDIO"); System.out.println(" TITLE " + "\"" + nextLine[1] + "\""); System.out.println(" PERFORMER " + "\"" + nextLine[0] + "\""); System.out.println(" INDEX 01 " + formatter.format(minutes) + ":" + formatter.format(seconds) + ":00"); // Calculate time minutes += Integer.parseInt(nextLine[2]); seconds += Integer.parseInt(nextLine[3]); while (seconds >= 60) { seconds -= 60; minutes++; } // Next track i++; } System.out.println("\nControl check: total time of MP3 should be: " + minutes + ":" + seconds); } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
- Run mvn eclipse:eclipse on a command prompt. You need Maven to perform this operation. You can download it from: http://maven.apache.org/. This operation will generate a .project file. Import that project into Eclipse.
- Once imported in Eclipse, use the built-in run dialog. Eclipse will output the file to the console
- At the bottom of the file, there's an extra check to be sure you didn't provide any incorrect data
Comments
Nice job, but somehow I have the feeling something like this could exist already.
I think I once generated a .cue file directly from my Media Player software using the current playlist, way back in the day, but I cannot remember exactly at the moment. (Starting from seperate tracks, which is not the case here, so never mind.)
Anyhow, nice programming exercise. You forgot to mention people still need Maven to build the .cue file (not everyone is a developer, right? :p).
Couldn't you, however, just read the ID3 tag info of the .mp3 files, so you would be able to skip the exhausting process of creating the .csv file and manually entering all data...?
I don't see the benefit of having to enter all 'timings' in a .csv file, if you could also enter them in one of the online .cue generator tools. The added value is that your program calculates the sum of the tracktimes to compute the total audio length. A bit bizarre none of those .cue generator sites supports it. Maybe there are others out there :)
Yes, I understand your comment :-). It could be there's something out there, but I didn't spend much time searching as my application was written in 5 minutes :-D.
Some remarks:
* CUE file generation of Media Player: don't know, cannot find it in the help files
* Maven is indeed required, I'll update my blogpost. Thanks!
* I cannot read the individual times as I only have 1 long MP3
* You have to consider putting time in c/p minutes/seconds in a CSV file, and searching/trying/loosing time on other online application. I tried some of them, and Nero Burning Rom didn't want to take their output. I guess I shouldn't be using Nero, but I'm not going to instal 31356 burning software packages :-)
At first I misunderstood the concept of this blogpost, but indeed, when you only have 1 large audio-file and a text-based tracklist, then your way is a good way to go I guess :)
Thank you Jochus! You just saved me some precious time. I was going to code something similar.
Like you I could find no tool which does the sum of the tracks' length. With a few tweaks your simple solution fitted my needs nicely.
Tip: if you have the original mp3 files which were merged/mixed into a single one a quick way to get the data for the csv file is using mp3info (under GUN/Linux) like this:
mp3info -p "%a;%t;%m;%s\n" *.mp3 > tracklist.csv
Thanks dll, your last command is really useful to me! :-)
Add new comment