Added Support for custom ffmpeg Command Line Arguments when Rendering a Video | https://trello.com/c/69CNoWuA/

This commit is contained in:
CrushedPixel
2015-07-01 13:28:41 +02:00
parent c34ec09e6b
commit a189868390
5 changed files with 63 additions and 26 deletions

View File

@@ -88,7 +88,6 @@ public class GuiConstants {
public static final int RENDER_SETTINGS_FORCECHUNKS_BUTTON = 9008; public static final int RENDER_SETTINGS_FORCECHUNKS_BUTTON = 9008;
public static final int RENDER_SETTINGS_FRAMERATE_SLIDER = 9009; public static final int RENDER_SETTINGS_FRAMERATE_SLIDER = 9009;
public static final int RENDER_SETTINGS_BITRATE_INPUT = 9010; public static final int RENDER_SETTINGS_BITRATE_INPUT = 9010;
public static final int RENDER_SETTINGS_YOUTUBE_READY = 9011;
public static final int RENDER_SETTINGS_STATIC_CAMERA = 9012; public static final int RENDER_SETTINGS_STATIC_CAMERA = 9012;
public static final int RENDER_SETTINGS_ADVANCED_BUTTON = 9013; public static final int RENDER_SETTINGS_ADVANCED_BUTTON = 9013;
public static final int RENDER_SETTINGS_COLOR_PICKER = 9014; public static final int RENDER_SETTINGS_COLOR_PICKER = 9014;

View File

@@ -1,13 +1,11 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.gui.elements.GuiColorPicker; import eu.crushedpixel.replaymod.gui.elements.*;
import eu.crushedpixel.replaymod.gui.elements.GuiDropdown;
import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput;
import eu.crushedpixel.replaymod.gui.elements.GuiToggleButton;
import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.settings.RenderOptions; import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.utils.StringUtils;
import eu.crushedpixel.replaymod.video.frame.*; import eu.crushedpixel.replaymod.video.frame.*;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
@@ -35,6 +33,7 @@ public class GuiRenderSettings extends GuiScreen {
private GuiVideoFramerateSlider framerateSlider; private GuiVideoFramerateSlider framerateSlider;
private GuiNumberInput bitrateInput; private GuiNumberInput bitrateInput;
private GuiColorPicker colorPicker; private GuiColorPicker colorPicker;
private GuiAdvancedTextField ffmpegArguments;
private List<GuiButton> permanentButtons = new ArrayList<GuiButton>(); private List<GuiButton> permanentButtons = new ArrayList<GuiButton>();
private List<GuiButton> defaultButtons = new ArrayList<GuiButton>(); private List<GuiButton> defaultButtons = new ArrayList<GuiButton>();
@@ -143,6 +142,10 @@ public class GuiRenderSettings extends GuiScreen {
colorPicker = new GuiColorPicker(GuiConstants.RENDER_SETTINGS_COLOR_PICKER, 0, 0, I18n.format("replaymod.gui.rendersettings.skycolor")+": ", 0, 0); colorPicker = new GuiColorPicker(GuiConstants.RENDER_SETTINGS_COLOR_PICKER, 0, 0, I18n.format("replaymod.gui.rendersettings.skycolor")+": ", 0, 0);
colorPicker.enabled = enableGreenscreen.isChecked(); colorPicker.enabled = enableGreenscreen.isChecked();
ffmpegArguments = new GuiAdvancedTextField(fontRendererObj, 0, 0, 50, 20);
ffmpegArguments.hint = I18n.format("replaymod.gui.rendersettings.ffmpeghint");
ffmpegArguments.setMaxStringLength(3200);
ignoreCamDir = new GuiCheckBox(GuiConstants.RENDER_SETTINGS_STATIC_CAMERA, 0, 0, I18n.format("replaymod.gui.rendersettings.stablecamera"), false); ignoreCamDir = new GuiCheckBox(GuiConstants.RENDER_SETTINGS_STATIC_CAMERA, 0, 0, I18n.format("replaymod.gui.rendersettings.stablecamera"), false);
ignoreCamDir.enabled = false; ignoreCamDir.enabled = false;
@@ -224,6 +227,10 @@ public class GuiRenderSettings extends GuiScreen {
i++; i++;
} }
ffmpegArguments.width = 305;
ffmpegArguments.xPosition = (this.width-ffmpegArguments.width)/2;
ffmpegArguments.yPosition = this.virtualY + 20 + ((i/2)*25);
initialized = true; initialized = true;
} }
@@ -259,15 +266,28 @@ public class GuiRenderSettings extends GuiScreen {
this.drawString(fontRendererObj, bitrateString, forceChunks.xPosition, bitrateInput.yPosition + 6, Color.WHITE.getRGB()); this.drawString(fontRendererObj, bitrateString, forceChunks.xPosition, bitrateInput.yPosition + 6, Color.WHITE.getRGB());
rendererDropdown.drawTextBox(); rendererDropdown.drawTextBox();
} else {
ffmpegArguments.drawTextBox();
String[] rows = StringUtils.splitStringInMultipleRows(I18n.format("replaymod.gui.rendersettings.ffmpeg.description"), 305);
int i = 0;
for(String row : rows) {
drawString(fontRendererObj, row, ffmpegArguments.xPosition, ffmpegArguments.yPosition + 30 + (15 * i), Color.WHITE.getRGB());
i++;
}
} }
} }
@Override @Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
if(!rendererDropdown.mouseClickedResult(mouseX, mouseY)) { if(!rendererDropdown.mouseClickedResult(mouseX, mouseY)) {
xRes.mouseClicked(mouseX, mouseY, mouseButton); if(!advancedTab) {
yRes.mouseClicked(mouseX, mouseY, mouseButton); xRes.mouseClicked(mouseX, mouseY, mouseButton);
bitrateInput.mouseClicked(mouseX, mouseY, mouseButton); yRes.mouseClicked(mouseX, mouseY, mouseButton);
bitrateInput.mouseClicked(mouseX, mouseY, mouseButton);
} else {
ffmpegArguments.mouseClicked(mouseX, mouseY, mouseButton);
}
if(mouseButton == 0) { if(mouseButton == 0) {
List<GuiButton> toHandle = new ArrayList<GuiButton>(); List<GuiButton> toHandle = new ArrayList<GuiButton>();
@@ -298,20 +318,23 @@ public class GuiRenderSettings extends GuiScreen {
@Override @Override
protected void keyTyped(char typedChar, int keyCode) throws IOException { protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(keyCode == Keyboard.KEY_TAB) { if(!advancedTab) {
if(xRes.isFocused() && customResolution.isChecked()) { if(keyCode == Keyboard.KEY_TAB) {
xRes.setFocused(false); if(xRes.isFocused() && customResolution.isChecked()) {
yRes.setFocused(true); xRes.setFocused(false);
yRes.setFocused(true);
} else if(yRes.isFocused() && customResolution.isChecked()) {
yRes.setFocused(false);
xRes.setFocused(true);
}
return;
} }
else if(yRes.isFocused() && customResolution.isChecked()) { xRes.textboxKeyTyped(typedChar, keyCode);
yRes.setFocused(false); yRes.textboxKeyTyped(typedChar, keyCode);
xRes.setFocused(true); bitrateInput.textboxKeyTyped(typedChar, keyCode);
} } else {
return; ffmpegArguments.textboxKeyTyped(typedChar, keyCode);
} }
xRes.textboxKeyTyped(typedChar, keyCode);
yRes.textboxKeyTyped(typedChar, keyCode);
bitrateInput.textboxKeyTyped(typedChar, keyCode);
super.keyTyped(typedChar, keyCode); super.keyTyped(typedChar, keyCode);
} }
@@ -320,6 +343,7 @@ public class GuiRenderSettings extends GuiScreen {
xRes.updateCursorCounter(); xRes.updateCursorCounter();
yRes.updateCursorCounter(); yRes.updateCursorCounter();
bitrateInput.updateCursorCounter(); bitrateInput.updateCursorCounter();
ffmpegArguments.updateCursorCounter();
super.updateScreen(); super.updateScreen();
} }
@@ -424,6 +448,10 @@ public class GuiRenderSettings extends GuiScreen {
} }
options.setRenderer(renderer); options.setRenderer(renderer);
if(ffmpegArguments.getText().trim().length() > 0) {
options.setCommandLineArguments(ffmpegArguments.getText());
}
ReplayHandler.startPath(options); ReplayHandler.startPath(options);
} }

