Added Support for custom ffmpeg Command Line Arguments when Rendering a Video | https://trello.com/c/69CNoWuA/
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user