public static void main(String[] args) throws IOException {

    Movie video =
        MovieCreator.build(
            Channels.newChannel(
                Mp4WithAudioDelayExample.class.getResourceAsStream("/count-video.mp4")));
    Movie audio =
        MovieCreator.build(
            Channels.newChannel(
                Mp4WithAudioDelayExample.class.getResourceAsStream("/count-english-audio.mp4")));

    List<Track> videoTracks = video.getTracks();
    video.setTracks(new LinkedList<Track>());

    List<Track> audioTracks = audio.getTracks();

    for (Track videoTrack : videoTracks) {
      video.addTrack(new AppendTrack(videoTrack, videoTrack));
    }
    for (Track audioTrack : audioTracks) {
      audioTrack.getTrackMetaData().setStartTime(10.0);
      video.addTrack(audioTrack);
    }

    IsoFile out = new DefaultMp4Builder().build(video);
    FileOutputStream fos = new FileOutputStream(new File(String.format("output.mp4")));
    out.getBox(fos.getChannel());
    fos.close();
  }
  public void testSimpleRoundWithEntriesTrip(
      int baseOffsetSize, int indexSize, int lengthSize, int offsetSize) throws IOException {
    ItemLocationBox ilocOrig = new ItemLocationBox();
    ilocOrig.setVersion(1);
    ilocOrig.setBaseOffsetSize(baseOffsetSize);
    ilocOrig.setIndexSize(indexSize);
    ilocOrig.setLengthSize(lengthSize);
    ilocOrig.setOffsetSize(offsetSize);
    ItemLocationBox.Item item =
        ilocOrig.createItem(12, 0, 13, 123, Collections.<ItemLocationBox.Extent>emptyList());
    ilocOrig.setItems(Collections.singletonList(item));
    ByteBuffer bb = ByteBuffer.allocate(l2i(ilocOrig.getSize()));
    ilocOrig.getBox(new ByteBufferByteChannel(bb));

    bb.rewind();

    IsoFile isoFile = new IsoFile(new ByteBufferByteChannel(bb));

    ItemLocationBox iloc = (ItemLocationBox) isoFile.getBoxes().get(0);

    Assert.assertEquals(ilocOrig.getBaseOffsetSize(), iloc.getBaseOffsetSize());
    Assert.assertEquals(ilocOrig.getContentSize(), iloc.getContentSize());
    Assert.assertEquals(ilocOrig.getIndexSize(), iloc.getIndexSize());
    Assert.assertEquals(ilocOrig.getLengthSize(), iloc.getLengthSize());
    Assert.assertEquals(ilocOrig.getOffsetSize(), iloc.getOffsetSize());
    Assert.assertEquals(ilocOrig.getItems(), iloc.getItems());
  }
 public static void main(String[] args) throws IOException {
   IsoFile isoFile = new IsoFile(new IsoBufferWrapperImpl(new File("/home/sannies/vw.mp4")));
   Path p = new Path(isoFile);
   isoFile.parse();
   CompositionTimeToSample ctts =
       (CompositionTimeToSample) p.getPath("/moov/trak[1]/mdia/minf/stbl/ctts");
   int[] cts = CompositionTimeToSample.blowupCompositionTimes(ctts.getEntries());
   RawH264Track track =
       new RawH264Track(new IsoBufferWrapperImpl(new File("/home/sannies/vw_track2.h264")));
   // RawH264Track track = new RawH264Track(new IsoBufferWrapperImpl(new
   // File("/home/sannies/suckerpunch-samurai_h640w_track1.h264")));
 }
 public void parse(IsoBufferWrapper in, long size, BoxParser boxParser, Box lastMovieFragmentBox)
     throws IOException {
   super.parse(in, size, boxParser, lastMovieFragmentBox);
   classificationEntity = IsoFile.bytesToFourCC(in.read(4));
   classificationTableIndex = in.readUInt16();
   language = in.readIso639();
   classificationInfo = in.readString();
 }
  public void testRoundTrip_1(String resource) throws Exception {

    long start1 = System.currentTimeMillis();
    String originalFile =
        this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + resource;

    long start2 = System.currentTimeMillis();

    IsoFile isoFile = new IsoFile(originalFile);

    long start3 = System.currentTimeMillis();

    long start4 = System.currentTimeMillis();
    Walk.through(isoFile);
    long start5 = System.currentTimeMillis();

    File result = File.createTempFile(this.getName(), resource.replace("/", "_"));

    FileOutputStream fos = new FileOutputStream(result);
    FileChannel fcOut = fos.getChannel();
    isoFile.getBox(fcOut);
    fcOut.close();
    fos.close();

    long start6 = System.currentTimeMillis();

    /*   System.err.println("Preparing tmp copy took: " + (start2 - start1) + "ms");
    System.err.println("Parsing took           : " + (start3 - start2) + "ms");
    System.err.println("Writing took           : " + (start6 - start3) + "ms");
    System.err.println("Walking took           : " + (start5 - start4) + "ms");*/

    IsoFile copyViaIsoFileReparsed = new IsoFile(result.getAbsolutePath());
    BoxComparator.check(
        isoFile,
        copyViaIsoFileReparsed,
        "/moov[0]/mvhd[0]",
        "/moov[0]/trak[0]/tkhd[0]",
        "/moov[0]/trak[0]/mdia[0]/mdhd[0]");
    isoFile.close();
    copyViaIsoFileReparsed.close();
    result.deleteOnExit();
    // as windows cannot delete file when something is memory mapped and the garbage collector
    // doesn't necessarily free the Buffers quickly enough we cannot delete the file here (we could
    // but only for linux)

  }
