forked from j62/ctbrec
Add dialog to specify media player params in the settings
This commit is contained in:
parent
6f57579041
commit
ff9ff8f40f
|
@ -1,6 +1,8 @@
|
||||||
3.4.1
|
3.4.1
|
||||||
========================
|
========================
|
||||||
* Filter terms can now be negated by prepending them with a "!"
|
* Filter terms can now be negated by prepending them with a "!"
|
||||||
|
* Added pinning for recordings. Pinned recordings cannot be deleted
|
||||||
|
* Added possibility to specify media player parameters
|
||||||
|
|
||||||
3.4.0
|
3.4.0
|
||||||
========================
|
========================
|
||||||
|
|
|
@ -127,14 +127,15 @@ public class Player {
|
||||||
try {
|
try {
|
||||||
if (cfg.getSettings().localRecording && rec != null) {
|
if (cfg.getSettings().localRecording && rec != null) {
|
||||||
File file = new File(cfg.getSettings().recordingsDir, rec.getPath());
|
File file = new File(cfg.getSettings().recordingsDir, rec.getPath());
|
||||||
String[] args = new String[] { cfg.getSettings().mediaPlayer, file.getName() };
|
String[] cmdline = createCmdline(file.getName());
|
||||||
playerProcess = rt.exec(args, OS.getEnvironment(), file.getParentFile());
|
playerProcess = rt.exec(cmdline, OS.getEnvironment(), file.getParentFile());
|
||||||
} else {
|
} else {
|
||||||
if (rec != null) {
|
if (rec != null) {
|
||||||
url = getRemoteRecordingUrl(rec, cfg);
|
url = getRemoteRecordingUrl(rec, cfg);
|
||||||
}
|
}
|
||||||
LOG.debug("Playing {}", url);
|
LOG.debug("Playing {}", url);
|
||||||
playerProcess = rt.exec(cfg.getSettings().mediaPlayer + " " + url);
|
String[] cmdline = createCmdline(url);
|
||||||
|
playerProcess = rt.exec(cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create threads, which read stdout and stderr of the player process. these are needed,
|
// create threads, which read stdout and stderr of the player process. these are needed,
|
||||||
|
@ -159,6 +160,16 @@ public class Player {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String[] createCmdline(String mediaSource) {
|
||||||
|
Config cfg = Config.getInstance();
|
||||||
|
String[] playerArgs = cfg.getSettings().mediaPlayerParams.trim().split(" ");
|
||||||
|
String[] cmdline = new String[playerArgs.length + 2];
|
||||||
|
cmdline[0] = cfg.getSettings().mediaPlayer;
|
||||||
|
cmdline[cmdline.length - 1] = mediaSource;
|
||||||
|
System.arraycopy(playerArgs, 0, cmdline, 1, playerArgs.length);
|
||||||
|
return cmdline;
|
||||||
|
}
|
||||||
|
|
||||||
private String getRemoteRecordingUrl(Recording rec, Config cfg)
|
private String getRemoteRecordingUrl(Recording rec, Config cfg)
|
||||||
throws MalformedURLException, InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws MalformedURLException, InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
String hlsBase = Config.getInstance().getServerUrl() + "/hls";
|
String hlsBase = Config.getInstance().getServerUrl() + "/hls";
|
||||||
|
|
|
@ -28,19 +28,9 @@ import javafx.scene.paint.Color;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
|
|
||||||
public abstract class AbstractFileSelectionBox extends HBox {
|
public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
private static final transient Logger LOG = LoggerFactory.getLogger(AbstractFileSelectionBox.class);
|
|
||||||
|
|
||||||
// private ObjectProperty<File> fileProperty = new ObjectPropertyBase<File>() {
|
private static final Logger LOG = LoggerFactory.getLogger(AbstractFileSelectionBox.class);
|
||||||
// @Override
|
|
||||||
// public Object getBean() {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public String getName() {
|
|
||||||
// return "file";
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
private StringProperty fileProperty = new SimpleStringProperty();
|
private StringProperty fileProperty = new SimpleStringProperty();
|
||||||
protected TextField fileInput;
|
protected TextField fileInput;
|
||||||
protected boolean allowEmptyValue = false;
|
protected boolean allowEmptyValue = false;
|
||||||
|
@ -51,7 +41,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
fileInput = new TextField();
|
fileInput = new TextField();
|
||||||
fileInput.textProperty().addListener(textListener());
|
fileInput.textProperty().addListener(textListener());
|
||||||
fileInput.focusedProperty().addListener((obs, o, n) -> {
|
fileInput.focusedProperty().addListener((obs, o, n) -> {
|
||||||
if(!n) {
|
if (!n.booleanValue()) {
|
||||||
validationError.hide();
|
validationError.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -62,7 +52,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
HBox.setHgrow(fileInput, Priority.ALWAYS);
|
HBox.setHgrow(fileInput, Priority.ALWAYS);
|
||||||
|
|
||||||
disabledProperty().addListener((obs, oldV, newV) -> {
|
disabledProperty().addListener((obs, oldV, newV) -> {
|
||||||
if (newV) {
|
if (newV.booleanValue()) {
|
||||||
hideValidationHints();
|
hideValidationHints();
|
||||||
} else {
|
} else {
|
||||||
if (StringUtil.isNotBlank(fileInput.getText())) {
|
if (StringUtil.isNotBlank(fileInput.getText())) {
|
||||||
|
@ -80,7 +70,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
private ChangeListener<? super String> textListener() {
|
private ChangeListener<? super String> textListener() {
|
||||||
return (obs, o, n) -> {
|
return (obs, o, n) -> {
|
||||||
String input = fileInput.getText();
|
String input = fileInput.getText();
|
||||||
if(StringUtil.isBlank(input) && allowEmptyValue) {
|
if (StringUtil.isBlank(input) && allowEmptyValue) {
|
||||||
fileProperty.set("");
|
fileProperty.set("");
|
||||||
hideValidationHints();
|
hideValidationHints();
|
||||||
return;
|
return;
|
||||||
|
@ -98,7 +88,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
validationError.setText(msg);
|
validationError.setText(msg);
|
||||||
fileInput.setTooltip(validationError);
|
fileInput.setTooltip(validationError);
|
||||||
Point2D p = fileInput.localToScreen(fileInput.getTranslateY(), fileInput.getTranslateY());
|
Point2D p = fileInput.localToScreen(fileInput.getTranslateY(), fileInput.getTranslateY());
|
||||||
if(!validationError.isShowing() && getScene() != null) {
|
if (!validationError.isShowing() && getScene() != null) {
|
||||||
validationError.show(getScene().getWindow(), p.getX(), p.getY() + fileInput.getHeight() + 4);
|
validationError.show(getScene().getWindow(), p.getX(), p.getY() + fileInput.getHeight() + 4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -114,7 +104,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String validate(File file) {
|
protected String validate(File file) {
|
||||||
if(isDisabled()) {
|
if (isDisabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,16 +121,14 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
|
|
||||||
private Button createBrowseButton() {
|
private Button createBrowseButton() {
|
||||||
Button button = new Button("Select");
|
Button button = new Button("Select");
|
||||||
button.setOnAction((e) -> {
|
button.setOnAction(e -> choose());
|
||||||
choose();
|
|
||||||
});
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void choose() {
|
protected void choose() {
|
||||||
FileChooser chooser = new FileChooser();
|
FileChooser chooser = new FileChooser();
|
||||||
File program = chooser.showOpenDialog(null);
|
File program = chooser.showOpenDialog(null);
|
||||||
if(program != null) {
|
if (program != null) {
|
||||||
try {
|
try {
|
||||||
fileInput.setText(program.getCanonicalPath());
|
fileInput.setText(program.getCanonicalPath());
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
|
|
|
@ -20,6 +20,8 @@ import javafx.stage.Modality;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class Dialogs {
|
public class Dialogs {
|
||||||
|
|
||||||
|
private Dialogs() {}
|
||||||
// TODO reduce calls to this method and use Dialogs.showError(Scene parent, String header, String text, Throwable t) instead
|
// TODO reduce calls to this method and use Dialogs.showError(Scene parent, String header, String text, Throwable t) instead
|
||||||
public static void showError(String header, String text, Throwable t) {
|
public static void showError(String header, String text, Throwable t) {
|
||||||
showError(null, header, text, t);
|
showError(null, header, text, t);
|
||||||
|
@ -73,7 +75,7 @@ public class Dialogs {
|
||||||
grid.add(notes, 0, 0);
|
grid.add(notes, 0, 0);
|
||||||
dialog.getDialogPane().setContent(grid);
|
dialog.getDialogPane().setContent(grid);
|
||||||
|
|
||||||
Platform.runLater(() -> notes.requestFocus());
|
Platform.runLater(notes::requestFocus);
|
||||||
|
|
||||||
dialog.setResultConverter(dialogButton -> {
|
dialog.setResultConverter(dialogButton -> {
|
||||||
if (dialogButton == ButtonType.OK) {
|
if (dialogButton == ButtonType.OK) {
|
||||||
|
|
|
@ -4,10 +4,11 @@ import ctbrec.Config;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ColorPicker;
|
import javafx.scene.control.ColorPicker;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
|
||||||
public class ColorSettingsPane extends Pane {
|
public class ColorSettingsPane extends HBox {
|
||||||
|
|
||||||
ColorPicker baseColor = new ColorPicker();
|
ColorPicker baseColor = new ColorPicker();
|
||||||
ColorPicker accentColor = new ColorPicker();
|
ColorPicker accentColor = new ColorPicker();
|
||||||
|
@ -15,14 +16,18 @@ public class ColorSettingsPane extends Pane {
|
||||||
Pane foobar = new Pane();
|
Pane foobar = new Pane();
|
||||||
|
|
||||||
public ColorSettingsPane(SettingsTab settingsTab) {
|
public ColorSettingsPane(SettingsTab settingsTab) {
|
||||||
|
super(5);
|
||||||
getChildren().add(baseColor);
|
getChildren().add(baseColor);
|
||||||
getChildren().add(accentColor);
|
getChildren().add(accentColor);
|
||||||
getChildren().add(reset);
|
getChildren().add(reset);
|
||||||
|
|
||||||
baseColor.setValue(Color.web(Config.getInstance().getSettings().colorBase));
|
baseColor.setValue(Color.web(Config.getInstance().getSettings().colorBase));
|
||||||
baseColor.setTooltip(new Tooltip("Base Color"));
|
baseColor.setTooltip(new Tooltip("Base Color"));
|
||||||
|
baseColor.setMaxSize(44, 25);
|
||||||
accentColor.setValue(Color.web(Config.getInstance().getSettings().colorAccent));
|
accentColor.setValue(Color.web(Config.getInstance().getSettings().colorAccent));
|
||||||
accentColor.setTooltip(new Tooltip("Accent Color"));
|
accentColor.setTooltip(new Tooltip("Accent Color"));
|
||||||
|
accentColor.setMaxSize(44, 25);
|
||||||
|
reset.setMaxSize(60, 25);
|
||||||
|
|
||||||
baseColor.setOnAction(evt -> {
|
baseColor.setOnAction(evt -> {
|
||||||
Config.getInstance().getSettings().colorBase = toWeb(baseColor.getValue());
|
Config.getInstance().getSettings().colorBase = toWeb(baseColor.getValue());
|
||||||
|
@ -63,15 +68,4 @@ public class ColorSettingsPane extends Pane {
|
||||||
sb.append(Integer.toHexString(v));
|
sb.append(Integer.toHexString(v));
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void layoutChildren() {
|
|
||||||
baseColor.resize(44, 25);
|
|
||||||
accentColor.resize(44, 25);
|
|
||||||
reset.resize(60, 25);
|
|
||||||
|
|
||||||
baseColor.setTranslateX(0);
|
|
||||||
accentColor.setTranslateX(baseColor.getTranslateX() + baseColor.getWidth() + 10);
|
|
||||||
reset.setTranslateX(accentColor.getTranslateX() + accentColor.getWidth() + 10);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -24,6 +25,7 @@ import com.squareup.moshi.Types;
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Hmac;
|
import ctbrec.Hmac;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
|
import ctbrec.Settings;
|
||||||
import ctbrec.Settings.DirectoryStructure;
|
import ctbrec.Settings.DirectoryStructure;
|
||||||
import ctbrec.StringUtil;
|
import ctbrec.StringUtil;
|
||||||
import ctbrec.io.ModelJsonAdapter;
|
import ctbrec.io.ModelJsonAdapter;
|
||||||
|
@ -554,23 +556,34 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createGeneralPanel() {
|
private Node createGeneralPanel() {
|
||||||
|
Settings settings = Config.getInstance().getSettings();
|
||||||
GridPane layout = createGridLayout();
|
GridPane layout = createGridLayout();
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
layout.add(new Label("Player"), 0, row);
|
layout.add(new Label("Player"), 0, row);
|
||||||
ProgramSelectionBox mediaPlayer = new ProgramSelectionBox(Config.getInstance().getSettings().mediaPlayer);
|
ProgramSelectionBox mediaPlayer = new ProgramSelectionBox(settings.mediaPlayer);
|
||||||
mediaPlayer.fileProperty().addListener((obs, o, n) -> {
|
mediaPlayer.fileProperty().addListener((obs, o, n) -> {
|
||||||
String path = n;
|
String path = n;
|
||||||
if (!Objects.equals(path, Config.getInstance().getSettings().mediaPlayer)) {
|
if (!Objects.equals(path, settings.mediaPlayer)) {
|
||||||
Config.getInstance().getSettings().mediaPlayer = path;
|
settings.mediaPlayer = path;
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GridPane.setFillWidth(mediaPlayer, true);
|
GridPane.setFillWidth(mediaPlayer, true);
|
||||||
GridPane.setHgrow(mediaPlayer, Priority.ALWAYS);
|
GridPane.setHgrow(mediaPlayer, Priority.ALWAYS);
|
||||||
GridPane.setMargin(mediaPlayer, new Insets(0, 0, 0, CHECKBOX_MARGIN));
|
GridPane.setMargin(mediaPlayer, new Insets(0, 0, 0, CHECKBOX_MARGIN));
|
||||||
GridPane.setColumnSpan(mediaPlayer, 3);
|
GridPane.setColumnSpan(mediaPlayer, 2);
|
||||||
layout.add(mediaPlayer, 1, row++);
|
layout.add(mediaPlayer, 1, row);
|
||||||
|
Button mediaPlayerParamsButton = new Button("⚙");
|
||||||
|
mediaPlayerParamsButton.setOnAction(e -> {
|
||||||
|
Optional<String> playerParams = Dialogs.showTextInput(mediaPlayerParamsButton.getScene(), "Media Player Parameters",
|
||||||
|
"Media Player Start Parameters", settings.mediaPlayerParams);
|
||||||
|
playerParams.ifPresent(p -> {
|
||||||
|
settings.mediaPlayerParams = p;
|
||||||
|
saveConfig();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
layout.add(mediaPlayerParamsButton, 3, row++);
|
||||||
|
|
||||||
Label l = new Label("Allow multiple players");
|
Label l = new Label("Allow multiple players");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
|
@ -581,6 +594,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
});
|
});
|
||||||
GridPane.setMargin(l, new Insets(3, 0, 0, 0));
|
GridPane.setMargin(l, new Insets(3, 0, 0, 0));
|
||||||
GridPane.setMargin(multiplePlayers, new Insets(CHECKBOX_MARGIN, 0, 0, CHECKBOX_MARGIN));
|
GridPane.setMargin(multiplePlayers, new Insets(CHECKBOX_MARGIN, 0, 0, CHECKBOX_MARGIN));
|
||||||
|
GridPane.setHgrow(multiplePlayers, Priority.ALWAYS);
|
||||||
layout.add(multiplePlayers, 1, row);
|
layout.add(multiplePlayers, 1, row);
|
||||||
|
|
||||||
l = new Label("Show \"Player Starting\" Message");
|
l = new Label("Show \"Player Starting\" Message");
|
||||||
|
|
|
@ -59,8 +59,8 @@ public class Settings {
|
||||||
public int httpSecurePort = 8443;
|
public int httpSecurePort = 8443;
|
||||||
public String httpServer = "localhost";
|
public String httpServer = "localhost";
|
||||||
public int httpTimeout = 10000;
|
public int httpTimeout = 10000;
|
||||||
public String httpUserAgent = "Mozilla/5.0 Gecko/20100101 Firefox/62.0";
|
public String httpUserAgent = "Mozilla/5.0 Gecko/20100101 Firefox/73.0";
|
||||||
public String httpUserAgentMobile = "Mozilla/5.0 (Android 9.0; Mobile; rv:63.0) Gecko/63.0 Firefox/63.0";
|
public String httpUserAgentMobile = "Mozilla/5.0 (Android 9.0; Mobile; rv:73.0) Gecko/63.0 Firefox/73.0";
|
||||||
public byte[] key = null;
|
public byte[] key = null;
|
||||||
public String lastDownloadDir = "";
|
public String lastDownloadDir = "";
|
||||||
public String livejasminBaseUrl = "https://www.livejasmin.com";
|
public String livejasminBaseUrl = "https://www.livejasmin.com";
|
||||||
|
@ -71,6 +71,7 @@ public class Settings {
|
||||||
public boolean localRecording = true;
|
public boolean localRecording = true;
|
||||||
public int maximumResolution = 0;
|
public int maximumResolution = 0;
|
||||||
public String mediaPlayer = "/usr/bin/mpv";
|
public String mediaPlayer = "/usr/bin/mpv";
|
||||||
|
public String mediaPlayerParams = "";
|
||||||
public String mfcBaseUrl = "https://www.myfreecams.com";
|
public String mfcBaseUrl = "https://www.myfreecams.com";
|
||||||
public List<String> mfcDisabledModelsTableColumns = new ArrayList<>();
|
public List<String> mfcDisabledModelsTableColumns = new ArrayList<>();
|
||||||
public boolean mfcIgnoreUpscaled = false;
|
public boolean mfcIgnoreUpscaled = false;
|
||||||
|
|
Loading…
Reference in New Issue