Exemple #1
0
  @Test
  public void testAVCClipCat() throws IOException {
    File f1 = new File("src/test/resources/AVCClipCatTest/seq_1.mp4");
    File f2 = new File("src/test/resources/AVCClipCatTest/seq_2.mp4");
    File f3 = new File("src/test/resources/AVCClipCatTest/seq_3.mp4");

    MovieBox m1 = MP4Util.parseMovie(f1);
    MovieBox m2 = MP4Util.parseMovie(f2);
    MovieBox m3 = MP4Util.parseMovie(f3);

    VirtualTrack t1 =
        new AVCClipTrack(new RealTrack(m1, m1.getVideoTrack(), new FilePool(f1, 10)), 60, 120);
    VirtualTrack t2 =
        new AVCClipTrack(new RealTrack(m2, m2.getVideoTrack(), new FilePool(f2, 10)), 60, 120);
    VirtualTrack t3 =
        new AVCClipTrack(new RealTrack(m3, m3.getVideoTrack(), new FilePool(f3, 10)), 60, 120);

    AVCConcatTrack ct = new AVCConcatTrack(t1, t2, t3);
    VirtualMovie vm = new VirtualMP4Movie(ct);

    MovieRange range = new MovieRange(vm, 0, vm.size());

    BufferedOutputStream out =
        new BufferedOutputStream(
            new FileOutputStream(
                new File(System.getProperty("user.home"), "Desktop/cat_avc_clip.mp4")));
    IOUtils.copy(range, out);
    out.flush();
    out.close();
  }
Exemple #2
0
 private static void saveSlices(List<MovieBox> slices, List<String> names, File parentFile)
     throws IOException {
   for (int i = 0; i < slices.size(); i++) {
     if (names.get(i) == null) continue;
     SeekableByteChannel out = null;
     try {
       out = writableChannel(new File(parentFile, names.get(i)));
       MP4Util.writeMovie(out, slices.get(i));
     } finally {
       NIOUtils.closeQuietly(out);
     }
   }
 }
Exemple #3
0
 public static void main1(String[] args) throws Exception {
   if (args.length < 2) {
     System.out.println("Syntax: self <ref movie> <out movie>");
     System.exit(-1);
   }
   File outFile = new File(args[1]);
   Platform.deleteFile(outFile);
   SeekableByteChannel input = null;
   try {
     input = readableChannel(new File(args[0]));
     MovieBox movie = MP4Util.parseMovieChannel(input);
     new Flattern().flattern(movie, outFile);
   } finally {
     if (input != null) input.close();
   }
 }
Exemple #4
0
  @Test
  public void testAVCClip() throws IOException {
    File f1 = new File("src/test/resources/AVCClipCatTest/seq_1.mp4");

    MovieBox m1 = MP4Util.parseMovie(f1);

    VirtualTrack t1 =
        new AVCClipTrack(new RealTrack(m1, m1.getVideoTrack(), new FilePool(f1, 10)), 60, 120);

    VirtualMovie vm = new VirtualMP4Movie(t1);

    MovieRange range = new MovieRange(vm, 0, vm.size());

    BufferedOutputStream out =
        new BufferedOutputStream(
            new FileOutputStream(
                new File(System.getProperty("user.home"), "Desktop/precise_clip.mp4")));
    IOUtils.copy(range, out);
    out.flush();
    out.close();
  }
