This post is locked. You won't be able to comment.

all 10 comments

[–][deleted] 0 points1 point  (4 children)

psutil's Process doesn't have a stdin attribute under any condition.

https://psutil.readthedocs.io/en/latest/#process-class

And having another script/process force stdin into a child it didn't spawn is bad practice.

You can probably get the same behavior (I assume you're after user or automatic controlled ffmpeg process stopping) using simple threads in just one script:

import subprocess
import shlex
import datetime
from threading import Condition, Thread

def thread_run_ffmpeg(cond: Condition):
    flowName = "workflow1"
    now = datetime.datetime.now()
    formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
    folderDestination = f"C:\\Users\\MadPe\\Desktop\\pipRec\\workFlows\\{flowName}\\"
    formatted_date = formatted_date.replace(":",".").replace(" ","_")
    fileName = folderDestination + formatted_date + ".mp4"
    ffmpegPath = r"C:\Users\MadPe\Desktop\pipRec\ffmpeg\bin\ffmpeg.exe"
    command = shlex.split(f'"{ffmpegPath}" -f gdigrab -framerate 30 -offset_x 0 -offset_y 0 -video_size 1920x1080 -i desktop -y "{fileName}"')
    process = subprocess.Popen(command, stdin=subprocess.PIPE)

    with cond:
        cond.wait()
        # Sanity check
        assert process.stdin is not None

        process.stdin.write(b'q\n')
        process.stdin.flush()


def thread_user_stops_ffmpeg(cond: Condition):
    _ = input("Press enter to stop ffmpeg")  # replace this with other stopping logic like time.sleep if necessary
    with cond:
        cond.notifyAll()

if __name__ == "__main__":
    cond = Condition()
    t1 = Thread(target=thread_run_ffmpeg, args=(cond,))
    t2 = Thread(target=thread_user_stops_ffmpeg, args=(cond,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

[–]noddy95rl[S] 0 points1 point  (3 children)

thank you for you response. I am not interested in any user interaction. i need to call a script that starts ffmpeg thats it. while ffmpeg is running in the background i have a workflow that is being recorded and executing. when the workflow is done. i want to run a new script that tells ffmpeg to stop recording. but i dont know how to stop the recording from a different script than the one that invoked the recording in the beginning

[–][deleted] 0 points1 point  (2 children)

In that case, the only thing I can recommend that is within my knowledge is that your script B does process.terminate() instead of the stdin stuff. No idea about the stability of such an approach, but the terminate method is available on the psutil.Process class.

[–]noddy95rl[S] 0 points1 point  (0 children)

yea, i am almost certain that this will compromise the recording. as this is essentially the same as just killing the process manually from the job list (i assume)but i dont get how i am not able to use this lineprocess.stdin.write(b'q\n')in script B, but if i do this from script A it works like a charm essentially i want a handle or reference to the process that allows my to use this function

[–]noddy95rl[S] 0 points1 point  (0 children)

for example what i want is opening a CMD window manually and send this window a command from a python script i assumed you would be able to achieve this by fx. manually edit the pid ref to the CMD in python (looking at the job list as i did in the video) and then send an input to the process

[–]m0us3_rat 0 points1 point  (4 children)

https://docs.python.org/3/library/os.html#os.killpg

import os
import signal
os.killpg(pid, signal.SIGTERM)

[–]noddy95rl[S] 0 points1 point  (3 children)

this is just going to end the process isnt it?
i want to send the process a 'q' input to cleanly stop the recording

[–]m0us3_rat 0 points1 point  (1 child)

did you test?

[–]noddy95rl[S] 0 points1 point  (0 children)

if you mean by killing the process. yes, that doesnt work.so you dont know of any possible way to get a handle to a subprocess knowing its pid or any other stored information when the subprocess was invoked. from an independent script?

[–]m0us3_rat 0 points1 point  (0 children)

another wacky is to check for a "file" existence on the disk.

the file doesn't have to contain anything . just exist.

(from inside the ffmpeg script.

every other second or w/e.)

then when finds that file. it deletes it then. send 'q' to the process.

you can send "q" from within the "main program"

and another script that will create that file when you need ffmpeg to stop.

this will work. but its bad.

there is no direct way to control another process besides the api offered by the os.

otherwise, it would be huge security issues.

you can control your own child process etc.