org.jcodec.containers.mp4.boxes.Box.java Source code

Java tutorial

Introduction

Here is the source code for org.jcodec.containers.mp4.boxes.Box.java

Source

package org.jcodec.containers.mp4.boxes;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.collections15.Predicate;
import org.apache.commons.io.IOUtils;

/**
 * This class is part of JCodec ( www.jcodec.org ) This software is distributed
 * under FreeBSD License
 * 
 * An MP4 file struncture (box).
 * 
 * @author The JCodec project
 * 
 */
public abstract class Box {
    protected Header header;

    public Box(Header header) {
        this.header = header;
    }

    public Box(Box other) {
        this.header = other.header;
    }

    public Header getHeader() {
        return header;
    }

    public abstract void parse(InputStream input) throws IOException;

    public static Box findFirst(NodeBox box, String... path) {
        return findFirst(box, Box.class, path);
    }

    public static <T> T findFirst(NodeBox box, Class<T> clazz, String... path) {
        T[] result = (T[]) findAll(box, clazz, path);

        return result.length > 0 ? result[0] : null;
    }

    public static Box[] findAll(Box box, String... path) {
        return findAll(box, Box.class, path);
    }

    private static void findSub(Box box, List<String> path, Collection<Box> result) {

        if (path.size() > 0) {
            String head = path.remove(0);
            if (box instanceof NodeBox) {
                NodeBox nb = (NodeBox) box;
                for (Box candidate : nb.getBoxes()) {
                    if (head == null || head.equals(candidate.header.getFourcc())) {
                        findSub(candidate, path, result);
                    }
                }
            }
            path.add(0, head);
        } else {
            result.add(box);
        }
    }

    public static <T> T[] findAll(Box box, Class<T> class1, String... path) {
        List<Box> result = new LinkedList<Box>();
        List<String> tlist = new LinkedList<String>();
        for (String type : path) {
            tlist.add(type);
        }
        findSub(box, tlist, result);
        return result.toArray((T[]) Array.newInstance(class1, 0));
    }

    public void write(DataOutput out) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        doWrite(new DataOutputStream(bout));
        byte[] bytes = bout.toByteArray();

        header.setBodySize(bytes.length);
        header.write(out);
        out.write(bytes);
    }

    public void write(File dst) throws IOException {
        DataOutputStream dout = null;
        try {
            dout = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dst)));
            write(dout);
        } finally {
            IOUtils.closeQuietly(dout);
        }
    }

    protected void doWrite(DataOutput out) throws IOException {
        throw new RuntimeException(header.getFourcc() + " not implemented, must override");
    }

    public static Predicate<Box> not(final String type) {
        return new Predicate<Box>() {
            public boolean evaluate(Box object) {
                return !object.getHeader().getFourcc().equals(type);
            }
        };
    }

    public Box cloneBox() {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            write(new DataOutputStream(baos));
            return NodeBox.parseChildBox(new ByteArrayInputStream(baos.toByteArray()), BoxFactory.getDefault());
        } catch (IOException e) {
        }
        return null;
    }

    public long calcSize() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            write(new DataOutputStream(baos));
        } catch (IOException e) {
        }
        return baos.size();
    }

    public String getFourcc() {
        return header.getFourcc();
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        dump(sb);
        return sb.toString();

    }

    protected void dump(StringBuilder sb) {
        sb.append("'" + header.getFourcc() + "'");
    }
}