Exemple #6
0
  public void convert(Context context, String infile, String outfile) throws IOException {
    AACToM4A.context = context;

    InputStream input = new FileInputStream(infile);

    PushbackInputStream pbi = new PushbackInputStream(input, 100);

    System.err.println("well you got " + input.available());
    Movie movie = new Movie();

    Track audioTrack = new AACTrackImpl(pbi);
    movie.addTrack(audioTrack);

    IsoFile out = new DefaultMp4Builder().build(movie);
    FileOutputStream output = new FileOutputStream(outfile);
    out.getBox(output.getChannel());
    output.close();
  }
  public void simpleRoundTrip(
      boolean isSampleSizePresent,
      boolean isSampleDurationPresent,
      boolean isSampleCompositionTimeOffsetPresent,
      int dataOffset,
      SampleFlags sf)
      throws IOException {
    TrackRunBox trun = new TrackRunBox();
    trun.setFirstSampleFlags(sf);
    trun.setSampleSizePresent(!isSampleSizePresent);
    trun.setSampleSizePresent(isSampleSizePresent);
    trun.setSampleDurationPresent(!isSampleDurationPresent);
    trun.setSampleDurationPresent(isSampleDurationPresent);
    trun.setSampleCompositionTimeOffsetPresent(!isSampleCompositionTimeOffsetPresent);
    trun.setSampleCompositionTimeOffsetPresent(isSampleCompositionTimeOffsetPresent);
    trun.setDataOffset(dataOffset);
    List<TrackRunBox.Entry> entries = new LinkedList<TrackRunBox.Entry>();
    entries.add(new TrackRunBox.Entry(1000, 2000, new SampleFlags(), 3000));
    entries.add(new TrackRunBox.Entry(1001, 2001, new SampleFlags(), 3001));
    trun.setEntries(entries);

    File f = File.createTempFile(this.getClass().getSimpleName(), "");
    FileChannel fc = new FileOutputStream(f).getChannel();
    trun.getBox(fc);
    fc.close();

    IsoFile isoFile = new IsoFile(f.getAbsolutePath());
    TrackRunBox trun2 = (TrackRunBox) isoFile.getBoxes().get(0);

    Assert.assertEquals(trun.isDataOffsetPresent(), trun2.isDataOffsetPresent());
    Assert.assertEquals(
        trun.isSampleCompositionTimeOffsetPresent(), trun2.isSampleCompositionTimeOffsetPresent());
    Assert.assertEquals(trun.isSampleDurationPresent(), trun2.isSampleDurationPresent());
    Assert.assertEquals(trun.isSampleFlagsPresent(), trun2.isSampleFlagsPresent());
    Assert.assertEquals(trun.isSampleSizePresent(), trun2.isSampleSizePresent());
    Assert.assertEquals(trun.getDataOffset(), trun2.getDataOffset());

    Assert.assertEquals(trun.getDataOffset(), trun2.getDataOffset());
    Assert.assertEquals(trun.getFirstSampleFlags(), trun2.getFirstSampleFlags());
  }
  /** {@inheritDoc} */
  public IsoFile build(Movie movie) {
    LOG.fine("Creating movie " + movie);
    for (Track track : movie.getTracks()) {
      // getting the samples may be a time consuming activity
      List<ByteBuffer> samples = track.getSamples();
      putSamples(track, samples);
      long[] sizes = new long[samples.size()];
      for (int i = 0; i < sizes.length; i++) {
        sizes[i] = samples.get(i).limit();
      }
      putSampleSizes(track, sizes);
    }

    IsoFile isoFile = new IsoFile();
    // ouch that is ugly but I don't know how to do it else
    List<String> minorBrands = new LinkedList<String>();
    minorBrands.add("isom");
    minorBrands.add("iso2");
    minorBrands.add("avc1");

    isoFile.addBox(new FileTypeBox("isom", 0, minorBrands));
    isoFile.addBox(createMovieBox(movie));
    InterleaveChunkMdat mdat = new InterleaveChunkMdat(movie);
    isoFile.addBox(mdat);

    /*
    dataOffset is where the first sample starts. In this special mdat the samples always start
    at offset 16 so that we can use the same offset for large boxes and small boxes
     */
    long dataOffset = mdat.getDataOffset();
    for (StaticChunkOffsetBox chunkOffsetBox : chunkOffsetBoxes) {
      long[] offsets = chunkOffsetBox.getChunkOffsets();
      for (int i = 0; i < offsets.length; i++) {
        offsets[i] += dataOffset;
      }
    }

    return isoFile;
  }
  public void testSimpleRoundTrip(int baseOffsetSize, int indexSize, int lengthSize, int offsetSize)
      throws IOException {
    ItemLocationBox ilocOrig = new ItemLocationBox();
    ilocOrig.setVersion(1);
    ilocOrig.setBaseOffsetSize(baseOffsetSize);
    ilocOrig.setIndexSize(indexSize);
    ilocOrig.setLengthSize(lengthSize);
    ilocOrig.setOffsetSize(offsetSize);
    ByteBuffer bb = ByteBuffer.allocate(l2i(ilocOrig.getSize()));
    ilocOrig.getBox(new ByteBufferByteChannel(bb));
    Assert.assertTrue(bb.remaining() == 0);
    bb.rewind();

    IsoFile isoFile = new IsoFile(new ByteBufferByteChannel(bb));

    ItemLocationBox iloc = (ItemLocationBox) isoFile.getBoxes().get(0);

    Assert.assertEquals(ilocOrig.getBaseOffsetSize(), iloc.getBaseOffsetSize());
    Assert.assertEquals(ilocOrig.getContentSize(), iloc.getContentSize());
    Assert.assertEquals(ilocOrig.getIndexSize(), iloc.getIndexSize());
    Assert.assertEquals(ilocOrig.getLengthSize(), iloc.getLengthSize());
    Assert.assertEquals(ilocOrig.getOffsetSize(), iloc.getOffsetSize());
    Assert.assertEquals(ilocOrig.getItems(), iloc.getItems());
  }
    public void getBox(WritableByteChannel writableByteChannel) throws IOException {
      ByteBuffer bb = ByteBuffer.allocate(16);
      long size = getSize();
      if (isSmallBox(size)) {
        IsoTypeWriter.writeUInt32(bb, size);
      } else {
        IsoTypeWriter.writeUInt32(bb, 1);
      }
      bb.put(IsoFile.fourCCtoBytes("mdat"));
      if (isSmallBox(size)) {
        bb.put(new byte[8]);
      } else {
        IsoTypeWriter.writeUInt64(bb, size);
      }
      bb.rewind();
      writableByteChannel.write(bb);
      if (writableByteChannel instanceof GatheringByteChannel) {
        List<ByteBuffer> nuSamples = unifyAdjacentBuffers(samples);

        int STEPSIZE = 1024;
        for (int i = 0; i < Math.ceil((double) nuSamples.size() / STEPSIZE); i++) {
          List<ByteBuffer> sublist =
              nuSamples.subList(
                  i * STEPSIZE, // start
                  (i + 1) * STEPSIZE < nuSamples.size()
                      ? (i + 1) * STEPSIZE
                      : nuSamples.size()); // end
          ByteBuffer sampleArray[] = sublist.toArray(new ByteBuffer[sublist.size()]);
          do {
            ((GatheringByteChannel) writableByteChannel).write(sampleArray);
          } while (sampleArray[sampleArray.length - 1].remaining() > 0);
        }
        // System.err.println(bytesWritten);
      } else {
        for (ByteBuffer sample : samples) {
          sample.rewind();
          writableByteChannel.write(sample);
        }
      }
    }
 public void getBox(WritableByteChannel writableByteChannel) throws IOException {
   ByteBuffer bb = ByteBuffer.allocate(16);
   long size = getSize();
   if (isSmallBox(size)) {
     IsoTypeWriter.writeUInt32(bb, size);
   } else {
     IsoTypeWriter.writeUInt32(bb, 1);
   }
   bb.put(IsoFile.fourCCtoBytes("mdat"));
   if (isSmallBox(size)) {
     bb.put(new byte[8]);
   } else {
     IsoTypeWriter.writeUInt64(bb, size);
   }
   bb.rewind();
   writableByteChannel.write(bb);
   for (List<Sample> samples : chunkList) {
     for (Sample sample : samples) {
       sample.writeTo(writableByteChannel);
     }
   }
 }
