Skip to content

Commit

Permalink
[common][fmp4] Added progress listener to Mp4Demuxer
Browse files Browse the repository at this point in the history
  • Loading branch information
aldenml committed Mar 26, 2016
1 parent bb440c1 commit a6d73c0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 21 deletions.
10 changes: 7 additions & 3 deletions common/src/main/java/com/frostwire/fmp4/IsoMedia.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ public static void read(InputChannel ch, OnBoxListener l) throws IOException {
}
}

public static LinkedList<Box> head(RandomAccessFile in) throws IOException {
public static LinkedList<Box> head(RandomAccessFile in, ByteBuffer buf) throws IOException {
in.seek(0);

final InputChannel ch = new InputChannel(in.getChannel());
final LinkedList<Box> boxes = new LinkedList<>();

read(ch, new OnBoxListener() {
read(ch, -1, null, new OnBoxListener() {
@Override
public boolean onBox(Box b) {
if (b.parent == null) {
Expand All @@ -125,13 +125,17 @@ public boolean onBox(Box b) {

return b.type != Box.mdat;
}
});
}, buf);

in.seek(0);

return boxes;
}

public static LinkedList<Box> head(RandomAccessFile in) throws IOException {
return head(in, ByteBuffer.allocate(10 * 1024));
}

public static boolean write(OutputChannel ch, LinkedList<Box> boxes, OnBoxListener l, ByteBuffer buf) throws IOException {
buf.clear();

Expand Down
57 changes: 41 additions & 16 deletions common/src/main/java/com/frostwire/fmp4/Mp4Demuxer.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,46 +30,55 @@
*/
public final class Mp4Demuxer {

public static void track(int id, Mp4Tags tags, RandomAccessFile in, RandomAccessFile out) throws IOException {
LinkedList<Box> head = IsoMedia.head(in);
public static void track(int id, Mp4Tags tags, RandomAccessFile in, RandomAccessFile out, DemuxerListener l) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(100 * 1024);
LinkedList<Box> head = IsoMedia.head(in, buf);
boolean fragments = Box.findFirst(head, Box.mvex) != null;
track(id, fragments, head, tags, in, out);
track(id, fragments, head, tags, in, out, l, buf);
}

public static void track(int id, Mp4Tags tags, RandomAccessFile in, RandomAccessFile out) throws IOException {
track(id, tags, in, out, null);
}

public static void audio(File intput, File output, Mp4Tags tags) throws IOException {
RandomAccessFile in = new RandomAccessFile(intput, "r");
public static void audio(File input, File output, Mp4Tags tags, DemuxerListener l) throws IOException {
RandomAccessFile in = new RandomAccessFile(input, "r");
RandomAccessFile out = new RandomAccessFile(output, "rw");

try {
LinkedList<Box> head = IsoMedia.head(in);
ByteBuffer buf = ByteBuffer.allocate(100 * 1024);
LinkedList<Box> head = IsoMedia.head(in, buf);

// find audio track
SoundMediaHeaderBox smhd = Box.findFirst(head, Box.smhd);
TrackBox trak = (TrackBox) smhd.parent.parent.parent;
TrackHeaderBox tkhd = trak.findFirst(Box.tkhd);

boolean fragments = Box.findFirst(head, Box.mvex) != null;
track(tkhd.trackId(), fragments, head, tags, in, out);
track(tkhd.trackId(), fragments, head, tags, in, out, l, buf);

} finally {
close(in);
close(out);
}
}

private static void track(int id, boolean fragments, LinkedList<Box> head, Mp4Tags tags, RandomAccessFile in, RandomAccessFile out) throws IOException {
public static void audio(File input, File output, Mp4Tags tags) throws IOException {
audio(input, output, tags, null);
}

private static void track(int id, boolean fragments, LinkedList<Box> head, Mp4Tags tags, RandomAccessFile in, RandomAccessFile out, final DemuxerListener l, final ByteBuffer buf) throws IOException {
out.setLength(0);

if (fragments) {
trackFragments(id, head, tags, in, out);
trackFragments(id, head, tags, in, out, l, buf);
} else {
trackSimple(id, tags, in, out);
trackSimple(id, tags, in, out, l, buf);
}
}

private static void trackFragments(int id, LinkedList<Box> head, Mp4Tags tags, RandomAccessFile fIn, RandomAccessFile fOut) throws IOException {
private static void trackFragments(int id, LinkedList<Box> head, Mp4Tags tags, RandomAccessFile fIn, RandomAccessFile fOut, final DemuxerListener l, final ByteBuffer buf) throws IOException {
final int trackId = id;
final ByteBuffer buf = ByteBuffer.allocate(10 * 1024);
final int mdatOffset = calcMdatOffset(head, fIn.length(), tags);
fOut.seek(mdatOffset);

Expand All @@ -96,6 +105,7 @@ private static void trackFragments(int id, LinkedList<Box> head, Mp4Tags tags, R

@Override
public boolean onBox(Box b) {
notifyCount(l, in.count(), out.count());
if (b.parent == null && b.type != Box.mdat && b.type != Box.moof) {
boxes.add(b);
}
Expand Down Expand Up @@ -209,6 +219,7 @@ public boolean onBox(Box b) {

try {
IO.copy(in, out, mdat.length(), buf);
notifyCount(l, in.count(), out.count());
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -311,17 +322,17 @@ public boolean onBox(Box b) {
}, buf);
}

private static void trackSimple(int id, Mp4Tags tags, RandomAccessFile fIn, RandomAccessFile fOut) throws IOException {
private static void trackSimple(int id, Mp4Tags tags, RandomAccessFile fIn, RandomAccessFile fOut, final DemuxerListener l, final ByteBuffer buf) throws IOException {
int trackId = id;
ByteBuffer buf = ByteBuffer.allocate(10 * 1024);
InputChannel in = new InputChannel(fIn.getChannel());
OutputChannel out = new OutputChannel(fOut.getChannel());
final InputChannel in = new InputChannel(fIn.getChannel());
final OutputChannel out = new OutputChannel(fOut.getChannel());

final LinkedList<Box> boxes = new LinkedList<>();

IsoMedia.read(in, fIn.length(), null, new IsoMedia.OnBoxListener() {
@Override
public boolean onBox(Box b) {
notifyCount(l, in.count(), out.count());
if (b.parent == null) {
boxes.add(b);
}
Expand Down Expand Up @@ -405,6 +416,7 @@ public boolean onBox(Box b) {
IsoMedia.write(out, boxes, new IsoMedia.OnBoxListener() {
@Override
public boolean onBox(Box b) {
notifyCount(l, in.count(), out.count());
return true;
}
}, buf);
Expand All @@ -414,8 +426,10 @@ public boolean onBox(Box b) {

int skp = chunkOffsetOrg[i] - pos;
IO.skip(in, skp, buf);
notifyCount(l, in.count(), out.count());

IO.copy(in, out, chunkSize[i], buf);
notifyCount(l, in.count(), out.count());
}
}

Expand Down Expand Up @@ -491,4 +505,15 @@ private static void close(RandomAccessFile f) {
// ignore
}
}

private static void notifyCount(DemuxerListener l, long readCount, long writeCount) {
if (l != null) {
l.onCount(readCount, writeCount);
}
}

public interface DemuxerListener {

void onCount(long readCount, long writeCount);
}
}
4 changes: 2 additions & 2 deletions common/src/main/java/com/frostwire/util/MP4Muxer.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ protected Box createUdta(Movie movie) {
}
}

public void demuxAudio(String video, String output, final MP4Metadata mt) throws IOException {
public void demuxAudio(String video, String output, final MP4Metadata mt, Mp4Demuxer.DemuxerListener l) throws IOException {
try {
Mp4Tags tags = new Mp4Tags();
tags.compatibleBrands = new int[]{com.frostwire.fmp4.Box.M4A_, com.frostwire.fmp4.Box.mp42, com.frostwire.fmp4.Box.isom, com.frostwire.fmp4.Box.zero};
tags.title = mt.title;
tags.author = mt.author;
tags.source = mt.source;
tags.jpg = mt.jpg;
Mp4Demuxer.audio(new File(video), new File(output), tags);
Mp4Demuxer.audio(new File(video), new File(output), tags, l);
} catch (Throwable e) {
e.printStackTrace();
demuxAudioUsingMP4Parser(video, output, mt);
Expand Down

0 comments on commit a6d73c0

Please sign in to comment.