示例#1
0
class App:
    def __init__(self, preview=False, max_video_length=MAX_VIDEO_LENGTH):
        log.info("booting up..")
        self.final_dir = self._setup_dirs()
        self.max_video_length = max_video_length
        self.video_recorder = VideoRecorder(preview=preview)
        self.audio_recorder = AudioRecorder()
        time.sleep(2)
        log.info("ready!")

    def _setup_dirs(self):
        final_dir = os.path.expanduser('~/media/')
        if (os.path.isdir(final_dir) == False):
            os.mkdir(final_dir)
        return final_dir

    def _make_filename(self):
        return datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S")

    def has_space(self):
        statvfs = os.statvfs("/")
        megabytes_available = int(statvfs.f_frsize * statvfs.f_bavail / 1024 /
                                  1024)
        log.info(f"Still {megabytes_available}MB left on device")
        return megabytes_available > MIN_DISK_SPACE_MB

    def on_keyboard_release(self, key):
        if key == keyboard.Key.enter:
            if lock.locked():
                self.stop_recording()
            elif self.has_space():
                self.start_recording()
            else:
                return False
        if key == keyboard.Key.esc:
            if lock.locked():
                self.stop_recording()
            return False

    def timer(self, seconds, current_video):
        log.info(f"going to sleep for {seconds}s and then stop recording")
        for i in range(seconds):
            if not lock.locked():
                log.info("looks like recording has ended before timeout")
                return
            elif current_video != self.file_name:
                log.info("there is a different ongoing recording")
                return
            time.sleep(1)
        log.info("time's up!, stopping recording")
        self.stop_recording()

    def start_recording(self):
        lock.acquire()
        self.start_datetime = datetime.datetime.now()
        self.file_name = self._make_filename()
        timer_thread = threading.Thread(target=self.timer,
                                        args=(self.max_video_length,
                                              self.file_name))
        timer_thread.start()
        self.tmp_dir = tempfile.mkdtemp()

        log.info("starting threads...")
        self.video_recorder.start(self.file_name, self.tmp_dir)
        self.audio_recorder.start(self.file_name, self.tmp_dir)

    def stop_recording(self):
        log.info("stopping threads...")
        if not self.audio_recorder.stop():
            return
        if not self.video_recorder.stop():
            return
        now = datetime.datetime.now()
        video_length = (now - self.start_datetime).seconds
        if video_length > MIN_VIDEO_LENGTH:
            log.info("starting mux...")
            cmd = (
                f"ffmpeg -i {self.tmp_dir}/{self.file_name}.wav -i {self.tmp_dir}/{self.file_name}.h264 "
                f"-c:v copy -c:a aac -strict experimental {self.final_dir}/{self.file_name}.mp4"
            )
            subprocess.run(cmd, capture_output=True, shell=True)
            log.info(f"{self.file_name}.mp4 is ready!")
        else:
            log.info(f"Video was to short: {video_length}, removing it")
        shutil.rmtree(self.tmp_dir)
        log.info(f"{self.tmp_dir} removed")
        lock.release()

    def run(self):
        def on_release(button):
            if lock.locked():
                self.stop_recording()
            elif self.has_space():
                self.start_recording()
            else:
                return False

        button = Button(2)
        button.when_released = on_release
        listener = keyboard.Listener(on_release=self.on_keyboard_release)
        listener.start()
        pause()
示例#2
0
    if new_state == State.ACTIVE:
        # Motion has been detected, so the scene is now ACTIVE.
        if state == State.IDLE:
            # Transitioning from IDLE to ACTIVE, so we need to start recording.
            VideoRecorder.start()
        state = State.ACTIVE

    elif new_state == State.RECORDING:
        state = State.RECORDING

    elif new_state == State.IDLE:
        if state != State.IDLE:
            # Transitioning from RECORDING to IDLE.  Stop the recording.
            state = State.IDLE
            VideoRecorder.stop()

    # draw the text on the frame
    if state == State.IDLE:
        text = "Idle."
    elif state == State.RECORDING:
        text = "Idle, Recording..."
    elif state == State.ACTIVE:
        text = "Active, Recording..."
    else:
        raise ValueError("Unexpected value for state: ", state)

    cv2.putText(frame, "Status: {}".format(text), (10, 20),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

    # Check to see if the frame should be displayed to screen.