package com.xenoage.zong.desktop.io.mp3.out; import static com.xenoage.utils.error.Err.handle; import static com.xenoage.utils.log.Report.warning; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import com.xenoage.utils.document.io.FileOutput; import com.xenoage.utils.io.OutputStream; import com.xenoage.utils.jse.io.JseFileUtils; import com.xenoage.utils.jse.io.JseOutputStream; import com.xenoage.utils.lang.Lang; import com.xenoage.zong.Voc; import com.xenoage.zong.Zong; import com.xenoage.zong.core.Score; import com.xenoage.zong.desktop.io.wav.out.WavScoreFileOutput; /** * This class writes an MP3 file from a given {@link Score}. * * The LAME tool must be installed and in the system path. * If lame can not be found, an error is reported. * * @author Andreas Wenger */ public class Mp3ScoreFileOutput extends FileOutput<Score> { private static boolean debugToConsole = false; @Override public void write(Score score, int fileIndex, OutputStream stream) throws IOException { writeMp3(score, stream); } /** * Writes the given score as a MP3 into the given stream. */ public static void writeMp3(Score score, OutputStream stream) throws IOException { //look if LAME is installed try { Runtime.getRuntime().exec("lame"); } catch (Exception ex) { handle(warning(Lang.get(Voc.CouldNotFindLAME, Zong.website + "/lame"))); } //save temporary WAVE file first File tempWAVFile = File.createTempFile(Mp3ScoreFileOutput.class.getName(), ".wav"); try (OutputStream tempStream = new JseOutputStream(tempWAVFile)) { WavScoreFileOutput.writeWav(score, tempStream); } //create temporary MP3 file File tempMP3File = File.createTempFile(Mp3ScoreFileOutput.class.getName(), ".mp3"); //convert to MP3 try { Process process = new ProcessBuilder("lame", tempWAVFile.getAbsolutePath(), tempMP3File.getAbsolutePath()).start(); if (debugToConsole) { //forward LAME error output to console try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } } process.waitFor(); int exitValue = process.exitValue(); if (exitValue != 0) throw new IOException("LAME process returned: " + exitValue); tempWAVFile.delete(); //copy MP3 file to output stream try (JseOutputStream mp3Stream = new JseOutputStream(stream)) { JseFileUtils.copyFileToStream(tempMP3File, mp3Stream); } tempMP3File.delete(); } catch (Exception ex) { tempWAVFile.delete(); tempMP3File.delete(); throw new IOException(ex); } } }