Browse Source

Finish video cutting code.

Start to implement copy and vp9 tabs.
master
BuildTools 1 year ago
parent
commit
373f436a0b
  1. 52
      src/main/java/lt/haruki/ffmpeg_gui/MainFrame.form
  2. 220
      src/main/java/lt/haruki/ffmpeg_gui/MainFrame.java

52
src/main/java/lt/haruki/ffmpeg_gui/MainFrame.form

@ -31,8 +31,10 @@
<Component id="jPanel8" max="32767" attributes="0"/>
<Component id="jTabbedPane1" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="jProgressBar1" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jProgressBar1" min="-2" pref="503" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="jButton3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="jButton2" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
@ -116,7 +118,10 @@
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jProgressBar1" max="32767" attributes="0"/>
<Component id="jButton2" pref="25" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jButton2" alignment="3" pref="25" max="32767" attributes="0"/>
<Component id="jButton3" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -629,15 +634,15 @@
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel20" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jTextField1" min="-2" pref="80" max="-2" attributes="0"/>
<Component id="jSpinner1" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="jLabel21" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jTextField2" min="-2" pref="80" max="-2" attributes="0"/>
<Component id="jSpinner2" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="jLabel22" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jTextField3" min="-2" pref="80" max="-2" attributes="0"/>
<Component id="jSpinner3" min="-2" pref="80" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -651,11 +656,11 @@
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel20" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel21" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jTextField2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel22" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jTextField3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jSpinner1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jSpinner2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jSpinner3" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="68" max="32767" attributes="0"/>
</Group>
@ -668,31 +673,16 @@
<Property name="text" type="java.lang.String" value="Start time:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="jTextField1">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel21">
<Properties>
<Property name="text" type="java.lang.String" value="End time:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="jTextField2">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel22">
<Properties>
<Property name="text" type="java.lang.String" value="Duration:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="jTextField3">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel23">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
@ -701,6 +691,12 @@
<Property name="text" type="java.lang.String" value="(!Soon) Cut Video (optional)"/>
</Properties>
</Component>
<Component class="javax.swing.JSpinner" name="jSpinner1">
</Component>
<Component class="javax.swing.JSpinner" name="jSpinner2">
</Component>
<Component class="javax.swing.JSpinner" name="jSpinner3">
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="jLabel24">
@ -711,5 +707,13 @@
<Property name="text" type="java.lang.String" value="Video Re-encoding"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="jButton3">
<Properties>
<Property name="text" type="java.lang.String" value="TEST"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton3ActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

220
src/main/java/lt/haruki/ffmpeg_gui/MainFrame.java