Exemple #12
0
  public SampleList(TrackBox trackBox) {
    this.isoFile = trackBox.getIsoFile(); // where are we?
    offsets2Sizes = new HashMap<Long, Long>();

    // find all mdats first to be able to use them later with explicitly looking them up
    long currentOffset = 0;
    for (Box b : 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;
    }

    // first we get all sample from the 'normal' MP4 part.
    // if there are none - no problem.

    SampleSizeBox sampleSizeBox = trackBox.getSampleTableBox().getSampleSizeBox();
    ChunkOffsetBox chunkOffsetBox = trackBox.getSampleTableBox().getChunkOffsetBox();
    SampleToChunkBox sampleToChunkBox = trackBox.getSampleTableBox().getSampleToChunkBox();

    if (sampleToChunkBox != null
        && sampleToChunkBox.getEntries().size() > 0
        && chunkOffsetBox != null
        && chunkOffsetBox.getChunkOffsets().length > 0
        && sampleSizeBox != null
        && sampleSizeBox.getSampleCount() > 0) {
      long[] numberOfSamplesInChunk =
          sampleToChunkBox.blowup(chunkOffsetBox.getChunkOffsets().length);
      if (sampleSizeBox.getSampleSize() > 0) {
        // Every sample has the same size!
        // no need to store each size separately
        // this happens when people use raw audio formats in MP4 (are you stupid guys???)
        offsets2Sizes = new DummyMap<Long, Long>(sampleSizeBox.getSampleSize());
        long sampleSize = sampleSizeBox.getSampleSize();
        for (int i = 0; i < numberOfSamplesInChunk.length; i++) {
          long thisChunksNumberOfSamples = numberOfSamplesInChunk[i];
          long sampleOffset = chunkOffsetBox.getChunkOffsets()[i];
          for (int j = 0; j < thisChunksNumberOfSamples; j++) {
            offsets2Sizes.put(sampleOffset, sampleSize);
            sampleOffset += sampleSize;
          }
        }
      } else {
        // the normal case where all samples have different sizes
        int sampleIndex = 0;
        long sampleSizes[] = sampleSizeBox.getSampleSizes();
        for (int i = 0; i < numberOfSamplesInChunk.length; i++) {
          long thisChunksNumberOfSamples = numberOfSamplesInChunk[i];
          long sampleOffset = chunkOffsetBox.getChunkOffsets()[i];
          for (int j = 0; j < thisChunksNumberOfSamples; j++) {
            long sampleSize = sampleSizes[sampleIndex];
            offsets2Sizes.put(sampleOffset, sampleSize);
            sampleOffset += sampleSize;
            sampleIndex++;
          }
        }
      }
    }

    // Next we add all samples from the fragments
    // in most cases - I've never seen it different it's either normal or fragmented.

    List<MovieExtendsBox> movieExtendsBoxes = trackBox.getParent().getBoxes(MovieExtendsBox.class);

    if (movieExtendsBoxes.size() > 0) {
      List<TrackExtendsBox> trackExtendsBoxes =
          movieExtendsBoxes.get(0).getBoxes(TrackExtendsBox.class);
      for (TrackExtendsBox trackExtendsBox : trackExtendsBoxes) {
        if (trackExtendsBox.getTrackId() == trackBox.getTrackHeaderBox().getTrackId()) {
          for (MovieFragmentBox movieFragmentBox :
              trackBox.getIsoFile().getBoxes(MovieFragmentBox.class)) {
            offsets2Sizes.putAll(
                getOffsets(movieFragmentBox, trackBox.getTrackHeaderBox().getTrackId()));
          }
        }
      }
    }

    // We have now a map from all sample offsets to their sizes
  }
 public MutableDrmInformationBox() {
   super(IsoFile.fourCCtoBytes(TYPE));
 }
 public ClassificationBox() {
   super(IsoFile.fourCCtoBytes(TYPE));
 }
 protected void getContent(IsoOutputStream isos) throws IOException {
   isos.write(IsoFile.fourCCtoBytes(classificationEntity));
   isos.writeUInt16(classificationTableIndex);
   isos.writeIso639(language);
   isos.writeStringZeroTerm(classificationInfo);
 }
 public TrackFragmentRandomAccessBox() {
   super(IsoFile.fourCCtoBytes(TYPE));
 }
Exemple #17
0
 public TitleBox() {
   super(IsoFile.fourCCtoBytes(TYPE));
 }
 public AppleDataReferenceBox() {
   super(IsoFile.fourCCtoBytes(TYPE));
 }
 public AppleLosslessSpecificBox() {
   super(IsoFile.fourCCtoBytes("alac"));
 }