Exemple #5
0
  public void flatternChannel(MovieBox movie, SeekableByteChannel out) throws IOException {
    if (!movie.isPureRefMovie(movie))
      throw new IllegalArgumentException("movie should be reference");
    ByteBuffer buf = ByteBuffer.allocate(16 * 1024 * 1024);
    FileTypeBox ftyp =
        FileTypeBox.createFileTypeBox("qt  ", 0x20050300, Arrays.asList(new String[] {"qt  "}));
    ftyp.write(buf);
    long movieOff = buf.position();
    movie.write(buf);

    int extraSpace = calcSpaceReq(movie);
    Header.createHeader("free", 8 + extraSpace).write(buf);
    NIOUtils.skip(buf, extraSpace);

    long mdatOff = buf.position();
    Header.createHeader("mdat", 0x100000001L).write(buf);
    buf.flip();
    out.write(buf);

    SeekableByteChannel[][] inputs = getInputs(movie);

    TrakBox[] tracks = movie.getTracks();
    ChunkReader[] readers = new ChunkReader[tracks.length];
    ChunkWriter[] writers = new ChunkWriter[tracks.length];
    Chunk[] head = new Chunk[tracks.length];
    int totalChunks = 0, writtenChunks = 0, lastProgress = 0;
    long[] off = new long[tracks.length];
    for (int i = 0; i < tracks.length; i++) {
      readers[i] = new ChunkReader(tracks[i]);
      totalChunks += readers[i].size();

      writers[i] = new ChunkWriter(tracks[i], inputs[i], out);
      head[i] = readers[i].next();
      if (tracks[i].isVideo()) off[i] = 2 * movie.getTimescale();
    }

    while (true) {
      int min = -1;
      for (int i = 0; i < readers.length; i++) {
        if (head[i] == null) continue;

        if (min == -1) min = i;
        else {
          long iTv = movie.rescale(head[i].getStartTv(), tracks[i].getTimescale()) + off[i];
          long minTv = movie.rescale(head[min].getStartTv(), tracks[min].getTimescale()) + off[min];
          if (iTv < minTv) min = i;
        }
      }
      if (min == -1) break;
      writers[min].write(head[min]);
      head[min] = readers[min].next();
      writtenChunks++;

      lastProgress = calcProgress(totalChunks, writtenChunks, lastProgress);
    }
    long mdatSize = out.position() - mdatOff;

    for (int i = 0; i < tracks.length; i++) {
      writers[i].apply();
    }
    out.setPosition(movieOff);
    MP4Util.writeMovie(out, movie);

    long extra = mdatOff - out.position();
    if (extra < 0) throw new RuntimeException("Not enough space to write the header");
    out.write(
        (ByteBuffer)
            ByteBuffer.allocate(8).putInt((int) extra).put(new byte[] {'f', 'r', 'e', 'e'}).flip());

    out.setPosition(mdatOff + 8);
    out.write(ByteBuffer.allocate(8).putLong(mdatSize));
  }
Exemple #6
0
  public static void main1(String[] args) throws Exception {
    if (args.length < 1) {
      System.out.println(
          "Syntax: cut [-command arg]...[-command arg] [-self] <movie file>\n"
              + "\tCreates a reference movie out of the file and applies a set of changes specified by the commands to it.");
      System.exit(-1);
    }

    List<Slice> slices = new ArrayList<Slice>();
    List<String> sliceNames = new ArrayList<String>();

    boolean selfContained = false;
    int shift = 0;
    while (true) {
      if ("-cut".equals(args[shift])) {
        String[] pt = StringUtils.splitS(args[shift + 1], ":");
        slices.add(new Slice(parseInt(pt[0]), parseInt(pt[1])));
        if (pt.length > 2) sliceNames.add(pt[2]);
        else sliceNames.add(null);
        shift += 2;
      } else if ("-self".equals(args[shift])) {
        ++shift;
        selfContained = true;
      } else break;
    }
    File source = new File(args[shift]);

    SeekableByteChannel input = null;
    SeekableByteChannel out = null;
    List<SeekableByteChannel> outs = new ArrayList<SeekableByteChannel>();
    try {
      input = readableChannel(source);
      MovieBox movie = createRefMovie(input, "file://" + source.getCanonicalPath());
      List<MovieBox> slicesMovs;
      if (!selfContained) {
        out =
            writableChannel(
                new File(
                    source.getParentFile(),
                    JCodecUtil2.removeExtension(source.getName()) + ".ref.mov"));
        slicesMovs = new Cut().cut(movie, slices);
        MP4Util.writeMovie(out, movie);
      } else {
        out =
            writableChannel(
                new File(
                    source.getParentFile(),
                    JCodecUtil2.removeExtension(source.getName()) + ".self.mov"));
        slicesMovs = new Cut().cut(movie, slices);
        new Strip().strip(movie);
        new Flattern().flatternChannel(movie, out);
      }
      saveSlices(slicesMovs, sliceNames, source.getParentFile());
    } finally {
      if (input != null) input.close();
      if (out != null) out.close();
      for (SeekableByteChannel o : outs) {
        o.close();
      }
    }
  }