@ -4,10 +4,14 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.DateFormatter;
public class MainFrame extends javax.swing.JFrame {
@ -115,13 +119,14 @@ public class MainFrame extends javax.swing.JFrame {
jLabel2 = new javax.swing.JLabel();
jPanel8 = new javax.swing.JPanel();
jLabel20 = new javax.swing.JLabel();
jTextField1 = new javax.swing.JTextField();
jLabel21 = new javax.swing.JLabel();
jTextField2 = new javax.swing.JTextField();
jLabel22 = new javax.swing.JLabel();
jTextField3 = new javax.swing.JTextField();
jLabel23 = new javax.swing.JLabel();
jSpinner1 = new javax.swing.JSpinner();
jSpinner2 = new javax.swing.JSpinner();
jSpinner3 = new javax.swing.JSpinner();
jLabel24 = new javax.swing.JLabel();
jButton3 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Lucy's FFMPEG GUI v0.0.1");
@ -377,16 +382,10 @@ public class MainFrame extends javax.swing.JFrame {
jLabel20.setText("Start time:");
jTextField1.setEnabled(false);
jLabel21.setText("End time:");
jTextField2.setEnabled(false);
jLabel22.setText("Duration:");
jTextField3.setEnabled(false);
jLabel23.setFont(new java.awt.Font("Segoe UI", 1, 14)); // NOI18N
jLabel23.setText("(!Soon) Cut Video (optional)");
@ -401,15 +400,15 @@ public class MainFrame extends javax.swing.JFrame {
.addGroup(jPanel8Layout.createSequentialGroup()
.addComponent(jLabel20)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jLabel21)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSpinner2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jLabel22)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(jSpinner3, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 0, Short.MAX_VALUE))
);
jPanel8Layout.setVerticalGroup(
@ -419,17 +418,24 @@ public class MainFrame extends javax.swing.JFrame {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel20)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel21)
.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel22)
.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSpinner2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSpinner3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(68, Short.MAX_VALUE))
);
jLabel24.setFont(new java.awt.Font("Segoe UI", 1, 14)); // NOI18N
jLabel24.setText("Video Re-encoding");
jButton3.setText("TEST");
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
@ -440,8 +446,10 @@ public class MainFrame extends javax.swing.JFrame {
.addComponent(jPanel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 503, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jButton3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton2))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -513,7 +521,9 @@ public class MainFrame extends javax.swing.JFrame {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE)
.addComponent(jButton3)))
.addContainerGap())
);
@ -530,21 +540,6 @@ public class MainFrame extends javax.swing.JFrame {
//Create a file chooser
//In response to a button click:
fc.setFileFilter(new FileFilter() {
public String getDescription() {
return "Video to encode: (*.mp4/mkv/avi)";
}
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
} else {
String filename = f.getName().toLowerCase();
return filename.endsWith(".mp4") || filename.endsWith(".mkv") || filename.endsWith(".avi") ;
}
}
});
fc.showOpenDialog(null);
if(fc.getSelectedFile() != null) {
fileName = fc.getSelectedFile().getAbsolutePath().split("\\.(?=[^\\.]+$)")[0];
@ -553,23 +548,83 @@ public class MainFrame extends javax.swing.JFrame {
}
}//GEN-LAST:event_jButton1ActionPerformed
private String copy(String timeStart, String timeEnd, String timeDuration) {
String cmd = String.format("ffmpeg -y -i \"%s\" -ss %s -to %s -t %s -c copy \"%s_copy.%s\"",
(fileName + "." + fileExt), timeStart, timeEnd, timeDuration, fileName, fileExt);
return cmd;
}
private String x264(String timeStart, String timeEnd, String timeDuration) {
String cmd = String.format("ffmpeg -y -i \"%s\" -ss %s -to %s -t %s -c:v libx264 -preset %s -crf %d -tune %s -profile:v %s -movflags +faststart \"%s_x264_%s_%s.%s\"",
(fileName + "." + fileExt), timeStart, timeEnd, timeDuration, jComboBox1.getSelectedItem(), jSlider1.getValue(), jComboBox2.getSelectedItem(),
jComboBox3.getSelectedItem(), fileName, jSlider1.getValue(), jComboBox1.getSelectedItem(), fileExt);
if(jCheckBox1.isSelected()) cmd = cmd.replaceFirst("-c:v libx264", "-c:v libx264rgb").replaceAll("_x264", "_x264rgb");
if(jComboBox2.getSelectedItem().equals("none")) cmd = cmd.replaceAll("-tune \\w+ ", "");
if(!jCheckBox2.isSelected()) cmd = cmd.replaceAll("-movflags +faststart ", "");
return cmd;
}
/* NOT IMPLEMENTED */
private String x265(String timeStart, String timeEnd, String timeDuration) {
return "";
}
private String vp8(String timeStart, String timeEnd, String timeDuration) {
return "";
}
private String vp9(String timeStart, String timeEnd, String timeDuration) {
return "";
}
private String webm(String timeStart, String timeEnd, String timeDuration) {
return "";
}
private String av1(String timeStart, String timeEnd, String timeDuration) {
return "";
}
private String vvc(String timeStart, String timeEnd, String timeDuration) {
return "";
}
/* NOT IMPLEMENTED */
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
if(jLabel2.getText().equals("<none>")) { return; }
new Thread(() -> {
String cmd;
jButton2.setEnabled(false);
jProgressBar1.setIndeterminate(true);
try {
String cmd = String.format("ffmpeg -y -i \"%s\" -c:v libx264 -preset %s -crf %d -tune %s -profile:v %s -movflags +faststart \"%s_x264_%s_%s.%s\"",
(fileName + "." + fileExt), jComboBox1.getSelectedItem(), jSlider1.getValue(), jComboBox2.getSelectedItem(), jComboBox3.getSelectedItem(), fileName, jSlider1.getValue(), jComboBox1.getSelectedItem(), fileExt);
if(jCheckBox1.isSelected()) cmd = cmd.replaceFirst("-c:v libx264", "-c:v libx264rgb").replaceAll("_x264", "_x264rgb");
if(jComboBox2.getSelectedItem().equals("none")) cmd = cmd.replaceAll("-tune \\w+ ", "");
if(!jCheckBox2.isSelected()) cmd = cmd.replaceAll("-movflags +faststart ", "");
String timeStart = jSpinner1.getValue().toString().substring(11, 19);
String timeEnd = jSpinner2.getValue().toString().substring(11, 19);
String timeDuration = jSpinner3.getValue().toString().substring(11, 19);
switch(jTabbedPane1.getSelectedIndex()) {
case 0 : { cmd = copy(timeStart, timeEnd, timeDuration); break; }
case 1 : { cmd = x264(timeStart, timeEnd, timeDuration); break; }
case 2 : { cmd = x265(timeStart, timeEnd, timeDuration); break; }
case 3 : { cmd = vp8(timeStart, timeEnd, timeDuration); break; }
case 4 : { cmd = vp9(timeStart, timeEnd, timeDuration); break; }
case 5 : { cmd = webm(timeStart, timeEnd, timeDuration); break; }
case 6 : { cmd = av1(timeStart, timeEnd, timeDuration); break; }
case 7 : { cmd = vvc(timeStart, timeEnd, timeDuration); break; }
default: return;
}
if(timeEnd.equals("00:00:00"))
cmd = cmd.replaceAll("-to \\d\\d:\\d\\d:\\d\\d ", "");
if(timeDuration.equals("00:00:00"))
cmd = cmd.replaceAll("-t \\d\\d:\\d\\d:\\d\\d ", "");
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", cmd);
System.out.println("Command: " + cmd);
Process proc = pb.start();
CustomOutputStream guiOutput = new CustomOutputStream();
CustomOutputStream guiOutputErr = new CustomOutputStream();
PipeStream out = new PipeStream(proc.getInputStream(), guiOutput);
PipeStream err = new PipeStream(proc.getErrorStream(), System.err);
@ -582,7 +637,7 @@ public class MainFrame extends javax.swing.JFrame {
System.out.println("Done!");
jProgressBar1.setIndeterminate(false);
jButton2.setEnabled(true);
} catch (Exception e) {
} catch (IOException | InterruptedException e) {
System.err.println(e);
}
}).start();
@ -598,6 +653,10 @@ public class MainFrame extends javax.swing.JFrame {
}
}//GEN-LAST:event_jCheckBox1StateChanged
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
}//GEN-LAST:event_jButton3ActionPerformed
public static MainFrame getInstance() {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
@ -617,6 +676,80 @@ public class MainFrame extends javax.swing.JFrame {
}
private void setup() {
fc.setCurrentDirectory(new File(
System.getProperty("user.home") + System.getProperty("file.separator")+ "Videos")
);
fc.setFileFilter(new FileFilter() {
public String getDescription() {
return "Video to encode: (*.mp4/mkv/avi)";
}
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
} else {
String filename = f.getName().toLowerCase();
return filename.endsWith(".mp4") || filename.endsWith(".mkv") || filename.endsWith(".avi") ;
}
}
});
//FOR CUTTING VIDEO
Calendar calendar1 = Calendar.getInstance();
calendar1.set(Calendar.HOUR_OF_DAY, 24); // 24 == 12 PM == 00:00:00
calendar1.set(Calendar.MINUTE, 0);
calendar1.set(Calendar.SECOND, 0);
Calendar calendar2 = Calendar.getInstance();
calendar2.set(Calendar.HOUR_OF_DAY, 24); // 24 == 12 PM == 00:00:00
calendar2.set(Calendar.MINUTE, 0);
calendar2.set(Calendar.SECOND, 0);
Calendar calendar3 = Calendar.getInstance();
calendar3.set(Calendar.HOUR_OF_DAY, 24); // 24 == 12 PM == 00:00:00
calendar3.set(Calendar.MINUTE, 0);
calendar3.set(Calendar.SECOND, 0);
SpinnerDateModel model1 = new SpinnerDateModel();
SpinnerDateModel model2 = new SpinnerDateModel();
SpinnerDateModel model3 = new SpinnerDateModel();
model1.setValue(calendar1.getTime());
model2.setValue(calendar1.getTime());
model3.setValue(calendar1.getTime());
jSpinner1.setModel(model1);
jSpinner2.setModel(model2);
jSpinner3.setModel(model3);
JSpinner.DateEditor editor1 = new JSpinner.DateEditor(jSpinner1, "HH:mm:ss");
DateFormatter formatter1 = (DateFormatter)editor1.getTextField().getFormatter();
formatter1.setAllowsInvalid(false);
formatter1.setOverwriteMode(true);
JSpinner.DateEditor editor2 = new JSpinner.DateEditor(jSpinner2, "HH:mm:ss");
DateFormatter formatter2 = (DateFormatter)editor2.getTextField().getFormatter();
formatter2.setAllowsInvalid(false);
formatter2.setOverwriteMode(true);
JSpinner.DateEditor editor3 = new JSpinner.DateEditor(jSpinner3, "HH:mm:ss");
DateFormatter formatter3 = (DateFormatter)editor3.getTextField().getFormatter();
formatter3.setAllowsInvalid(false);
formatter3.setOverwriteMode(true);
jSpinner1.setEditor(editor1);
jSpinner2.setEditor(editor2);
jSpinner3.setEditor(editor3);
jTabbedPane1.setEnabledAt(2, false);
jTabbedPane1.setEnabledAt(3, false);
jTabbedPane1.setEnabledAt(4, true);
jTabbedPane1.setEnabledAt(5, false);
jTabbedPane1.setEnabledAt(6, false);
jTabbedPane1.setEnabledAt(7, false);
setLocationRelativeTo(null);
setVisible(true);
}
@ -624,6 +757,7 @@ public class MainFrame extends javax.swing.JFrame {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JCheckBox jCheckBox1;
private javax.swing.JCheckBox jCheckBox2;
private javax.swing.JCheckBox jCheckBox3;
@ -665,10 +799,10 @@ public class MainFrame extends javax.swing.JFrame {
private javax.swing.JPanel jPanel9;
private javax.swing.JProgressBar jProgressBar1;
private javax.swing.JSlider jSlider1;
private javax.swing.JSpinner jSpinner1;
private javax.swing.JSpinner jSpinner2;
private javax.swing.JSpinner jSpinner3;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
// End of variables declaration//GEN-END:variables
// </editor-fold>
}
Loading…
Cancel
Save