Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added command line arguments #749

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jozsefmorrissey
Copy link

Added the followning command line arguments:

  • input_profile
  • output_profile
  • termination_timer
  • output_file
  • record_on_start

This allows your application to be started and stopped via the terminal or a script.

I requested this feature last week, went ahead and implemented it myself.

Note: for the termination timer i used pthread, I tried to use qthread and my work can be found on branch command_args_qthread I was unable to get it to work, I am unfamiliar with the qt framework.

…ofile, termination_timer, output_file, record_on_start) to allow the application to be triggered and terminated purely with a single command
@MaartenBaert
Copy link
Owner

This is a lot to read through so this will take some time. Some remarks:

  • I use std::thread for multithreading already so that would be preferable over pthread. However I think it's actually completely unnecessary to use threads for this since there's also QTimer. The way you've implemented this now seems to be horribly susceptible to race conditions, there's no locking whatsoever and you're calling GUI functions from a non-GUI thread which is a great way to crash Qt. I'm surprised that this works at all actually.

  • I don't want to add a separate command-line argument for every option in the program, but I don't really like using the input and output profiles for this either because this makes scripting harder: a script that invokes SSR would have to generate a profile and put this in the SSR profile directory where it might interfere with other things. I think it would be better to add a single command-line option to load a different settings file instead.

@jozsefmorrissey
Copy link
Author

Hopefully it comes in handy. I have very little c++ experience but worked quite a bit in c, hence the use of pthread.

I tried for two days to get QTimer and QThread working to implement the timed termination and failed. It seamed like QThread is meant to work in conjunction with the gui. I don't see any race condition issues but again I have never worked with Qt framework before and have no real understanding of how it works.

I first attempted to update you settings object, hoping that the gui interface and the recording process would update as well, this did not work. Given my limited knowledge and experience with your application, This is a minimalist modification, It seamed to me that your settings are tightly coupled to the gui which forced me to interact with the gui classes/functions.

If I get time I will take another look with you comments in mind. I will push changes if I can find a more appropriate way to apply my changes.

@MaartenBaert
Copy link
Owner

MaartenBaert commented Feb 15, 2020

That's correct, the GUI is interwoven with the rest of the program in a way that makes it very tricky to do something like start a recording without actually going through the GUI. This is arguably a design flaw, but changing this now would require a complete redesign of the application. So it's something I've accepted.

I've resurrected the old record-schedule branch and updated the GUI a bit. This provides the ability to automatically stop the recording as you and several other people have requested.

There are now also command-line options to load a custom settings file and automatically start the recording or activate the recording schedule. Since it is possible to generate a custom settings file from a user script, it is now possible to run SSR entirely from the command line (with options --settingsfile=FILE --start-hidden --start-recording --start-schedule). The GUI is still there but you won't see it.

I've done only a few simple tests so far, it would be useful if you could test it some more and tell me whether you encounter any problems before I release this in the next version.

@MaartenBaert
Copy link
Owner

By the way, for future reference, the tricky thing with Qt and threads is that Qt wants to run all GUI-related actions in a single thread. You can have other threads doing other things, but if you want to do something that will affect the GUI (like start the recording), you need to use the signal/slot mechanism to send a message to the GUI thread using Qt::QueuedConnection. This is done for example by the video and audio preview widgets (capturing and scaling/processing is done in another thread, which then sends a signal to the GUI to update itself when needed).

@MaartenBaert
Copy link
Owner

I've just added support for several commands over stdin. The commands are:

record-start
record-pause
record-cancel
record-save
schedule-activate
schedule-deactivate
window-show
window-hide
quit

Note that these are basically equivalent to pressing buttons in the GUI, so under some circumstances the commands won't work, for example when there's an open dialog window that's blocking the application. Also, in some cases it is necessary to wait a bit after a command has been executed before issuing the next command. For example, sending record-save immediately followed by quit will likely cause the application to quit before the video is properly finalized and saved. So if you're planning to control these with scripts, make sure that there's some time between commands. It's not ideal but there's no easy way to fix this.

@jozsefmorrissey
Copy link
Author

Changes look good I will play around with them tomorrow.

@jozsefmorrissey
Copy link
Author

jozsefmorrissey commented Feb 24, 2020

Hey Maarten,

Sorry about the delay, I didn't want to send my comments prematurely. I have concerns about your stop/start/save/.... commands. I cannot seem to trigger them from another terminal/process, if you know how let me know. If you need clarification on the issue I made a quick video going over the following notes.

Findings:
--settingsfile:
You should no longer seperate the in/out settings.
Allowing users to indicate --settingsfile=mySettings which will correspond
to ~/.ssr/settings/mySettngs.conf
So if they define a settings file within your application it can later be
referenced via cmdline arg.

No Issues: --start-hidden, --start-recording

Not Tested(? use case): --start-schedule, schedule-activate, schedule-deactivate

Desige considerations:
- Free up the need to use a specific terminal.
- Use named processes.

How you normally control input to another process: (Does not work with ssr)
  echo "record-pause" >> /proc/[PID]/fd/0

mc works (Custom scripts to control named processes: mc.sh, target_term.py)