View File

@@ -11,6 +11,7 @@ public final class RenderOptions {
private FrameRenderer renderer; private FrameRenderer renderer;
private String bitrate = "10M"; private String bitrate = "10M";
private int fps = 30; private int fps = 30;
private String commandLineArguments = null;
// Advanced // Advanced
private boolean waitForChunks = true; private boolean waitForChunks = true;

View File

@@ -59,12 +59,18 @@ public class VideoWriter {
File folder = ReplayFileIO.getRenderFolder(); File folder = ReplayFileIO.getRenderFolder();
String fileName = FILE_FORMAT.format(Calendar.getInstance().getTime()); String fileName = FILE_FORMAT.format(Calendar.getInstance().getTime());
final String args = options.getExportCommandArgs() final String args;
.replace("%WIDTH%", String.valueOf(options.getWidth()))
.replace("%HEIGHT%", String.valueOf(options.getHeight())) if(options.getCommandLineArguments() != null) {
.replace("%FPS%", String.valueOf(options.getFps())) args = options.getCommandLineArguments();
.replace("%FILENAME%", fileName) } else {
.replace("%BITRATE%", options.getBitrate()); args = options.getExportCommandArgs()
.replace("%WIDTH%", String.valueOf(options.getWidth()))
.replace("%HEIGHT%", String.valueOf(options.getHeight()))
.replace("%FPS%", String.valueOf(options.getFps()))
.replace("%FILENAME%", fileName)
.replace("%BITRATE%", options.getBitrate());
}
List<String> command = new ArrayList<String>(); List<String> command = new ArrayList<String>();
command.add(options.getExportCommand()); command.add(options.getExportCommand());

View File

@@ -286,6 +286,9 @@ replaymod.gui.rendersettings.quality=Video Quality
replaymod.gui.rendersettings.chromakey=Chroma Keying replaymod.gui.rendersettings.chromakey=Chroma Keying
replaymod.gui.rendersettings.skycolor=Sky Color replaymod.gui.rendersettings.skycolor=Sky Color
replaymod.gui.rendersettings.ffmpeghint=ffmpeg Command Line Arguments
replaymod.gui.rendersettings.ffmpeg.description=If you define custom Command Line Arguments for ffmpeg, they will replace the Replay Mod's Render Settings (File Destination, Codec, Bitrate, Framerate etc.)
replaymod.gui.rendersettings.stablecamera=Ignore Camera Rotation replaymod.gui.rendersettings.stablecamera=Ignore Camera Rotation
replaymod.gui.rendersettings.exportyoutube=Export for YouTube replaymod.gui.rendersettings.exportyoutube=Export for YouTube