0

I have a function that replay some steps from a .json file and another fuction which record those steps. I need the recordingScreen function to stop once the playActions function finishes simultaneously (by using the flag) and create a video for each iteration, but it only creates the video for the last file (iteration)

I have tried with a flag that changes from false when the playActions function finishes I have also tried with queue from this example link and using using a threadsafe threading.Event() from this example link. But as I am a beginner I have not been able to implement any of them correctly within my code, which is as follow:

files= ["actions_test_10-07-2020_15-56-43.json", "actions_test_10-08-2020_14-59-00.json"]
date = datetime.today().strftime("%m-%d-%Y_%H-%M-%S")
Stop_recording = False

def main():
    initializePyAutoGUI()
    countdownTimer()
    for i in range(len(files)):
        global Stop_recording
        Stop_recording = False
        t1 = threading.Thread(target=playActions, args=[files[i]])
        t2 = threading.Thread(target=recordScreen)

        t1.start()
        t2.start()

        t1.join()
        t2.join()

    print("Done")


def recordScreen():
    output = '{}.avi'.format(date)
    img = pyautogui.screenshot()
    img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    # get info from img
    height, width, channels = img.shape
    # Define the codec and create VideoWriter object
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter(output, fourcc, 20.0, (width, height))

    while not Stop_recording:
        img = pyautogui.screenshot()
        image = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
        out.write(image)
        StopIteration(0.5)

    out.release()
    cv2.destroyAllWindows()

def playActions(filename):
    # Read the file
    script_dir = os.path.dirname(__file__)
    filepath = os.path.join(script_dir, 'recordings', filename)
    with open(filepath, 'r') as jsonfile:
        # parse the json
        data = json.load(jsonfile)
        # loop over each action
        # Because we are not waiting any time before executing the first action, any delay before the initial
        # action is recorded will not be reflected in the playback.
        for index, action in enumerate(data):
            action_start_time = time()
            # look for escape input to exit
            if action['button'] == 'Key.esc':
                break
            # perform the action
            if action['type'] == 'keyDown':
                key = convertKey(action['button'])
                pyautogui.keyDown(key)
                print("keyDown on {}".format(key))
            elif action['type'] == 'keyUp':
                key = convertKey(action['button'])
                pyautogui.keyUp(key)
                print("keyUp on {}".format(key))
            elif action['type'] == 'click' and action['button'] == "Button.right":
                pyautogui.rightClick(action['pos'][0], action['pos'][1], duration=0.25)
                print("right click on {}".format(action['pos']))
            elif action['type'] == 'click' and action['button'] == "Button.left":
                # Check if the period between clicks is short and perform a double click then, otherwise
                # it performs a single click
                if index > 0:
                    if (data[index]['time']) - (data[index - 1]['time']) < 0.5:
                        pyautogui.doubleClick(action['pos'][0], action['pos'][1])
                        print("Double click on {}".format(action['pos']))
                pyautogui.leftClick(action['pos'][0], action['pos'][1], duration=0.25)
                print("left click on {}".format(action['pos']))

            # then sleep until next action should occur
            try:
                next_action = data[index + 1]
            except IndexError:
                # this was the last action in the list
                break
            elapsed_time = next_action['time'] - action['time']

            # if elapsed_time is negative, that means our actions are not ordered correctly. throw an error
            if elapsed_time < 0:
                raise Exception('Unexpected action ordering.')

            # adjust elapsed_time to account for our code taking time to run
            elapsed_time -= (time() - action_start_time)
            if elapsed_time < 0:
                elapsed_time = 0
            print('sleeping for {}'.format(elapsed_time))
            sleep(elapsed_time)
    global Stop_recording
    Stop_recording = True
Jesus Fernandez
  • 500
  • 1
  • 7
  • 20

0 Answers0