/**
* Creates <code>Movie</code> object from a <code>ReadableByteChannel</code>.
*
* @param name track name to identify later
* @param readableByteChannel the box structure is read from this channel
* @param randomAccessSource the samples or read from this randomAccessSource
* @return a representation of the movie
* @throws IOException in case of I/O error during IsoFile creation
*/
public static Movie build(ReadableByteChannel readableByteChannel, RandomAccessSource randomAccessSource, String name) throws IOException {
IsoFile isoFile = new IsoFile(readableByteChannel);
Movie m = new Movie();
List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);
for (TrackBox trackBox : trackBoxes) {
SchemeTypeBox schm = Path.getPath(trackBox, "mdia[0]/minf[0]/stbl[0]/stsd[0]/enc.[0]/sinf[0]/schm[0]");
if (schm != null && (schm.getSchemeType().equals("cenc") || schm.getSchemeType().equals("cbc1"))) {
m.addTrack(new CencMp4TrackImplImpl(
trackBox.getTrackHeaderBox().getTrackId(), isoFile,
randomAccessSource, name + "[" + trackBox.getTrackHeaderBox().getTrackId() + "]"));
} else if (schm != null && (schm.getSchemeType().equals("piff"))) {
m.addTrack(new PiffMp4TrackImpl(
trackBox.getTrackHeaderBox().getTrackId(), isoFile,
randomAccessSource, name + "[" + trackBox.getTrackHeaderBox().getTrackId() + "]"));
} else {
m.addTrack(new Mp4TrackImpl(
trackBox.getTrackHeaderBox().getTrackId(), isoFile,
randomAccessSource, name + "[" + trackBox.getTrackHeaderBox().getTrackId() + "]"));
}
}
m.setMatrix(isoFile.getMovieBox().getMovieHeaderBox().getMatrix());
return m;
}
public static void main(String[] args) throws IOException {
IsoFile isoFile = new IsoFile("D:\\downloads\\cracked.s01e01.hdtv.x264-2hd.mp4");
List<TrackBox> trackBoxes = Path.getPath(isoFile, "moov/trak/");
long trackId = -1;
TrackBox trackBox = null;
for (TrackBox _trackBox : trackBoxes) {
if (Path.getPath(_trackBox, "mdia/minf/stbl/stsd/avc1") != null) {
trackId = _trackBox.getTrackHeaderBox().getTrackId();
trackBox = _trackBox;
}
}
Mp4SampleList sl = new Mp4SampleList(trackId, isoFile, new FileRandomAccessSourceImpl(
new RandomAccessFile("D:\\downloads\\cracked.s01e01.hdtv.x264-2hd.mp4", "r")));
FileChannel fc = new FileOutputStream("out.h264").getChannel();
ByteBuffer separator = ByteBuffer.wrap(new byte[]{0, 0, 0, 1});
fc.write((ByteBuffer) ((Buffer)separator).rewind());
// Write SPS
fc.write((
((AvcConfigurationBox) Path.getPath(trackBox, "mdia/minf/stbl/stsd/avc1/avcC")
).getSequenceParameterSets().get(0)));
// Warning:
// There might be more than one SPS (I've never seen that but it is possible)
fc.write((ByteBuffer) ((Buffer)separator).rewind());
// Write PPS
fc.write((
((AvcConfigurationBox) Path.getPath(trackBox, "mdia/minf/stbl/stsd/avc1/avcC")
).getPictureParameterSets().get(0)));
// Warning:
// There might be more than one PPS (I've never seen that but it is possible)
int lengthSize = ((AvcConfigurationBox) Path.getPath(trackBox, "mdia/minf/stbl/stsd/avc1/avcC")).getLengthSizeMinusOne() + 1;
for (Sample sample : sl) {
ByteBuffer bb = sample.asByteBuffer();
while (bb.remaining() > 0) {
int length = (int) IsoTypeReaderVariable.read(bb, lengthSize);
fc.write((ByteBuffer) ((Buffer)separator).rewind());
fc.write((ByteBuffer) ((Buffer)bb.slice()).limit(length));
((Buffer)bb).position(bb.position() + length);
}
}
fc.close();
}