Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import javax.swing.JOptionPane;
- import javax.swing.JTextField;
- /**
- * Francis Lyons
- * 10/13/14
- *
- * program built to delete i frames and repeat certain sections of b-frames
- *
- * takes as an argument the filename w/o filetype of the video to be used (works with videos in AVI format, converted using FFMPEG)
- *
- * reccomended to use avidemux or something similar to find total number of frames in video / specific frame locations
- */
- public class NewMash
- {
- public static final int[] F_BYTES = new int[4];
- public static final int[] I_BYTES = new int[4];
- /*
- * the nextFrame method should return the long position of the
- * beginning of the next frame, regardless of if it is a keyframe
- * or not. method will return -1 if it hits the end of the file
- * before finding another frame
- * takes as a parameter the current read position in the file
- */
- public static long nextFrame(RandomAccessFile file, long start) throws IOException
- {
- long startPos = -1;
- long currentPos = start; // get current read position
- file.seek(start);
- while(file.getFilePointer() < file.length())
- {
- file.seek(currentPos); // currentPos is incremented by 1 each time, reads in if went to far
- if(file.read() == F_BYTES[0] && file.read() == F_BYTES[1] && file.read() == F_BYTES[2] && file.read() == F_BYTES[3])
- {
- // we have found the beginning of a frame
- // grab the found frame start position and get out of the while loop
- startPos = currentPos;
- break;
- }
- currentPos++;
- }
- file.seek(start);
- return startPos;
- }
- /*
- * method to check if current frame is a keyframe
- * to be used properly this method should be used in conjunction
- * with nextFrame (this method should take as a parameter the long position
- * of the beginning of a frame in the file, then it will return boolean
- * of whether or not the frame is an i frame)
- *
- * right now the number of bytes to search for the iframe flag
- * is hardcoded at 15 to be safe
- */
- public static boolean isIFrame(RandomAccessFile file, long pos) throws IOException
- {
- boolean iFrame = false;
- for(int i = 0; i < 15; i++)
- {
- file.seek(pos + i); // start reading at the given position, then moves 1 forward each time
- if(file.read() == I_BYTES[0] && file.read() == I_BYTES[1] && file.read() == I_BYTES[2] && file.read() == I_BYTES[3])
- {
- // we have found the flag that indicates that this is an iframe
- // exit the for loop
- iFrame = true;
- break;
- }
- }
- file.seek(pos);
- return iFrame;
- }
- public static void main(String[] args) throws IOException
- {
- String filename = args[0]; // only argument should be the filename of the video
- // get user input for various parameters
- JTextField endBeginTxtFld = new JTextField(); // end of beginning unchanged area
- JTextField startTxtFld = new JTextField(); // start of changed area
- JTextField endTxtFld = new JTextField(); // end of changed area
- JTextField repeatTxtFld = new JTextField(); // number of times to repeat each frame
- JTextField totalRepTxtFld = new JTextField(); // number of times to repeat whole change area
- Object[] message = {"end of beginning: ", endBeginTxtFld,
- "start frame: ", startTxtFld,
- "end frame: ", endTxtFld,
- "number of times to repeat each frame: ", repeatTxtFld,
- "number of times to repeat total frame area: ", totalRepTxtFld};
- JOptionPane.showConfirmDialog(null, message, "Enter Specified Values", JOptionPane.OK_OPTION);
- // get strings for each of the inputs
- String endBegStr = endBeginTxtFld.getText();
- String startStr = startTxtFld.getText();
- String endStr = endTxtFld.getText();
- String repeatStr = repeatTxtFld.getText();
- String totalRepStr = totalRepTxtFld.getText();
- // get usable integer values from above strings
- int endBegin = Integer.parseInt(endBegStr);
- int start = Integer.parseInt(startStr);
- int end = Integer.parseInt(endStr);
- int repeat = Integer.parseInt(repeatStr);
- int totalRep = Integer.parseInt(totalRepStr);
- F_BYTES[0] = 48; // decimal equivalent of 30 in hex
- F_BYTES[1] = 48; // decimal equivalent of 30 in hex
- F_BYTES[2] = 100; // decimal equivalent of 64 in hex
- F_BYTES[3] = 99; // decimal equivalent of 63 in hex
- I_BYTES[0] = 0; // decimal equivalent of 00 in hex
- I_BYTES[1] = 1; // decimal equivalent of 01 in hex
- I_BYTES[2] = 176; // decimal equivalent of B0 in hex
- I_BYTES[3] = 1; // decimal equivalent of 01 in hex
- RandomAccessFile file = new RandomAccessFile(filename + ".avi", "rw");
- // skip some initial frames otherwise video just changes from green
- int frames = 0;
- long current = nextFrame(file, 0);
- System.out.println("finding beginning");
- while(frames < endBegin)
- {
- current = nextFrame(file, current + 1);
- frames++; // found another frame, increment count
- //System.out.println(frames + " / " + copyBegin);
- }
- FileOutputStream newFile = new FileOutputStream(filename + "_0.avi" ,true);
- file.seek(0);
- System.out.println("copying beginning");
- // copy beginning of file until moved past startOffSet number of frames
- while(file.getFilePointer() < current)
- {
- newFile.write(file.readByte());
- }
- System.out.println("skipping from beginning to repeat area");
- // go through these frames but dont read them over
- while(frames < start)
- {
- current = nextFrame(file, current + 1);
- frames++; // found another frame, increment count
- //System.out.println(frames + " / " + start);
- }
- long currFrame = nextFrame(file, file.getFilePointer());
- long nextFrame;
- long startFrame = currFrame;
- // need to loop through file and copy over bytes unless we are in an iframe
- System.out.println("copying repeat area");
- for(int j = 0; j < totalRep; j++)
- {
- file.seek(startFrame);
- currFrame = startFrame;
- nextFrame = nextFrame(file, currFrame + 1);
- int frameCount = start;
- while(file.getFilePointer() < file.length() && frameCount < end)
- {
- if(nextFrame == -1)
- {
- // there is no next frame, just copy the rest
- while(file.getFilePointer() < file.length())
- {
- newFile.write(file.readByte());
- }
- }
- // if next frame is iFrame and we want to delete them, skip past it
- else if(isIFrame(file, currFrame))
- {
- //System.out.println("skipped iFrame");
- // skip to next frame
- file.seek(nextFrame);
- }
- // if not iFrame then we want to copy it
- else
- {
- for(int i = 0; i < repeat; i++)
- {
- while(file.getFilePointer() < nextFrame)
- {
- newFile.write(file.readByte());
- }
- file.seek(currFrame);
- }
- }
- // nextFrame is now the current frame
- currFrame = nextFrame;
- nextFrame = nextFrame(file, file.getFilePointer() + 1);
- frameCount++;
- //System.out.println(frameCount + " / " + end);
- newFile.flush();
- //System.out.println(file.getFilePointer() + " / " + file.length());
- }
- System.out.println("repeat: " + j);
- }
- System.out.println("copying end");
- while(file.getFilePointer() < file.length())
- {
- //copy rest of the file after 'end'
- nextFrame = nextFrame(file, file.getFilePointer() + 1);
- if(nextFrame == -1)
- {
- // there is no next frame, just copy the rest
- while(file.getFilePointer() < file.length())
- {
- newFile.write(file.readByte());
- }
- }
- // if next frame is iFrame and we want to delete them, skip past it
- else if(isIFrame(file, currFrame))
- {
- //System.out.println("skipped iFrame");
- // skip to next frame
- file.seek(nextFrame);
- }
- // if not iFrame or we want to keep iFrames then copy it
- else
- {
- while(file.getFilePointer() < nextFrame)
- {
- newFile.write(file.readByte());
- }
- file.seek(currFrame);
- }
- currFrame = nextFrame;
- nextFrame = nextFrame(file, file.getFilePointer() + 1);
- newFile.flush();
- }
- System.out.println("done");
- newFile.close();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement