Popen subprocess giving wrong ffmpeg process ID when trying to close

83 views Asked by At

I'm trying to create a Video Management System application using Python and Django, that displays live camera stream and do video recording. For this, I add cameras using POST request and everything works fine.

But when I am required to update a camera's details, like IP address or password, then first I delete the camera and then create a new instance with same camera name. The problem I'm facing is that the process ID of the camera (ffmpeg instance here) is not updating, e.g. if initially the process ID was 10, then it remains 10 (in terminate() function in the code) even when I re-create the camera with new details but I do get new process ID in start() function.

Below is the code:

import subprocess
from subprocess import Popen
import os, sys
import threading
import time
from datetime import datetime
import pytz
import os, signal


"""This class is used to create camera objects to display live stream and recordings,
    it is also used to manage recordings files by deleting them at the given time"""
class CameraStream:
    
    def __init__(self, device_name, username, password, ip_address, storage_days):

        self.cam_name = device_name
        self.username = username
        self.password = password
        self.cam_ip = ip_address
        self.storage_days = storage_days
        self.p1 = None
        self.p2 = None
        self.p1_id = None
        self.p2_id = None

        self.recordings_list = []

        folder_name = f"videos/Recordings/{self.cam_name}"
        folder_name2 = f"videos/LiveStreams/{self.cam_name}"

        if not os.path.exists(folder_name):
            os.mkdir(folder_name)
        if not os.path.exists(folder_name2):
            os.mkdir(folder_name2)

        self.directory = folder_name

        t = threading.Thread(target=self.maintain_recordings, args=())
        t.start()

        self.live_stream = f"ffmpeg -fflags nobuffer -rtsp_transport tcp -i rtsp://{self.username}:{self.password}@{self.cam_ip}:554/stream1 -copyts -vcodec copy -acodec copy -hls_flags delete_segments+append_list -f hls -hls_time 6 -hls_list_size 5 -hls_segment_type mpegts -hls_segment_filename videos/LiveStreams/{self.cam_name}/%d.ts videos/LiveStreams/{self.cam_name}/index.m3u8".split(" ")
        self.recording = f"ffmpeg -use_wallclock_as_timestamps 1 -rtsp_transport tcp -i rtsp://{self.username}:{self.password}@{self.cam_ip}:554/stream1 -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_time 1800 -segment_format mp4 -segment_atclocktime 1 -strftime 1 videos/Recordings/{self.cam_name}/%Y%m%dT%H%M%S.mp4".split(" ")

        self.start()


    def start(self):
        self.p1 = Popen(self.live_stream)
        self.p2 = Popen(self.recording)
        # self.p1.wait()       # wait() is not letting the POST request to complete. Hence, using time.sleep() to get process id
        # self.p2.wait()
        time.sleep(2)
        self.p1_id = self.p1.pid
        self.p2_id = self.p2.pid
        print("In start func: ", self.p1_id, self.p2_id)     # gives new process ID here

    def terminate_process(self):
        print("you have awakened me!")
        try:
            try:
                print("In terminate func: ", self.p1_id, self.p2_id)    # gives older process ID here
                os.kill(int(self.p1_id), signal.SIGKILL)
                os.kill(int(self.p2_id), signal.SIGKILL)
                print("terminated by process id!")
            except:
                print("could not delete by process id!")
            try:
                self.p1.terminate()
                self.p2.terminate()
                print("terminated by terminate()")
            except:
                print("could not delete by terminate()")
            try:
                self.p1.kill()
                self.p2.kill()
                print("terminated by kill()")
            except:
                print("could not delete by kill()")
        except Exception as e:
            print("Failed to stop ffmpeg: ", e)

I think I'm making a mistake when deleting the ffmpeg subprocess but can't figure out what it is. Have tried many methods to stop/kill the subprocess but I'm still facing the problem. I believe there is a problem with the terminate_process() function.

I'm deleting the object by using the del keyword, e.g. del <obj_name>, maybe it's keeping the object in the memory but only destroying the reference to that object.

0

There are 0 answers