Package net.sourceforge.jaad.mp4

Source Code of net.sourceforge.jaad.mp4.MP4Container

/*
*  Copyright (C) 2011 in-somnia
*
*  This file is part of JAAD.
*
*  JAAD is free software; you can redistribute it and/or modify it
*  under the terms of the GNU Lesser General Public License as
*  published by the Free Software Foundation; either version 3 of the
*  License, or (at your option) any later version.
*
*  JAAD is distributed in the hope that it will be useful, but WITHOUT
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
*  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
*  Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library.
*  If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.jaad.mp4;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.jaad.mp4.api.Brand;
import net.sourceforge.jaad.mp4.api.Movie;
import net.sourceforge.jaad.mp4.boxes.Box;
import net.sourceforge.jaad.mp4.boxes.BoxFactory;
import net.sourceforge.jaad.mp4.boxes.BoxTypes;
import net.sourceforge.jaad.mp4.boxes.impl.FileTypeBox;
import net.sourceforge.jaad.mp4.boxes.impl.ProgressiveDownloadInformationBox;

/**
* The MP4Container is the central class for the MP4 demultiplexer. It reads the
* container and gives access to the containing data.
*
* The data source can be either an <code>InputStream</code> or a
* <code>RandomAccessFile</code>. Since the specification does not decree a
* specific order of the content, the data needed for parsing (the sample
* tables) may be at the end of the stream. In this case, random access is
* needed and reading from an <code>InputSteam</code> will cause an exception.
* Thus, whenever possible, a <code>RandomAccessFile</code> should be used for
* local files. Parsing from an <code>InputStream</code> is useful when reading
* from a network stream.
*
* Each <code>MP4Container</code> can return the used file brand (file format
* version). Optionally, the following data may be present:
* <ul>
* <li>progressive download informations: pairs of download rate and playback
* delay, see {@link #getDownloadInformationPairs() getDownloadInformationPairs()}</li>
* <li>a <code>Movie</code></li>
* </ul>
*
* Additionally it gives access to the underlying MP4 boxes, that can be
* retrieved by <code>getBoxes()</code>. However, it is not recommended to
* access the boxes directly.
*
* @author in-somnia
*/
public class MP4Container {

  static {
    Logger log = Logger.getLogger("MP4 API");
    for(Handler h : log.getHandlers()) {
      log.removeHandler(h);
    }
    log.setLevel(Level.WARNING);

    final ConsoleHandler h = new ConsoleHandler();
    h.setLevel(Level.ALL);
    log.addHandler(h);
  }
  private final MP4InputStream in;
  private final List<Box> boxes;
  private Brand major, minor;
  private Brand[] compatible;
  private FileTypeBox ftyp;
  private ProgressiveDownloadInformationBox pdin;
  private Box moov;
  private Movie movie;

  public MP4Container(InputStream in) throws IOException {
    this.in = new MP4InputStream(in);
    boxes = new ArrayList<Box>();

    readContent();
  }

  public MP4Container(RandomAccessFile in) throws IOException {
    this.in = new MP4InputStream(in);
    boxes = new ArrayList<Box>();

    readContent();
  }

  private void readContent() throws IOException {
    //read all boxes
    Box box = null;
    long type;
    boolean moovFound = false;
    while(in.hasLeft()) {
      box = BoxFactory.parseBox(null, in);
      if(boxes.isEmpty()&&box.getType()!=BoxTypes.FILE_TYPE_BOX) throw new MP4Exception("no MP4 signature found");
      boxes.add(box);

      type = box.getType();
      if(type==BoxTypes.FILE_TYPE_BOX) {
        if(ftyp==null) ftyp = (FileTypeBox) box;
      }
      else if(type==BoxTypes.MOVIE_BOX) {
        if(movie==null) moov = box;
        moovFound = true;
      }
      else if(type==BoxTypes.PROGRESSIVE_DOWNLOAD_INFORMATION_BOX) {
        if(pdin==null) pdin = (ProgressiveDownloadInformationBox) box;
      }
      else if(type==BoxTypes.MEDIA_DATA_BOX) {
        if(moovFound) break;
        else if(!in.hasRandomAccess()) throw new MP4Exception("movie box at end of file, need random access");
      }
    }
  }

  public Brand getMajorBrand() {
    if(major==null) major = Brand.forID(ftyp.getMajorBrand());
    return major;
  }

  public Brand getMinorBrand() {
    if(minor==null) minor = Brand.forID(ftyp.getMajorBrand());
    return minor;
  }

  public Brand[] getCompatibleBrands() {
    if(compatible==null) {
      final String[] s = ftyp.getCompatibleBrands();
      compatible = new Brand[s.length];
      for(int i = 0; i<s.length; i++) {
        compatible[i] = Brand.forID(s[i]);
      }
    }
    return compatible;
  }

  //TODO: pdin, movie fragments??
  public Movie getMovie() {
    if(moov==null) return null;
    else if(movie==null) movie = new Movie(moov, in);
    return movie;
  }

  public List<Box> getBoxes() {
    return Collections.unmodifiableList(boxes);
  }
}
TOP

Related Classes of net.sourceforge.jaad.mp4.MP4Container

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.