/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.castlabs.dash.dashfragmenter.cmdlines;
import com.castlabs.dash.dashfragmenter.Command;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.FileDataSourceImpl;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.builder.Mp4Builder;
import com.googlecode.mp4parser.authoring.tracks.*;
import com.googlecode.mp4parser.authoring.tracks.h264.H264TrackImpl;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.spi.FileOptionHandler;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.WritableByteChannel;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.castlabs.dash.helpers.LanguageHelper.getFilesLanguage;
public class MuxMp4 implements Command {
private static Logger LOG = Logger.getLogger(MuxMp4.class.getName());
@Argument(required = true, multiValued = true, handler = FileOptionHandler.class, usage = "Bitstream input files. In case that an audio input format cannot convey the input's language the filename is expected to be [basename]-[lang].[ext]", metaVar = "vid1.h264, aud1.dtshd ...")
protected List<File> inputFiles;
@Option(name = "--outputfile", aliases = "-o",
usage = "output file - if no output file is given output.mp4 is used",
metaVar = "PATH")
protected File outputFile = new File(System.getProperty("user.dir") + File.separator + "output.mp4");
public int run() {
long start = System.currentTimeMillis();
List<Track> tracks = null;
try {
tracks = createTracks();
// export the dashed single track MP4s
writeMp4(tracks);
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
return 8279;
}
//System.out.println("Finished writeOnDemand in " + (System.currentTimeMillis() - start) + "ms");
return 0;
}
public void postProcessCmdLineArgs(CmdLineParser cmdLineParser) throws CmdLineException {
}
Mp4Builder getFileBuilder(Movie m) {
return new DefaultMp4Builder();
}
private void writeMp4(List<Track> tracks) throws IOException {
Movie m = new Movie();
m.setTracks(tracks);
Mp4Builder mp4Builder = getFileBuilder(m);
Container isoFile = mp4Builder.build(m);
System.out.print("Writing t ");
WritableByteChannel wbc = new FileOutputStream(outputFile).getChannel();
try {
isoFile.writeContainer(wbc);
} finally {
wbc.close();
}
System.out.println("Done.");
}
/**
* Generates filenames from type, language and bitrate.
*
* @return a descriptive filename <code>type[-lang]-bitrate.mp4</code>
*/
private Map<Track, String> generateFilenames(Map<Track, String> trackOriginalFilename) {
HashMap<Track, String> filenames = new HashMap<Track, String>();
for (Track track : trackOriginalFilename.keySet()) {
String originalFilename = trackOriginalFilename.get(track);
originalFilename = originalFilename.replace(".aac", "");
originalFilename = originalFilename.replace(".ec3", "");
originalFilename = originalFilename.replace(".h264", "");
originalFilename = originalFilename.replace(".ac3", "");
originalFilename = originalFilename.replace(".dtshd", "");
filenames.put(track, String.format("%s.mp4", originalFilename));
}
return filenames;
}
/**
* Creates a List of Track
*
* @throws java.io.IOException
*/
List<Track> createTracks() throws IOException {
List<Track> tracks = new LinkedList<Track>();
for (File inputFile : inputFiles) {
if (inputFile.getName().endsWith(".aac")) {
Track track = new AACTrackImpl(new FileDataSourceImpl(inputFile));
track.getTrackMetaData().setLanguage(getFilesLanguage(inputFile).getISO3Language());
tracks.add(track);
} else if (inputFile.getName().endsWith(".ac3")) {
Track track = new AC3TrackImpl(new FileDataSourceImpl(inputFile));
track.getTrackMetaData().setLanguage(getFilesLanguage(inputFile).getISO3Language());
tracks.add(track);
} else if (inputFile.getName().endsWith(".h264")) {
Track track = new H264TrackImpl(new FileDataSourceImpl(inputFile));
tracks.add(track);
} else if (inputFile.getName().endsWith(".ec3")) {
Track track = new EC3TrackImpl(new FileDataSourceImpl(inputFile));
track.getTrackMetaData().setLanguage(getFilesLanguage(inputFile).getISO3Language());
tracks.add(track);
} else if (inputFile.getName().endsWith(".dtshd")) {
Track track = new DTSTrackImpl(new FileDataSourceImpl(inputFile));
track.getTrackMetaData().setLanguage(getFilesLanguage(inputFile).getISO3Language());
tracks.add(track);
} else {
System.err.println("Cannot identify type of " + inputFile + ". Extensions aac, ac3, ec3 or dtshd are known.");
}
}
return tracks;
}
}