Genymobile / scrcpy

Display and control your Android device
Apache License 2.0
111.84k stars 10.7k forks source link

【HELP】The mp4 file recorded through scrcpy cannot be opened, the file is corrupted. #5195

Open codematrixer opened 2 months ago

codematrixer commented 2 months ago

I use the following Python script to start screen recording:

process = subprocess.Popen(['scrcpy', '-s', 'a3c1fab5', '--no-display', '-b', '300000', '--record', '/tmp/20240814141706907.mp4', '--max-size', '1280'],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   encoding="utf-8",
                                   shell=False)

And then use the following Python script to stop screen recording:

process.terminate()
try:
    process.wait(timeout=30)
except subprocess.TimeoutExpired:
    logger.warning("Scrcpy process did not terminate within timeout period.")

It always throws subprocess.TimeoutExpired error, It seems that the resources of scrcpy are not being released, causing a timeout.

and then the file /tmp/20240814141706907.mp4 cannot be opened.

Is there an issue with the way I am closing the scrcpy process? Looking forward to your reply.


p.s. I directly execute the command scrcpy -s a3c1fab5 --no-display -b 300000 --record /tmp/20240814141706907.mp4 --max-size 1280 through the command line. After pressing Ctrl+C, the file can be opened.

rom1v commented 2 months ago

on Windows TerminateProcess() is used. Note that exit handlers and finally clauses, etc., will not be executed.

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Process.terminate

So the recording cannot complete properly.

rom1v commented 2 months ago

For Windows, you could try:

import signal
os.kill(self.p.pid, signal.CTRL_C_EVENT)

https://stackoverflow.com/a/62222396/1987178

For Linux, it should probably be:

os.kill(pid, signal.SIGINT)

(not tested)

Also ref #5122

codematrixer commented 2 months ago

For Windows, you could try:

import signal
os.kill(self.p.pid, signal.CTRL_C_EVENT)

https://stackoverflow.com/a/62222396/1987178

For Linux, it should probably be:

os.kill(pid, signal.SIGINT)

(not tested)

Also ref #5122

On macOS, I tried os.kill(pid, signal.SIGINT)

but it doesn't work.

rom1v commented 2 months ago

When you press Ctrl+C in a terminal on macOS, it sends SIGINT, so it should work.

https://stackoverflow.com/a/11570297/1987178