如何杀死正在循环中启动的线程?

时间:2019-06-25 04:30:19

标签: python multithreading

我有使用开放CV录制1分钟长的视频,然后将小视频连接到主视频文件的代码。万一出了什么问题并且系统突然关闭而程序没有正确关闭,这应该是故障安全的。我想在单独的线程中运行视频录制和串联,因为将视频串联起来需要时间,如果不在单独的线程上运行,那么这段时间将浪费在素材中。我的问题是在循环中启动线程时出现的。全部运行一次,然后我得到一个错误,即一个线程只能启动一次。有没有办法可以在线程运行完毕后杀死它,然后在循环中再次启动它?或者还有更好的方法可以编写代码吗?

我试图通过调用del删除线程对象,但是我不知道自己在做什么错

import cv2
import os
from datetime import datetime, timedelta
from threading import *
from moviepy.editor import VideoFileClip, concatenate_videoclips


# Class for concatenating the videos
class VideoConcatenate(Thread):
    def run(self):

        today = datetime.today().strftime('%Y-%b-%d')

        print(datetime.now().strftime('%H:%M:%S') + " Starting video concatenation")
        # Define the small video and main video files
        clip_small = VideoFileClip('Cam01_'+str(today) + "_small_toAdd" + '.mp4')
        clip_main = VideoFileClip('Cam01_'+str(today) + "_main" + '.mp4')

        # Define the concatenation order
        clip_final = concatenate_videoclips([clip_main, clip_small])

        # Write the new/concatenated video file
        clip_final.write_videofile('Cam01_'+str(today) + "_main_recent" + '.mp4')
        print(datetime.now().strftime('%H:%M:%S') + " Concatenation Finished")

        # Rename the the main_recent file to main
        # This will overwrite the main video with the main_recent video
        os.rename('Cam01_'+str(today) + "_main_recent" + '.mp4', 'Cam01_'+str(today) + "_main" + '.mp4')

        # Remove the recently added video
        os.remove('Cam01_'+str(today) + "_small_toAdd" + '.mp4')


# Class for recording the videos the videos
class CaptureCamera(Thread):
    def run(self):

        today = datetime.today().strftime('%Y-%b-%d')

        # capture IP camera's live feed
        cap = cv2.VideoCapture('rtsp://admin:@10.187.1.146:554/user=admin_password=tlJwpbo6_channel=1_stream=0')
        ret, initialFrame = cap.read()

        # Settings for the video recording.
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        fps = 20

        # Get the frame's size and set the output frame size to 50%
        fshape = initialFrame.shape
        fheight = fshape[0]  # * 50/100
        fwidth = fshape[1]  # * 50/100

        frameSize = (int(fwidth), int(fheight))
        print(frameSize)

        if cap.isOpened:
            print(datetime.now().strftime('%H:%M:%S') + " The IP Camera's feed is now streaming\n")

            try:
                # Get time that recording started
                timeStart = datetime.now()

                # check if the day is correct
                if datetime.today().strftime('%Y-%b-%d') == today:
                    # Create main file for the day if doesn't exist
                    if not os.path.exists('Cam01_'+str(today)+ "_main"+'.mp4'):
                        print(datetime.now().strftime('%H:%M:%S')+" Creating main file for "+today)
                        vidOut = cv2.VideoWriter('Cam01_'+str(today) + "_main" + '.mp4', fourcc, fps, frameSize)

                        recStop = datetime.now()+timedelta(seconds=15)

                        print(datetime.now().strftime('%H:%M:%S')+" Recording initial 15 seconds")

                        # Record 15 seconds worth of video so the file is not empty and can be concatenated
                        while datetime.now() <= recStop:

                            # read frame
                            ret, frame = cap.read()

                            # # resize the frame to 50%
                            # frame = cv2.resize(frame, frameSize, interpolation = cv2.INTER_AREA)

                            # Write frame to video file
                            vidOut.write(frame)

                        vidOut.release()
                        print(datetime.now().strftime('%H:%M:%S')+" Created main file for " + today)
                    else:
                        print(datetime.now().strftime('%H:%M:%S')+' Cam01_'+str(today) + "_main"+'.mp4'+' already exists')

                    vidOut = cv2.VideoWriter('Cam01_'+str(today) + "_small" + '.mp4', fourcc, fps, frameSize)
                    print(datetime.now().strftime('%H:%M:%S')+" Recording for " + today + " from " + datetime.now().strftime('%H:%M:%S'))

                    # Set stop time for the recording
                    recStop = datetime.now() + timedelta(seconds=60*1)

                    print(datetime.now().strftime('%H:%M:%S')+" Recording for duration of 1 mins \n\nPress Ctrl+C on the keyboard to quit \n\n")

                    while datetime.now() <= recStop:

                        # read frame
                        ret, frame = cap.read()

                        # # resize the frame to 50%
                        # frame = cv2.resize(frame, frameSize, interpolation = cv2.INTER_AREA)

                        # Write frame to video file
                        vidOut.write(frame)

                    print("Recording ended at " + datetime.now().strftime("%Y-%B-%d, %A %H:%M:%S"))

                    vidOut.release()  # End video write and release the file

                    # rename the small file to be added to main so a new small file can be created
                    os.rename('Cam01_'+str(today) + "_small" + '.mp4',
                              'Cam01_'+str(today) + "_small_toAdd" + '.mp4')

            except KeyboardInterrupt:
                print("\nProcess Interrupted by User")
                if vidOut.isOpened():
                    vidOut.release()   # End video write
                    cap.release()  # Release IP Cameras
                    os.rename('Cam01_' + str(today) + "_small" + '.mp4',
                              'Cam01_' + str(today) + "_small_toAdd" + '.mp4')

                    print("\nRecording ended at " + datetime.now().strftime("%Y-%B-%d, %A %H:%M:%S"))
                    print("                               H:MM:SS.milliseconds")
                    print("The recording was operated for "+str(datetime.now()-timeStart))
        else:
            print("The video stream couldn't be reached")


def main():
    t1 = CaptureCamera()
    t1.daemon = True

    t2 = VideoConcatenate()
    t2.daemon = True

    while True:
        if not t1.is_alive():
            t1.start()
        else:
            del t1
            t1.run()

        t1.join()  # Wait for t1 to complete running and join the main thread.

        if not t2.is_alive():
            t2.start()
        else:
            del t2
            t2.run()


main()


我希望发生的事情是,第一个线程(用于视频录制)一直运行到完成,然后一旦它加入主线程,第二个线程(用于视频串联)将在第一个线程再次运行时运行。基本上,我不希望视频连接是在后台运行的,并且不应中断视频录制。

0 个答案:

没有答案