All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcodec.movtool.Undo Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package org.jcodec.movtool;

import static org.jcodec.common.NIOUtils.readableFileChannel;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

import org.jcodec.common.NIOUtils;
import org.jcodec.common.SeekableByteChannel;
import org.jcodec.containers.mp4.MP4Util;
import org.jcodec.containers.mp4.MP4Util.Atom;
import org.jcodec.containers.mp4.boxes.Box;
import org.jcodec.containers.mp4.boxes.BoxFactory;
import org.jcodec.containers.mp4.boxes.Header;
import org.jcodec.containers.mp4.boxes.MovieBox;
import org.jcodec.containers.mp4.boxes.NodeBox;

/**
 * This class is part of JCodec ( www.jcodec.org ) This software is distributed
 * under FreeBSD License
 * 
 * Uses QuickTime feature to undo the recent changes
 * 
 * @author The JCodec project
 * 
 */
public class Undo {
    public static void main(String[] args) throws IOException {
        if (args.length < 1) {
            System.err.println("Syntax: qt-undo [-l] ");
            System.err.println("\t-l\t\tList all the previous versions of this movie.");
            System.exit(-1);
        }
        Undo undo = new Undo();
        if ("-l".equals(args[0])) {
            List list = undo.list(args[1]);
            System.out.println((list.size() - 1) + " versions.");
        } else {
            undo.undo(args[0]);
        }
    }

    private void undo(String fineName) throws IOException {
        List versions = list(fineName);
        if (versions.size() < 2) {
            System.err.println("Nowhere to rollback.");
            return;
        }
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(new File(fineName), "rw");
            raf.seek(versions.get(versions.size() - 2).getOffset() + 4);
            raf.write(new byte[] { 'm', 'o', 'o', 'v' });
            raf.seek(versions.get(versions.size() - 1).getOffset() + 4);
            raf.write(new byte[] { 'f', 'r', 'e', 'e' });
        } finally {
            raf.close();
        }
    }

    private List list(String fileName) throws IOException {
        ArrayList result = new ArrayList();
        SeekableByteChannel is = null;
        try {
            is = readableFileChannel(new File(fileName));
            int version = 0;
            for (Atom atom : MP4Util.getRootAtoms(is)) {
                if ("free".equals(atom.getHeader().getFourcc()) && isMoov(is, atom)) {
                    result.add(atom);
                }
                if ("moov".equals(atom.getHeader().getFourcc())) {
                    result.add(atom);
                    break;
                }
            }
        } finally {
            is.close();
        }
        return result;
    }

    private boolean isMoov(SeekableByteChannel is, Atom atom) throws IOException {
        is.position(atom.getOffset() + atom.getHeader().headerSize());
        try {
            Box mov = NodeBox.parseBox(NIOUtils.fetchFrom(is, (int) atom.getHeader().getSize()), new Header("moov", atom
                    .getHeader().getSize()), BoxFactory.getDefault());
            return (mov instanceof MovieBox) && Box.findFirst((NodeBox) mov, "mvhd") != null;
        } catch (Throwable t) {
            return false;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy