diff --git a/actions.py b/actions.py index b0dd25d..1e6d9f2 100644 --- a/actions.py +++ b/actions.py @@ -74,7 +74,7 @@ class Actions(object): def load_slot_9_into_next_player(self): self._load_this_slot_into_next_player(9) - def trigger_next_player(self): + def switch_to_next_player(self): self.video_driver.switch_players_and_play_video() def cycle_display_mode(self): @@ -91,10 +91,16 @@ class Actions(object): self.data.control_mode = 'PLAYER' def toggle_pause_on_player(self): - self.video_driver.current_player.toggle_pause() + if self.data.player_mode == 'now': + self.video_driver.current_player.toggle_pause() + elif self.data.player_mode == 'next': + self.video_driver.next_player.toggle_pause() def toggle_show_on_player(self): - self.video_driver.current_player.toggle_show() + if self.data.player_mode == 'now': + self.video_driver.current_player.toggle_show() + elif self.data.player_mode == 'next': + self.video_driver.next_player.toggle_show() def seek_forward_on_player(self): self.video_driver.current_player.seek(30) @@ -171,6 +177,12 @@ class Actions(object): self.data.update_screen = True subprocess.call(['sudo', 'systemctl', 'stop', 'raspi2fb@1']) + def toggle_player_mode(self): + if self.data.player_mode == 'now': + self.data.player_mode = 'next' + elif self.data.player_mode == 'next': + self.data.player_mode = 'now' + def set_the_camera_colour_u_with_cc(self, amount): u_value = self._convert_midi_cc_value(amount, 0, 255) self.capture.set_colour(u_value, None) diff --git a/data_centre/data.py b/data_centre/data.py index d6c1ddc..14f674d 100644 --- a/data_centre/data.py +++ b/data_centre/data.py @@ -32,6 +32,7 @@ class Data(object): self.bank_number = 0 self.midi_status = 'disconnected' self.update_screen = True + self.player_mode = 'now' ### persisted data: self.bank_data = self._read_json(self.BANK_DATA_JSON) diff --git a/data_centre/json_objects/display_data.json b/data_centre/json_objects/display_data.json index 255c801..1b19f13 100644 --- a/data_centre/json_objects/display_data.json +++ b/data_centre/json_objects/display_data.json @@ -6,7 +6,7 @@ "location": "/media/pi/5EB5-664C/recur test videos/colour_pixal_01.mp4", "name": "colour_pixal_01.mp4", "rate": 1, - "start": 3.979 + "start": -1 }, { "end": -1, @@ -14,7 +14,7 @@ "location": "/media/pi/5EB5-664C/recur test videos/colour_pixal_02.mp4", "name": "colour_pixal_02.mp4", "rate": 1, - "start": 4.49 + "start": -1 }, { "end": -1, @@ -34,9 +34,9 @@ }, { "end": -1, - "length": -1, - "location": "", - "name": "", + "length": 804.245, + "location": "/media/pi/5EB5-664C/recur test videos/long_spinning.mp4", + "name": "long_spinning.mp4", "rate": 1, "start": -1 }, diff --git a/data_centre/json_objects/keypad_action_mapping.json b/data_centre/json_objects/keypad_action_mapping.json index 9c17bb1..dde1f97 100644 --- a/data_centre/json_objects/keypad_action_mapping.json +++ b/data_centre/json_objects/keypad_action_mapping.json @@ -15,7 +15,7 @@ "NAV_SETTINGS": ["enter_on_settings_selection"] }, "d": { - "DEFAULT": ["trigger_next_player"] + "DEFAULT": ["switch_to_next_player", "toggle_player_mode"] }, "e": { "DEFAULT": ["set_playing_sample_start_to_current_duration", "clear_playing_sample_start_time"] diff --git a/data_centre/json_objects/midi_action_mapping.json b/data_centre/json_objects/midi_action_mapping.json index 2253400..e8810c0 100644 --- a/data_centre/json_objects/midi_action_mapping.json +++ b/data_centre/json_objects/midi_action_mapping.json @@ -24,7 +24,7 @@ "NAV_SETTINGS": ["enter_on_settings_selection"] }, "note_on 75": { - "DEFAULT": ["trigger_next_player"] + "DEFAULT": ["switch_to_next_player"] }, "note_on 76": { "DEFAULT": ["set_playing_sample_start_to_current_duration", "clear_playing_sample_start_time"] diff --git a/data_centre/json_objects/settings.json b/data_centre/json_objects/settings.json index f8f0584..4f8a0c3 100644 --- a/data_centre/json_objects/settings.json +++ b/data_centre/json_objects/settings.json @@ -93,7 +93,7 @@ "on", "off" ], - "value": "on" + "value": "off" }, "QUIT": { "action": "quit_the_program", @@ -121,7 +121,7 @@ "on", "off" ], - "value": "off" + "value": "on" }, "LOAD_NEXT": { "action": "update_video_settings", @@ -174,7 +174,7 @@ "on", "off" ], - "value": "off" + "value": "on" } }, "video": { diff --git a/display_centre/display.py b/display_centre/display.py index fc7d020..c7544d0 100644 --- a/display_centre/display.py +++ b/display_centre/display.py @@ -7,7 +7,6 @@ class Display(object): MENU_HEIGHT = 10 SELECTOR_WIDTH = 0.47 ROW_OFFSET = 6.0 - VIDEO_DISPLAY_BANNER_TEXT = ' {} {} {}' def __init__(self, tk, video_driver, capture, message_handler, data): self.tk = tk @@ -35,9 +34,10 @@ class Display(object): self.display_text.tag_configure("DISPLAY_MODE", background="black", foreground="magenta") self.display_text.tag_configure("ERROR_MESSAGE", background="red", foreground="white") self.display_text.tag_configure("INFO_MESSAGE", background="blue", foreground="white") - self.display_text.tag_configure("PLAYER_INFO", background="black", foreground="yellow") - self.display_text.tag_configure("COLUMN_NAME", background="black", foreground="cyan") - self.display_text.tag_configure("FUNCTION", background="cyan", foreground="black") + self.display_text.tag_configure("NOW_PLAYER_INFO", background="black", foreground="yellow") + self.display_text.tag_configure("NEXT_PLAYER_INFO", background="black", foreground="cyan") + self.display_text.tag_configure("COLUMN_NAME", background="black", foreground="VioletRed1") + self.display_text.tag_configure("FUNCTION", background="yellow", foreground="black") self.display_text.tag_configure("BROKEN_PATH", background="black", foreground="gray") def _load_display(self): @@ -52,13 +52,20 @@ class Display(object): self.display_text.tag_add("TITLE", 1.19, 1.28) def _load_player(self): - text, banner = self._get_info_for_player() - end_of_text = float("3." + str(len(text))) - end_of_banner = float("3." + str(len(banner))) - self.display_text.insert(END, text + '\n') - self.display_text.tag_add("PLAYER_INFO", 2.0, end_of_text) - self.display_text.insert(END, banner + '\n') - self.display_text.tag_add("PLAYER_INFO", 3.0, end_of_banner) + if self.data.player_mode == 'now': + now_banner = self._get_banner_for_player('now') + self.display_text.insert(END, now_banner + '\n') + self.display_text.tag_add("NOW_PLAYER_INFO", 2.0, 2.0 + self.SELECTOR_WIDTH) + elif self.data.player_mode == 'next': + next_banner = self._get_banner_for_player('next') + self.display_text.insert(END, next_banner + '\n') + self.display_text.tag_add("NEXT_PLAYER_INFO", 2.0, 2.0 + self.SELECTOR_WIDTH) + + status = self._get_status_for_player() + self.display_text.insert(END, status + '\n') + self.display_text.tag_add("NOW_ALPHA", 3.0, 3.17) + self.display_text.tag_add("CAPTURE_ALPHA", 3.18, 3.29) + self.display_text.tag_add("NEXT_ALPHA", 3.29, 3.47) def _load_display_body(self): if self.data.display_mode == 'BROWSER': @@ -156,19 +163,24 @@ class Display(object): self.display_text.tag_remove("SELECT", self.ROW_OFFSET + row, self.ROW_OFFSET + self.SELECTOR_WIDTH + row) - def _get_info_for_player(self): - now_slot, now_status, next_slot, next_status, position, crop_length, start, end = self.video_driver.get_info_for_player_display() - banner = self.create_video_display_banner(start, end, crop_length, position) - time_been = self.format_time_value(position - start) - time_left = self.format_time_value(end - position) + def _get_status_for_player(self): + now_slot, now_status, now_alpha, next_slot, next_status, next_alpha = self.video_driver.get_player_info_for_status() capture_status = self._generate_capture_status() + preview_alpha = self.capture.get_preview_alpha() + + self._set_colour_from_alpha(now_alpha, preview_alpha, next_alpha) now_info = 'NOW [{}] {}'.format(now_slot, now_status) next_info = 'NEXT [{}] {}'.format(next_slot, next_status) capture_info = '{}'.format(capture_status) + return '{:17} {:10} {:17}'.format(now_info[:17], capture_info[:10], next_info[:18]) - return self.VIDEO_DISPLAY_BANNER_TEXT.format(time_been, banner, time_left), \ - '{:17} {:10} {:17}'.format(now_info[:17], capture_info[:10], next_info[:18]) + def _get_banner_for_player(self,player): + start, end, position = self.video_driver.get_player_info_for_banner(player) + banner = self.create_video_display_banner(start, end, position) + time_been = self.format_time_value(position - start) + time_left = self.format_time_value(end - position) + return ' {:5} {} {:5}'.format(time_been, banner, time_left) def _generate_capture_status(self): is_previewing = self.capture.is_previewing @@ -193,8 +205,7 @@ class Display(object): return capture_status @staticmethod - def create_video_display_banner(start, end, crop_length, position): - + def create_video_display_banner(start, end, position): banner_list = ['[', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', @@ -205,13 +216,34 @@ class Display(object): banner_list[0] = '<' elif position > end: banner_list[max] = '>' - elif crop_length != 0: + elif end - start != 0: marker = int(math.floor(float(position - start) / - float(crop_length) * (max - 1)) + 1) + float(end - start) * (max - 1)) + 1) banner_list[marker] = '*' return ''.join(banner_list) + def _set_colour_from_alpha(self, now_alpha, preview_alpha, next_alpha): + upper_bound = 150 + ### scale values + scaled_now = int(( now_alpha / 255 ) * (255 - upper_bound) + upper_bound) + scaled_preview = int(( preview_alpha / 255 ) * (255 - upper_bound) + upper_bound) + scaled_next = int(( next_alpha / 255 ) * (255 - upper_bound) + upper_bound) + + ### convert to hex + now_colour = self.hex_from_rgb(scaled_now, scaled_now, 0) + capture_colour = self.hex_from_rgb(255 * self.capture.is_recording, 0, scaled_preview) + next_colour = self.hex_from_rgb(0, scaled_next, scaled_next) + ### update the colours + self.display_text.tag_configure("NOW_ALPHA", background="black", foreground=now_colour) + self.display_text.tag_configure("CAPTURE_ALPHA", background="black", foreground=capture_colour) + self.display_text.tag_configure("NEXT_ALPHA", background="black", foreground=next_colour) + + @staticmethod + def hex_from_rgb(r, g, b): + return '#%02x%02x%02x' % (r, g, b) + + def _update_screen_every_second(self): self.refresh_display() self.tk.after(500, self._update_screen_every_second) @@ -224,36 +256,6 @@ class Display(object): self.display_text.configure(state='disable') self.display_text.focus_set() - def navigate_menu(self, move_direction, number_items_in_list): - last_list_index = number_items_in_list - 1 - bottom_menu_index = self.top_menu_index + self.MENU_HEIGHT - 1 - - ##self._unhighlight_this_row(self.selected_list_index - self.top_menu_index) - - if move_direction == 'down': - if self.selected_list_index != last_list_index: - if self.selected_list_index == bottom_menu_index: - self.top_menu_index += 1 - self.selected_list_index += 1 - else: - self.top_menu_index = 0 - self.selected_list_index = self.top_menu_index - - elif move_direction == 'up': - if self.selected_list_index != 0: - if self.selected_list_index == self.top_menu_index: - self.top_menu_index -= 1 - self.selected_list_index -= 1 - else: - self.selected_list_index = last_list_index - self.top_menu_index = last_list_index - (self.MENU_HEIGHT - 1) - if self.top_menu_index < 0: - self.top_menu_index = 0 - - ##self._highlight_this_row(self.selected_list_index - self.top_menu_index) - - return - @staticmethod def format_time_value(time_in_seconds): if time_in_seconds < 0: diff --git a/video_centre/capture.py b/video_centre/capture.py index c091be5..66024cd 100644 --- a/video_centre/capture.py +++ b/video_centre/capture.py @@ -157,17 +157,23 @@ class Capture(object): else: return self.device.frame.timestamp / 1000000 - def is_previewing(self): - if self.device.closed or not self.device.preview: - return False + def get_preview_alpha(self): + if self.is_previewing: + return self.device.preview.alpha else: - return True + return 0 - def is_recording(self): - if self.device.recording: - return True - else: - return False + #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 def set_colour(self, u_value, v_value): (u, v) = (128, 128) diff --git a/video_centre/video_driver.py b/video_centre/video_driver.py index 5c93b5d..0b4d332 100644 --- a/video_centre/video_driver.py +++ b/video_centre/video_driver.py @@ -42,7 +42,6 @@ class VideoDriver(object): self.root.after(1000,self.print_status) def begin_playing(self): - # TODO: the first clip will be a demo if self.current_player.try_load(self.get_next_layer_value(), self.show_on_load): self.in_first_load_cycle = True self.wait_for_first_load() @@ -62,14 +61,15 @@ class VideoDriver(object): self.in_current_playing_cycle = False self.in_next_load_cycle = True - self.switch_if_next_is_loaded() + self.switch_players() def switch_players(self): temp_player = self.last_player self.last_player = self.current_player self.current_player = self.next_player self.next_player = temp_player - #self.last_player.exit() + + self.play_video() def play_video(self): print(self.play_on_start) @@ -95,17 +95,22 @@ class VideoDriver(object): if self.next_player.is_loaded(): self.in_next_load_cycle = False self.switch_players() - self.play_video() else: if self.next_player.status != 'ERROR': self.root.after(self.delay, self.switch_if_next_is_loaded) else: self.in_next_load_cycle = False - def get_info_for_player_display(self): - return self.current_player.bankslot_number, self.current_player.status, self.next_player.bankslot_number, \ - self.next_player.status, self.current_player.get_position(), self.current_player.crop_length, \ - self.current_player.start, self.current_player.end + + def get_player_info_for_status(self): + return self.current_player.bankslot_number, self.current_player.status, self.current_player.alpha, \ + self.next_player.bankslot_number, self.next_player.status, self.next_player.alpha + + def get_player_info_for_banner(self, player): + if player == 'now': + return self.current_player.start, self.current_player.end, self.current_player.get_position() + elif player == 'next': + return self.next_player.start, self.next_player.end, self.next_player.get_position() def exit_all_players(self): self.next_player.exit() diff --git a/video_centre/video_player.py b/video_centre/video_player.py index 9caa8c6..87629c0 100644 --- a/video_centre/video_player.py +++ b/video_centre/video_player.py @@ -17,6 +17,7 @@ class VideoPlayer: self.crop_length = 0.0 self.location = '' self.load_attempts = 0 + self.alpha = 0 self.show_toggle_on = True @@ -40,7 +41,7 @@ class VideoPlayer: is_dev_mode, first_screen_arg, second_screen_arg = self.set_screen_size_for_dev_mode() arguments = ['--no-osd', '--layer', str(layer), '--adev', 'local', '--alpha', '0', first_screen_arg, second_screen_arg] if not is_dev_mode: - arguments.append('-b') + arguments.append('-b') ##=0x000000FF') self.status = 'LOADING' print('the location is {}'.format(self.location)) self.omx_player = OMXPlayer(self.location, args=arguments, dbus_name=self.name) @@ -71,9 +72,9 @@ class VideoPlayer: if position > start_threshold: self.status = 'LOADED' if show: - self.omx_player.set_alpha(255) + self.set_alpha_value(255) else: - self.omx_player.set_alpha(0) + self.set_alpha_value(0) self.omx_player.pause() elif self.omx_running: self.root.after(5, self.pause_at_start, show) @@ -81,9 +82,9 @@ class VideoPlayer: def play(self, show): self.status = 'PLAYING' if show: - self.omx_player.set_alpha(255) + self.set_alpha_value(255) else: - self.omx_player.set_alpha(0) + self.set_alpha_value(0) self.omx_player.play() self.pause_at_end() @@ -131,10 +132,14 @@ class VideoPlayer: def toggle_show(self): if self.show_toggle_on: self.show_toggle_on = False - self.omx_player.set_alpha(0) + self.set_alpha_value(0) else: self.show_toggle_on = True - self.omx_player.set_alpha(255) + self.set_alpha_value(255) + + def set_alpha_value(self, amount): + self.omx_player.set_alpha(amount) + self.alpha = amount def seek(self, amount): position = self.get_position()