Commands to be added:
--name
--exec=[name]:[cmd]
--modify-prop=[key]:[value]
--all-props
Prints a list of all modifiable properties controlling this application. Your config
files can be found at ~/.ssr/.conf
command to print list:
grep -roP "setValue("(.
?)"" | sed 's/."(.)"/\1/' | sort | uniq

@MaartenBaert
Copy link
Owner

Thanks for the feedback.

Like you already figured out, you can create a settings file graphically by starting SSR with the --settingsfile=<FILE> option, configuring everything the way you want, and then SSR will save your settings to <FILE> (rather than ~/.ssr/settings.conf) when closed.

The main use case of the schedule function is for users that use SSR to capture live streams while they aren't present. This is not exactly what SSR is designed for, but based on the number of people who have requested this feature it seems to be a common use case. There are probably more efficient ways to accomplish this, but those usually require technical knowledge about the underlying video streaming protocol which very few users have. So in practice a lot of users end up simply opening a webpage where the live stream will be visible, and record it with SSR. The schedule feature saves them a lot of disk space since they don't have to record continuously anymore.

I think /proc/[PID]/fd/0 doesn't work the way you want because you're writing to the wrong end of the pipe. I'm surprised that it doesn't produce an error actually, since you're writing to an FD that's only meant for reading. In bash you can make it work using named pipes instead:

PIPE="/tmp/ssr-command-pipe"
mkfifo "$PIPE"
simplescreenrecorder < "$PIPE" &
exec 4> "$PIPE"
sleep 3
echo "record-start" >&4
sleep 3
echo "record-save" >&4
sleep 3
echo "quit" >&4
exec 4>&-
rm "$PIPE"

It's ugly but that's just how bash works sadly. It's a lot cleaner in Python for example:

import subprocess
import time
p = subprocess.Popen(["simplescreenrecorder"], stdin=subprocess.PIPE, bufsize=0)
time.sleep(3)
p.stdin.write(b"record-start\n")
time.sleep(3)
p.stdin.write(b"record-save\n")
time.sleep(3)
p.stdin.write(b"quit\n")
p.wait()

I could also have SSR create a named pipe, but this doesn't make things any easier for bash users, and it's annoying for e.g. Python users that have decent pipe support.

I could also have SSR create a named unix domain socket, so one or more external processes can connect to it and send commands if they want. But then you would have to use netcat (nc) or a sockets library to talk to SSR which just makes things more complicated IMHO.

@MaartenBaert
Copy link
Owner

Regarding --modify-prop=[key]:[value], this is possible but requires duplicating a lot of code that's currently used for loading the settings file. I think it's easier to have a script generate a settings file and run SSR with that file, rather than sending commands to SSR to change the settings after loading the wrong ones.

Note that you don't actually have to write a complete settings file, since SSR will substitute all missing properties with the default value when it loads the settings file.

@blais
Copy link

blais commented Aug 4, 2020

This is useful. Personally I'd just like to have a simple GUI input that allows me to enter a stop time, like "Stop after 55 minutes" or somesuch.

@MaartenBaert
Copy link
Owner

@blais That's already possible with the recording schedule feature.

@blais
Copy link

blais commented Aug 8, 2020

@blais That's already possible with the recording schedule feature.

Thank you Maarten, I don't see that menu in the GUI. I found the dialog in the source so I know it's there,my version is probably too old (from Ubuntu 18.04 stable, = 0.3.8). I'll try compiling from HEAD.

@blais
Copy link

blais commented Aug 8, 2020

@blais That's already possible with the recording schedule feature.

Thank you Maarten, I don't see that menu in the GUI. I found the dialog in the source so I know it's there,my version is probably too old (from Ubuntu 18.04 stable, = 0.3.8). I'll try compiling from HEAD.

Confirmed that was it. Installed v0.4.2 and I can see it now.
Thanks for making screen recording simple and easy!

@KingFalse
Copy link

Java for example

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class ssr {
    public static void main(String[] args) throws IOException, InterruptedException {
        Runtime run = Runtime.getRuntime();
        Process p = run.exec("simplescreenrecorder");
        Thread.sleep(1000);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
        bw.write("record-start\n");
        bw.flush();
        Thread.sleep(1000*10);
        bw.write("record-save\n");
        bw.flush();
        bw.write("quit\n");
        bw.flush();
        bw.close();
        p.waitFor();
    }
}

@petterreinholdtsen
Copy link
Contributor

Any hope to have the merge conflict resolved and this patch included in a ssr release? It would make it possible to non-interactively test the program, a feature much valued by us Debian packagers to ensure the program keep working as libraries and other dependencies change over time.

@jozsefmorrissey
Copy link
Author

My understanding/recollection of this merge is that the changes I made were not utilizing the existing threading structure. So MaartenBaert created similar commands. I still use this branch because it works great for my needs. Last I checked he had implemented the following commands not sure if they will work for your purposes.
record-start
record-pause
record-cancel
record-save
schedule-activate
schedule-deactivate
window-show
window-hide
quit

@petterreinholdtsen
Copy link
Contributor

petterreinholdtsen commented Feb 18, 2023 via email

@jozsefmorrissey
Copy link
Author

I can only speculate as to why they were not documented, I would think they should be. I don't expect @MaartenBaert to chime in, after reviewing recent issues it seams this isn't actively being supported anymore... Sad its a powerful application with a simple interfacel. @MaartenBaert built a great tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants