Для завершения процесса вместе со всеми его дочерними подпроцессами вам следует воспользоваться модулем `psutil`. Вот пример, как можно использовать этот модуль:
```python
import psutil
from subprocess import Popen
def start_stream():
rtsp_connection = f"ffmpeg -i rtsp://{camera_login}:{camera_pass}@{camera_host}:554/Streaming/channels/1/ -err_detect ignore_err -reorder_queue_size 0 -map 0:v -c:v copy -f rtsp -rtsp_transport tcp rtsp://{rtsp_server}:8554/live.stream"
p = Popen(rtsp_connection, shell=True, cwd=".")
p.communicate()
p1 = Popen(['python', '-c', 'start_stream()'], shell=False, cwd=".")
# В определенный момент времени
p1.terminate() # Завершить процесс
parent = psutil.Process(p1.pid)
for child in parent.children(recursive=True):
child.kill() # Завершить все дочерние процессы
# Дополнительно можно использовать следующую команду, чтобы дождаться завершения всех процессов:
p1.wait()
```
В приведенном выше коде `p1.terminate()` завершает процесс `p1`, а затем с помощью модуля `psutil` мы завершаем все его дочерние процессы при помощи `child.kill()`. Затем мы можем использовать `p1.wait()` для дожидания окончания выполнения процесса и освобождения ресурсов.
Также, заметьте, что я изменил способ запуска процесса, используя `shell=True`, и передал команду как строку вместо списка аргументов. Это связано с тем, что вам нужно использовать команду `start_stream()` как внешнюю команду для запуска подпроцесса.
Импортируйте модули без скрытого импорта:
```python
import signal
import subprocess
import sys
```
Избегайте двойной вложенности процессов:
```python
args = ["ffmpeg", "-i", f"rtsp://{camera_login}:{camera_pass}@{camera_host}:554/Streaming/channels/1/", "-err_detect", "ignore_err", "-reorder_queue_size", "0", "-map", "0:v", "-c:v", "copy", "-f", "rtsp", "-rtsp_transport", "tcp", f"rtsp://{rtsp_server}:8554/live.stream"]
params = {'cwd': '.'}
if sys.platform == 'win32':
params['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
my_subprocess = Popen(args, **params)
try:
pass # тут работаешь с процессом
finally:
my_subprocess.signal(signal.CTRL_C_EVENT)
try:
my_subprocess.wait(timeout=5.0)
except subprocess.TimeoutExpired:
my_subprocess.kill()
```