public void writeTo(WritableByteChannel channel) throws java.io.IOException { for (Box box : boxes) { box.getBox(channel); } }
private static String createPath(Box box, String path) { if (box instanceof IsoFile) { return path; } else { List<?> boxesOfBoxType = box.getParent().getBoxes(box.getClass()); int index = boxesOfBoxType.indexOf(box); path = String.format("/%s[%d]", box.getType(), index) + path; return createPath(box.getParent(), path); } }
@Override protected long getContentSize() { long contentSize = 8; for (Box boxe : boxes) { contentSize += boxe.getSize(); } return contentSize; }
box.setParent(parent); LOG.finest("Parsing " + box.getType()); box.parse(byteChannel, header, contentSize, this); assert size == box.getSize() : "Reconstructed Size is not x to the number of parsed bytes! (" + box.getType() + ")" + " Actual Box size: " + size + " Calculated size: " + box.getSize(); return box;
public static void replace(Map<String, Box> replacements, File file) throws IOException { IsoFile isoFile = new IsoFile( new FileDataSourceImpl(new RandomAccessFile(file, "r").getChannel())); Map<String, Box> replacementSanitised = new HashMap<String, Box>(); Map<String, Long> positions = new HashMap<String, Long>(); for (Map.Entry<String, Box> e : replacements.entrySet()) { Box b = Path.getPath(isoFile, e.getKey()); replacementSanitised.put(Path.createPath( b ), e.getValue()); positions.put(Path.createPath( b ), b.getOffset()); assert b.getSize() == e.getValue().getSize(); } isoFile.close(); FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel(); for (String path : replacementSanitised.keySet()) { Box b = replacementSanitised.get(path); long pos = positions.get(path); fileChannel.position(pos); b.getBox(fileChannel); } fileChannel.close(); }
/** * Add <code>b</code> to the container and sets the parent correctly. * * @param b will be added to the container */ public void addBox(Box b) { b.setParent(this); boxes.add(b); }
private void initIsoFile(IsoFile isoFile) { this.isoFile = isoFile; // find all mdats first to be able to use them later with explicitly looking them up long currentOffset = 0; LinkedList<MediaDataBox> mdats = new LinkedList<MediaDataBox>(); for (Box b : this.isoFile.getBoxes()) { long currentSize = b.getSize(); if ("mdat".equals(b.getType())) { if (b instanceof MediaDataBox) { long contentOffset = currentOffset + ((MediaDataBox) b).getHeader().limit(); mdatStartCache.put((MediaDataBox) b, contentOffset); mdatEndCache.put((MediaDataBox) b, contentOffset + currentSize); mdats.add((MediaDataBox) b); } else { throw new RuntimeException("Sample need to be in mdats and mdats need to be instanceof MediaDataBox"); } } currentOffset += currentSize; } this.mdats = mdats.toArray(new MediaDataBox[mdats.size()]); }
private void correctChunkOffsets(Container container, long correction) { List<Box> chunkOffsetBoxes = Path.getPaths(container, "/moov[0]/trak/mdia[0]/minf[0]/stbl[0]/stco[0]"); for (Box chunkOffsetBox : chunkOffsetBoxes) { LinkedList<Box> stblChildren = new LinkedList<>(chunkOffsetBox.getParent().getBoxes()); stblChildren.remove(chunkOffsetBox); long[] cOffsets = ((ChunkOffsetBox) chunkOffsetBox).getChunkOffsets(); for (int i = 0; i < cOffsets.length; i++) { cOffsets[i] += correction; } StaticChunkOffsetBox cob = new StaticChunkOffsetBox(); cob.setChunkOffsets(cOffsets); stblChildren.add(cob); chunkOffsetBox.getParent().setBoxes(stblChildren); } }
public SampleDescriptionBox getSampleDescriptionBox() { OriginalFormatBox frma = Path.getPath(original.getSampleDescriptionBox(), "enc./sinf/frma"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); SampleDescriptionBox stsd; try { original.getSampleDescriptionBox().getBox(Channels.newChannel(baos)); stsd = (SampleDescriptionBox) new IsoFile(new MemoryDataSourceImpl(baos.toByteArray())).getBoxes().get(0); } catch (IOException e) { throw new RuntimeException("Dumping stsd to memory failed"); } if (stsd.getSampleEntry() instanceof AudioSampleEntry) { ((AudioSampleEntry) stsd.getSampleEntry()).setType(frma.getDataFormat()); } else if (stsd.getSampleEntry() instanceof VisualSampleEntry) { ((VisualSampleEntry) stsd.getSampleEntry()).setType(frma.getDataFormat()); } else { throw new RuntimeException("I don't know " + stsd.getSampleEntry().getType()); } List<Box> nuBoxes = new LinkedList<Box>(); for (Box box : stsd.getSampleEntry().getBoxes()) { if (!box.getType().equals("sinf")) { nuBoxes.add(box); } } stsd.getSampleEntry().setBoxes(nuBoxes); return stsd; }
box.setParent(parent); LOG.finest("Parsing " + box.getType()); box.parse(byteChannel, header, contentSize, this); assert size == box.getSize() : "Reconstructed Size is not x to the number of parsed bytes! (" + box.getType() + ")" + " Actual Box size: " + size + " Calculated size: " + box.getSize(); return box;
/** * Add <code>b</code> to the container and sets the parent correctly. * * @param b will be added to the container */ public void addBox(Box b) { b.setParent(this); boxes.add(b); }
private void initIsoFile(IsoFile isoFile) { this.isoFile = isoFile; // find all mdats first to be able to use them later with explicitly looking them up long currentOffset = 0; LinkedList<MediaDataBox> mdats = new LinkedList<MediaDataBox>(); for (Box b : this.isoFile.getBoxes()) { long currentSize = b.getSize(); if ("mdat".equals(b.getType())) { if (b instanceof MediaDataBox) { long contentOffset = currentOffset + ((MediaDataBox) b).getHeader().limit(); mdatStartCache.put((MediaDataBox) b, contentOffset); mdatEndCache.put((MediaDataBox) b, contentOffset + currentSize); mdats.add((MediaDataBox) b); } else { throw new RuntimeException("Sample need to be in mdats and mdats need to be instanceof MediaDataBox"); } } currentOffset += currentSize; } this.mdats = mdats.toArray(new MediaDataBox[mdats.size()]); }
public SampleList(TrackBox trackBox, IsoFile... additionalFragments) { Container topLevel = ((Box) trackBox.getParent()).getParent(); if (trackBox.getParent().getBoxes(MovieExtendsBox.class).isEmpty()) { if (additionalFragments.length > 0) { throw new RuntimeException("The TrackBox comes from a standard MP4 file. Only use the additionalFragments param if you are dealing with ( fragmented MP4 files AND additional fragments in standalone files )"); } samples = new DefaultMp4SampleList(trackBox.getTrackHeaderBox().getTrackId(), topLevel); } else { samples = new FragmentedMp4SampleList(trackBox.getTrackHeaderBox().getTrackId(), topLevel, additionalFragments); } }