package org.mp4parser.examples.mux.streaming;
import org.mp4parser.streaming.StreamingTrack;
import org.mp4parser.streaming.input.aac.AdtsAacStreamingTrack;
import org.mp4parser.streaming.input.h264.H264AnnexBTrack;
import org.mp4parser.streaming.output.mp4.FragmentedMp4Writer;
import java.io.FileOutputStream;
import java.net.URI;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.logging.LogManager;
public class H264AACExample {
public static void main(String[] args) throws Exception {
LogManager.getLogManager().readConfiguration(H264AACExample.class.getResourceAsStream("/log.properties"));
AdtsAacStreamingTrack aac = new AdtsAacStreamingTrack(
new URI("http://org.mp4parser.s3.amazonaws.com/examples/Cosmos%20Laundromat%20small.aac").
toURL().openStream(), 48000, 64000); // How should I know avg bitrate in advance?
H264AnnexBTrack h264 = new H264AnnexBTrack(
new URI("http://org.mp4parser.s3.amazonaws.com/examples/Cosmos%20Laundromat%20small.264").
toURL().openStream());
/*InputStream aacInputStream = new FileInputStream("c:\\dev\\mp4parser\\843D111F-E839-4597-B60C-3B8114E0AA72_AU01.aac");
AdtsAacStreamingTrack aac = new AdtsAacStreamingTrack(
aacInputStream, 48000, 64000); // How should I know avg bitrate in advance?
InputStream h264InputStream = new FileInputStream("c:\\dev\\mp4parser\\843D111F-E839-4597-B60C-3B8114E0AA72_ABR05.h264");
H264AnnexBTrack h264 = new H264AnnexBTrack(h264InputStream);
*/
ExecutorService es = Executors.newCachedThreadPool();
CompletionService<Void> ecs
= new ExecutorCompletionService<>(es);
FileOutputStream fos = new FileOutputStream("c:\\dev\\mp4parser\\output.mp4");
WritableByteChannel wbc = fos.getChannel();
//AsyncWritableByteChannel asyncWritableByteChannel = new AsyncWritableByteChannel(wbc);
FragmentedMp4Writer multiTrackFragmentedMp4Writer =
new FragmentedMp4Writer(Arrays.<StreamingTrack>asList(aac, h264), wbc);
final List<Future<Void>> allFutures = new ArrayList<>();
List<Callable<Void>> allCallables = new ArrayList<>();
allCallables.add(aac);
allCallables.add(h264);
for (Callable<Void> callable : allCallables) {
allFutures.add(ecs.submit(callable));
}
System.out.println("Reading and writing started.");
while (true) {
List<Future<Void>> toBeRemoved = new ArrayList<>();
for (Future<Void> future : allFutures) {
if (future.isDone()) {
toBeRemoved.add(future);
}
}
allFutures.removeAll(toBeRemoved);
if (!allFutures.isEmpty()) {
try {
ecs.take().get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
System.out.println("Execution exception " + e.getMessage());
e.printStackTrace();
for (Future<Void> future : allFutures) {
if (!future.isDone()) {
System.out.println("Cancelling " + future);
future.cancel(true);
}
}
break;
}
} else {
break;
}
}
//asyncWritableByteChannel.close();
multiTrackFragmentedMp4Writer.close(); // writes the remaining samples
fos.close();
es.shutdown();
}
}