Skip to content

Commit

Permalink
support of flac with information from cue. issue #47
Browse files Browse the repository at this point in the history
  • Loading branch information
yermak committed Mar 30, 2020
1 parent 7f2bf70 commit d3bbf6c
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/main/java/uk/yermak/audiobookconverter/Conversion.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void start(Convertable convertable, String outputDestination, Refreshable

Map<String, ProgressCallback> progressCallbacks = new HashMap<>();

convertable.getMedia().stream().map(MediaInfo::getFileName).forEach(s -> progressCallbacks.put(s, new ProgressCallback(s, refreshable)));
convertable.getMedia().stream().map(m -> (m.getFileName() + "-" + m.getDuration())).forEach(key -> progressCallbacks.put(key, new ProgressCallback(key, refreshable)));


progressCallbacks.put("output", new ProgressCallback("output", refreshable));
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/uk/yermak/audiobookconverter/FFMediaLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public MediaInfo call() throws Exception {
if (FilenameUtils.getExtension(filename).equalsIgnoreCase("FLAC")) {
File file = new File(FilenameUtils.getFullPath(filename) + FilenameUtils.getBaseName(filename) + ".cue");
if (file.exists()) {
String cue = FileUtils.readFileToString(file, "UTF-8");
String cue = FileUtils.readFileToString(file);
parseCueChapters(mediaInfo, cue);
}
}
Expand Down Expand Up @@ -144,13 +144,14 @@ static void parseCueChapters(MediaInfoBean mediaInfo, String cue) {
if ((i = line.indexOf("TRACK")) != -1) {
bookInfo.getTracks().add(new Track(cleanText(line.substring(i + 5))));
} else {
if ((i = line.indexOf("INDEX 00")) != -1 && bookInfo.getTracks().size() > 1) {
Track track = bookInfo.getTracks().get(bookInfo.getTracks().size() - 2);
track.setEnd(parseCueTime(line.substring(i + 8)));
}
if ((i = line.indexOf("INDEX 01")) != -1) {
long time = parseCueTime(line.substring(i + 8));
if (bookInfo.getTracks().size() > 1) {
Track track = bookInfo.getTracks().get(bookInfo.getTracks().size() - 2);
track.setEnd(time);
}
Track track = bookInfo.getTracks().get(bookInfo.getTracks().size() - 1);
track.setStart(parseCueTime(line.substring(i + 8)));
track.setStart(time);
}
}
}
Expand All @@ -162,7 +163,7 @@ static void parseCueChapters(MediaInfoBean mediaInfo, String cue) {
private static long parseCueTime(String substring) {
String cleanText = cleanText(substring);
String[] split = cleanText.split(":");
long time = 1000 * (Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1])) + Integer.parseInt(split[2]) * 10;
long time = 1000 * (Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1])) + Integer.parseInt(split[2])*1000 / 75;
return time;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public String call() throws Exception {
if (mediaInfo.getCodec().equals("aac")) {
logger.debug("Transcoding aac stream for {}", outputFileName);
ffmpegProcessBuilder = new ProcessBuilder(FFMPEG,
"-ss", toFFMpegTime(mediaInfo.getOffset()),
"-t", toFFMpegTime(mediaInfo.getDuration()),
"-i", mediaInfo.getFileName(),
"-vn",
"-codec:a", "copy",
Expand All @@ -63,6 +65,8 @@ public String call() throws Exception {
} else {
logger.debug("Re-encoding to aac for {}", outputFileName);
ffmpegProcessBuilder = new ProcessBuilder(FFMPEG,
"-ss", toFFMpegTime(mediaInfo.getOffset()),
"-t", toFFMpegTime(mediaInfo.getDuration()),
"-i", mediaInfo.getFileName(),
"-vn",
"-codec:a", "aac",
Expand Down Expand Up @@ -99,4 +103,8 @@ public String call() throws Exception {
}
}

static String toFFMpegTime(long time) {
return (time / 1000) + "." + time % 1000;
}

}
2 changes: 2 additions & 0 deletions src/main/java/uk/yermak/audiobookconverter/MediaInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public interface MediaInfo extends Organisable {
void setCodec(final String codec);

void setChapter(Chapter chapter);

long getOffset();
}


5 changes: 5 additions & 0 deletions src/main/java/uk/yermak/audiobookconverter/MediaInfoBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ public void setChapter(Chapter chapter) {
this.chapter = chapter;
}

@Override
public long getOffset() {
return 0;
}

public MediaInfoBean(final String fileName) {
this.fileName = fileName;
this.channels = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ public void setChapter(Chapter chapter) {
this.getMediaInfo().setChapter(chapter);
}

@Override
public long getOffset() {
return this.getMediaInfo().getOffset();
}

MediaInfoProxy(final String filename, final Future<MediaInfo> futureLoad) {
this.filename = filename;
this.futureLoad = futureLoad;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,9 @@ public void setCodec(String codec) {
public void setChapter(Chapter chapter) {
this.chapter = chapter;
}

@Override
public long getOffset() {
return track.getStart();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void run() {
List<MediaInfo> prioritizedMedia = prioritiseMedia();
for (MediaInfo mediaInfo : prioritizedMedia) {
String tempOutput = getTempFileName(jobId, mediaInfo.hashCode(), ".m4b");
ProgressCallback callback = progressCallbacks.get(mediaInfo.getFileName());
ProgressCallback callback = progressCallbacks.get(mediaInfo.getFileName() + "-" + mediaInfo.getDuration());
Future<String> converterFuture = executorService.submit(new FFMpegNativeConverter(conversion, mediaInfo, tempOutput, callback));
futures.add(converterFuture);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void testParseCueChapters() throws IOException {
AudioBookInfo bookInfo = new AudioBookInfo();
MediaInfoBean mediaInfo = new MediaInfoBean("test");
mediaInfo.setBookInfo(bookInfo);
mediaInfo.setDuration(2205071);
mediaInfo.setDuration(2305071);
FFMediaLoader.parseCueChapters(mediaInfo, cue);
assertEquals(bookInfo.getGenre(), "Classical");
assertEquals(bookInfo.getTitle(), "Брамс");
Expand All @@ -58,21 +58,21 @@ public void testParseCueChapters() throws IOException {
assertEquals(tracks.size(), 3);

Track track1 = tracks.get(0);
assertEquals(track1.getStart(), 320);
assertEquals(track1.getEnd(), 1313670);
assertEquals(track1.getStart(), 426);
assertEquals(track1.getEnd(), 1321093);
assertEquals(track1.getTrackNo(),"01 AUDIO");
assertEquals(track1.getTitle(), "Фортепианный концерт ре минор соч. 15 - Maestoso");
assertEquals(track1.getWriter(), "DeAgostini Classica 1");

Track track2 = tracks.get(1);
assertEquals(track2.getStart(), 1321070);
assertEquals(track2.getEnd(), 2198150);
assertEquals(track2.getStart(), 1321093);
assertEquals(track2.getEnd(), 2205093);
assertEquals(track2.getTitle(), "Фортепианный концерт ре минор соч. 15 - Adagio");
assertEquals(track2.getWriter(), "DeAgostini Classica 2");

Track track3 = tracks.get(2);
assertEquals(track3.getStart(), 2205070);
assertEquals(track3.getEnd(), 2205071);
assertEquals(track3.getStart(), 2205093);
assertEquals(track3.getEnd(), 2305071);
assertEquals(track3.getTitle(), "Фортепианный концерт ре минор соч. 15 - Rondo. Allegro ma non troppo");
assertEquals(track3.getWriter(), "DeAgostini Classica 3");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.yermak.audiobookconverter;

import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;

public class FFMpegNativeConverterTest {

@Test
public void testToFFMpegTime() {
assertEquals(FFMpegNativeConverter.toFFMpegTime(5432), "5.432");
assertEquals(FFMpegNativeConverter.toFFMpegTime(123), "0.123");
}
}

0 comments on commit d3bbf6c

Please sign in to comment.