diff --git a/actions.py b/actions.py index f2e0c89..588baf3 100644 --- a/actions.py +++ b/actions.py @@ -1,11 +1,12 @@ import subprocess class Actions(object): - def __init__(self, tk, message_handler, data, video_driver, display): + def __init__(self, tk, message_handler, data, video_driver, capture, display): self.tk = tk self.message_handler = message_handler self.data = data self.video_driver = video_driver + self.capture = capture self.display = display @@ -156,6 +157,25 @@ class Actions(object): self.data.update_slot_end_to_this_time(current_bank, current_slot, -1) self.load_this_slot_into_next_player(current_slot) + def toggle_capture_preview(self): + is_previewing = self.capture.is_previewing() + if is_previewing: + self.capture.stop_preview() + if self.video_driver.current_player.status == 'PAUSED': + self.toggle_pause_on_player() + else: + self.capture.start_preview() + if self.video_driver.current_player.status != 'PAUSED': + self.toggle_pause_on_player() + + def toggle_capture_recording(self): + is_recording = self.capture.is_recording() + if is_recording: + path_to_new_sample = self.capture.stop_recording() + # map new sample into next bank ? + else: + self.capture.start_recording() + def switch_display_to_hdmi(self): settings = self.data.get_settings_data() current_screen_mode = [x['options'][0] for x in settings if x['name'] == 'SCREEN_SIZE'] @@ -165,12 +185,8 @@ class Actions(object): self.message_handler.set_message('INFO', 'must be in dev_mode to change display') def switch_display_to_lcd(self): - settings = self.data.get_settings_data() - current_screen_mode = [x['options'][0] for x in settings if x['name'] == 'SCREEN_SIZE'] - if('dev_mode' in current_screen_mode): - self.run_script('switch_display_to_lcd') - else: - self.message_handler.set_message('INFO', 'must be in dev_mode to change display') + self.run_script('switch_display_to_lcd') + def set_composite_to_pal(self): self.run_script('set_composite_mode','2') diff --git a/data_centre/json_objects/keypad_action_mapping.json b/data_centre/json_objects/keypad_action_mapping.json index 497820b..ea0b7ac 100644 --- a/data_centre/json_objects/keypad_action_mapping.json +++ b/data_centre/json_objects/keypad_action_mapping.json @@ -23,7 +23,8 @@ "f": { "DEFAULT": ["set_playing_sample_end_to_current_duration", "clear_playing_sample_end_time"] }, - "g": {}, + "g": { + "DEFAULT": ["toggle_capture_preview", "toggle_capture_recording"]}, "h": { "DEFAULT": ["cycle_display_mode"] }, diff --git a/my_video.h264 b/my_video.h264 new file mode 100644 index 0000000..dd3497e Binary files /dev/null and b/my_video.h264 differ diff --git a/my_video.mp4 b/my_video.mp4 new file mode 100644 index 0000000..b4bf446 Binary files /dev/null and b/my_video.mp4 differ diff --git a/r_e_c_u_r.py b/r_e_c_u_r.py index e7e0096..f49a6d0 100644 --- a/r_e_c_u_r.py +++ b/r_e_c_u_r.py @@ -9,6 +9,7 @@ from display_centre.messages import MessageHandler from user_input.numpad_input import NumpadInput from user_input.midi_input import MidiInput from video_centre.video_driver import VideoDriver +from video_centre.capture import Capture import data_centre # create tk object @@ -25,13 +26,13 @@ data = Data(message_handler) # setup the video driver video_driver = VideoDriver(tk, message_handler, data) -#capture = Capture() +capture = Capture(tk, message_handler, data) # setup the display display = Display(tk, video_driver, message_handler, data) # setup the actions -actions = Actions(tk, message_handler, data, video_driver, display) +actions = Actions(tk, message_handler, data, video_driver, capture, display) numpad_input = NumpadInput(tk, message_handler, display, actions, data) midi_input = MidiInput(tk, message_handler, display, actions, data) diff --git a/video_centre/capture.py b/video_centre/capture.py index 36cfc6c..604bc36 100644 --- a/video_centre/capture.py +++ b/video_centre/capture.py @@ -1,7 +1,101 @@ - +import os +import subprocess +import datetime +from picamera import PiCamera class Capture(object): def __init__(self, root, message_handler, data): self.root = root self.message_handler = message_handler self.data = data + self.use_capture = True + self.device = None + self.raw_dir = '/home/pi/Videos/raw_recordings' + self.create_capture_device() + + def create_capture_device(self): + if self.use_capture: + self.device = PiCamera() + + def start_preview(self): + if self.device.closed: + self.create_capture_device() + self.device.start_preview() + self.set_preview_screen_size() + + def set_preview_screen_size(self): + if self.data.get_screen_size_setting() == 'dev_mode': + self.device.preview.fullscreen = False + self.device.preview.window = (50, 350, 500, 400) + else: + self.device.preview.fullscreen = True + + def stop_preview(self): + self.device.stop_preview() + if not self.device.recording: + self.device.close() + + def start_recording(self): + if self.device.closed: + self.create_capture_device() + # need to check the space in destination (or check in a main loop somewhere ?) + + if not os.path.exists(self.raw_dir): + os.makedirs(self.raw_dir) + self.device.start_recording(self.raw_dir + '/raw.h264') + + def stop_recording(self): + self.device.stop_recording() + #set status to saving + mp4box_process = self.convert_raw_recording() + print(mp4box_process.poll()) + self.root.after(0, self.wait_for_recording_to_save, mp4box_process) + + # return path to the video + if not self.device.preview: + self.device.close() + + def convert_raw_recording(self): + recording_path = self.generate_recording_path() + try: + return subprocess.Popen(['MP4Box -add {} {}'.format(self.raw_dir + '/raw.h264', recording_path)],shell=True) + except Exception as e: + print(e) + if hasattr(e, 'message'): + error_info = e.message + else: + error_info = e + self.message_handler.set_message('ERROR',error_info) + + + def wait_for_recording_to_save(self, process): + print('the poll is {}'.format(process.poll())) + if process.poll() is not None: + #remove saving status + os.remove(self.raw_dir + '/raw.h264') + else: + self.root.after(300, self.wait_for_recording_to_save, process) + + def generate_recording_path(self): + rec_dir = '/home/pi/Videos/recordings' + if not os.path.exists(rec_dir): + os.makedirs(rec_dir) + date = datetime.datetime.now().strftime("%Y-%m-%d") + i = 0 + while os.path.exists('{}/rec-{}-{}.mp4'.format(rec_dir,date, i)): + i += 1 + return '{}/rec-{}-{}.mp4'.format(rec_dir,date, i) + + def is_previewing(self): + if self.device.closed or not self.device.preview: + return False + else: + return True + + def is_recording(self): + if self.device.recording: + return True + else: + return False + +