diff --git a/actions.py b/actions.py index 656f13c..1799d86 100644 --- a/actions.py +++ b/actions.py @@ -19,7 +19,7 @@ class Actions(object): is_file, name = self.data.browser_data.extract_file_type_and_name_from_browser_format( self.data.return_browser_list()[self.display.selected_list_index]['name']) if is_file: - self.data.create_new_slot_mapping_in_first_open(name) + self.data.create_new_slot_mapping_in_first_open(name, self.display.bank_number) else: self.data.browser_data.update_open_folders(name) self.data.rewrite_browser_list() @@ -37,7 +37,7 @@ class Actions(object): getattr(self, action)() def clear_all_slots(self): - self.data.clear_all_slots() + self.data.clear_all_slots(self.display.bank_number) def quit_the_program(self): if self.video_driver.has_omx: @@ -45,7 +45,7 @@ class Actions(object): self.tk.destroy() def load_this_slot_into_next_player(self, slot): - self.data.update_next_slot_number(slot) + self.data.update_next_slot_number(self.display.bank_number,slot) self.video_driver.next_player.reload() def load_slot_0_into_next_player(self): @@ -106,26 +106,52 @@ class Actions(object): def toggle_function(self): self.message_handler.function_on = not self.message_handler.function_on + def next_bank(self): + print('next bank') + self.update_bank(1) + + def previous_bank(self): + self.update_bank(-1) + + def update_bank(self, amount): + new_bank_number = self.data.update_bank_number(self.display.bank_number, amount) + self.display.bank_number = new_bank_number + + def increase_speed(self): + new_rate = self.video_driver.current_player.change_rate(0.5) + current_bank, current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) + self.data.update_slot_rate_to_this(current_bank, current_slot, new_rate) + self.load_this_slot_into_next_player(current_slot) + + def decrease_speed(self): + new_rate = self.video_driver.current_player.change_rate(-0.5) + current_bank, current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) + self.data.update_slot_rate_to_this(current_bank, current_slot, new_rate) + self.load_this_slot_into_next_player(current_slot) + + def print_speed(self): + self.message_handler.set_message('INFO', 'the speed of current video is {}'.format(self.video_driver.current_player.omx_player.rate())) + def set_playing_sample_start_to_current_duration(self): - current_slot = self.video_driver.current_player.slot_number + current_bank, current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) current_position = self.video_driver.current_player.get_position() - self.data.update_slot_start_to_this_time(current_slot, current_position) + self.data.update_slot_start_to_this_time(current_bank, current_slot, current_position) self.load_this_slot_into_next_player(current_slot) def clear_playing_sample_start_time(self): - current_slot = self.video_driver.current_player.slot_number - self.data.update_slot_start_to_this_time(current_slot, -1) + current_bank, current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) + self.data.update_slot_start_to_this_time(current_bank, current_slot, -1) self.load_this_slot_into_next_player(current_slot) def set_playing_sample_end_to_current_duration(self): - current_slot = self.video_driver.current_player.slot_number + current_bank, current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) current_position = self.video_driver.current_player.get_position() - self.data.update_slot_end_to_this_time(current_slot, current_position) + self.data.update_slot_end_to_this_time(current_bank, current_slot, current_position) self.load_this_slot_into_next_player(current_slot) def clear_playing_sample_end_time(self): - current_slot = self.video_driver.current_player.slot_number - self.data.update_slot_end_to_this_time(current_slot, -1) + current_bank, current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) + self.data.update_slot_end_to_this_time(current_bank, current_slot, -1) self.load_this_slot_into_next_player(current_slot) def switch_display_to_hdmi(self): diff --git a/data_centre/browser_data.py b/data_centre/browser_data.py index e50e826..116e11d 100644 --- a/data_centre/browser_data.py +++ b/data_centre/browser_data.py @@ -27,9 +27,9 @@ class BrowserData(object): for browser_line in self.browser_list: is_file, file_name = self.extract_file_type_and_name_from_browser_format(browser_line['name']) if is_file: - is_slotted, slot_number = self._is_file_in_memory_bank(file_name) + is_slotted, bankslot_number = self._is_file_in_memory_bank(file_name) if is_slotted: - browser_line['slot'] = str(slot_number) + browser_line['slot'] = str(bankslot_number) return self.browser_list @@ -71,9 +71,10 @@ class BrowserData(object): ######## used for displaying the mappings in browser view ######## if not self.memory_bank: self.memory_bank = data_centre.data.read_json(data_centre.data.BANK_DATA_JSON) - for index, slot in enumerate(self.memory_bank): - if file_name == slot['name']: - return True, index + for bank_index, bank in enumerate(self.memory_bank): + for slot_index, slot in enumerate(bank): + if file_name == slot['name']: + return True, '{}-{}'.format(bank_index,slot_index) return False, '' diff --git a/data_centre/data.py b/data_centre/data.py index 176bd9b..2bb5824 100644 --- a/data_centre/data.py +++ b/data_centre/data.py @@ -16,10 +16,11 @@ def get_the_current_dir_path(): return os.path.split(current_file_path)[0] BANK_DATA_JSON = 'display_data.json' -NEXT_SLOT_JSON = 'next_slot_number.json' +NEXT_BANKSLOT_JSON = 'next_bankslot_number.json' SETTINGS_JSON = 'settings.json' KEYPAD_MAPPING = 'keypad_action_mapping.json' -EMPTY_SLOT = dict(name='', location='', length=-1, start=-1, end=-1) +EMPTY_SLOT = dict(name='', location='', length=-1, start=-1, end=-1, rate=1) +EMPTY_BANK = [EMPTY_SLOT for i in range(10)] PATH_TO_DATA_OBJECTS = '{}/json_objects/'.format(get_the_current_dir_path()) def read_json(file_name): @@ -51,37 +52,45 @@ class Data(object): def get_screen_size_setting(self): return read_json(SETTINGS_JSON)[0]['options'][0] - def create_new_slot_mapping_in_first_open(self, file_name): + def create_new_slot_mapping_in_first_open(self, file_name, bank_number): ######## used for mapping current video to next available slot ######## memory_bank = read_json(BANK_DATA_JSON) - for index, slot in enumerate(memory_bank): + for index, slot in enumerate(memory_bank[bank_number]): if (not slot['name']): - self.create_new_slot_mapping(index, file_name) + self.create_new_slot_mapping(bank_number, index, file_name) return True return False - def create_new_slot_mapping(self, slot_number, file_name): + def create_new_slot_mapping(self,bank_number, slot_number, file_name): ######## used for mapping current video to a specific slot ######## has_location, location = self._get_path_for_file(file_name) print('file_name:{},has_location:{}, location:{}'.format(file_name,has_location, location)) length = self._get_length_for_file(location) - new_slot = dict(name=file_name, location=location, length=length, start=-1, end=-1) - self._update_a_slots_data(slot_number, new_slot) + new_slot = dict(name=file_name, location=location, length=length, start=-1, end=-1, rate=1) + self._update_a_slots_data(bank_number, slot_number, new_slot) @staticmethod - def clear_all_slots(): - memory_bank = read_json(BANK_DATA_JSON) - for index, slot in enumerate(memory_bank): - memory_bank[index] = EMPTY_SLOT + def clear_all_slots(bank_number): + memory_bank = read_json(BANK_DATA_JSON) + memory_bank[bank_number] = EMPTY_BANK update_json(BANK_DATA_JSON, memory_bank) - def update_next_slot_number(self, new_value): + def update_bank_number(self, current_bank_number, amount): memory_bank = read_json(BANK_DATA_JSON) - if memory_bank[new_value]['location'] == '': + if(memory_bank[-1] != EMPTY_BANK): + memory_bank.append(EMPTY_BANK) + elif(memory_bank[-1] == EMPTY_BANK and memory_bank[-2] == EMPTY_BANK): + memory_bank.pop() + update_json(BANK_DATA_JSON, memory_bank) + return (current_bank_number+amount)%(len(memory_bank)) + + def update_next_slot_number(self, bank_number, new_value): + memory_bank = read_json(BANK_DATA_JSON) + if memory_bank[bank_number][new_value]['location'] == '': print('its empty!') self.message_handler.set_message('INFO', 'the slot you pressed is empty') else: - update_json(NEXT_SLOT_JSON, new_value) + update_json(NEXT_BANKSLOT_JSON, '{}-{}'.format(bank_number,new_value)) def add_open_folder(self, folder_name): self.browser_data.update_open_folders(folder_name) @@ -108,6 +117,20 @@ class Data(object): def return_browser_list(self): return self.browser_data.browser_list + @classmethod + def split_bankslot_number(cls, slot_number): + split = slot_number.split('-') + is_bank_num_int , converted_bank_number = cls.try_convert_string_to_int(split[0]) + is_slot_num_int , converted_slot_number = cls.try_convert_string_to_int(split[1]) + return converted_bank_number, converted_slot_number + + @staticmethod + def try_convert_string_to_int(string_input): + try: + return True , int(string_input) + except ValueError: + return False , '*' + @staticmethod def get_settings_data(): return read_json(SETTINGS_JSON) @@ -122,30 +145,36 @@ class Data(object): def get_next_context(self): ######## loads the slot details, uses settings to modify them and then set next slot number ######## - next_slot_number = read_json(NEXT_SLOT_JSON) + next_bankslot_number = read_json(NEXT_BANKSLOT_JSON) memory_bank = read_json(BANK_DATA_JSON) - next_slot_details = memory_bank[next_slot_number] + bank_num , slot_num = self.split_bankslot_number(next_bankslot_number) + next_slot_details = memory_bank[bank_num][slot_num] start_value = next_slot_details['start'] end_value = next_slot_details['end'] length = next_slot_details['length'] context = dict(location=next_slot_details['location'], name=next_slot_details['name'], - length=next_slot_details['length'], start=start_value, end=end_value, - slot_number=next_slot_number) + length=next_slot_details['length'], rate=next_slot_details['rate'], start=start_value, end=end_value, + bankslot_number=next_bankslot_number) return context - def update_slot_start_to_this_time(self, slot_number, position): + def update_slot_start_to_this_time(self, bank_number, slot_number, position): memory_bank = read_json(BANK_DATA_JSON) - memory_bank[slot_number]['start'] = position + print('bank_no {} , slot_no {} '.format(bank_number, slot_number)) + memory_bank[bank_number][slot_number]['start'] = position update_json(BANK_DATA_JSON, memory_bank) - def update_slot_end_to_this_time(self, slot_number, position): + def update_slot_end_to_this_time(self,bank_number, slot_number, position): memory_bank = read_json(BANK_DATA_JSON) - memory_bank[slot_number]['end'] = position + memory_bank[bank_number][slot_number]['end'] = position + update_json(BANK_DATA_JSON, memory_bank) + + def update_slot_rate_to_this(self,bank_number, slot_number, rate): + memory_bank = read_json(BANK_DATA_JSON) + memory_bank[bank_number][slot_number]['rate'] = rate update_json(BANK_DATA_JSON, memory_bank) def _get_length_for_file(self, path): - print('getting length for: {}'.format(path)) if self.has_omx: temp_player = OMXPlayer(path, args=['--alpha', '0'], dbus_name='t.t') duration = temp_player.duration() @@ -162,10 +191,10 @@ class Data(object): return False, '' @staticmethod - def _update_a_slots_data(slot_number, slot_info): + def _update_a_slots_data(bank_number, slot_number, slot_info): ######## overwrite a given slots info with new data ######## memory_bank = read_json(BANK_DATA_JSON) - memory_bank[slot_number] = slot_info + memory_bank[bank_number][slot_number] = slot_info update_json(BANK_DATA_JSON, memory_bank) @staticmethod diff --git a/data_centre/json_objects/display_data.json b/data_centre/json_objects/display_data.json index 718bf4a..ad288fd 100644 --- a/data_centre/json_objects/display_data.json +++ b/data_centre/json_objects/display_data.json @@ -1 +1 @@ -[{"name": "colour_pixel_01.mp4", "length": 49.28, "end": -1, "start": -1, "location": "/media/pi/TIM1/videos_to_play/colour_pixel_01.mp4"}, {"name": "colour_pixel_02.mp4", "start": -1, "location": "/media/pi/TIM1/videos_to_play/colour_pixel_02.mp4", "length": 87.04, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}, {"name": "", "length": -1, "location": "", "start": -1, "end": -1}] \ No newline at end of file +[[{"rate": 3.5, "location": "/media/pi/TIM1/videos_to_play/colour_pixel_01.mp4", "length": 49.28, "end": -1, "start": -1, "name": "colour_pixel_01.mp4"}, {"rate": 1, "location": "/media/pi/TIM1/videos_to_play/long_spinning.mp4", "length": 804.245, "end": -1, "start": -1, "name": "long_spinning.mp4"}, {"rate": 0.5, "location": "/media/pi/TIM1/Test.mp4", "length": 599.585, "end": -1, "start": -1, "name": "Test.mp4"}, {"rate": 3.0, "location": "/media/pi/TIM1/teaser1.mp4", "length": 3.114, "end": -1, "start": -1, "name": "teaser1.mp4"}, {"rate": 0.5, "start": -1, "length": 3.114, "end": -1, "location": "/media/pi/TIM1/teaser1.mp4", "name": "teaser1.mp4"}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}], [{"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}, {"rate": 1, "location": "", "length": -1, "end": -1, "start": -1, "name": ""}]] \ No newline at end of file diff --git a/data_centre/json_objects/keypad_action_mapping.json b/data_centre/json_objects/keypad_action_mapping.json index 24b6f87..497820b 100644 --- a/data_centre/json_objects/keypad_action_mapping.json +++ b/data_centre/json_objects/keypad_action_mapping.json @@ -31,22 +31,22 @@ "DEFAULT": ["toggle_function"] }, "j": { - "DEFAULT": ["load_slot_0_into_next_player"] + "DEFAULT": ["load_slot_0_into_next_player","previous_bank"] }, "k": { - "DEFAULT": ["load_slot_1_into_next_player"] + "DEFAULT": ["load_slot_1_into_next_player","next_bank"] }, "l": { "DEFAULT": ["load_slot_2_into_next_player","clear_all_slots"] }, "m": { - "DEFAULT": ["load_slot_3_into_next_player"] + "DEFAULT": ["load_slot_3_into_next_player","decrease_speed"] }, "n": { - "DEFAULT": ["load_slot_4_into_next_player"] + "DEFAULT": ["load_slot_4_into_next_player","increase_speed"] }, "o": { - "DEFAULT": ["load_slot_5_into_next_player"] + "DEFAULT": ["load_slot_5_into_next_player","print_speed"] }, "p": { "DEFAULT": ["load_slot_6_into_next_player"] diff --git a/data_centre/json_objects/next_bankslot_number.json b/data_centre/json_objects/next_bankslot_number.json new file mode 100644 index 0000000..6d77ead --- /dev/null +++ b/data_centre/json_objects/next_bankslot_number.json @@ -0,0 +1 @@ +"0-3" \ No newline at end of file diff --git a/data_centre/json_objects/next_slot_number.json b/data_centre/json_objects/next_slot_number.json deleted file mode 100644 index c227083..0000000 --- a/data_centre/json_objects/next_slot_number.json +++ /dev/null @@ -1 +0,0 @@ -0 \ No newline at end of file diff --git a/display_centre/display.py b/display_centre/display.py index 62c0d9c..8dab461 100644 --- a/display_centre/display.py +++ b/display_centre/display.py @@ -7,7 +7,7 @@ class Display(object): MENU_HEIGHT = 10 SELECTOR_WIDTH = 0.47 ROW_OFFSET = 6.0 - VIDEO_DISPLAY_TEXT = ' NOW [{}] {} NEXT [{}] {}' + VIDEO_DISPLAY_TEXT = ' NOW [{}] {} NEXT [{}] {}' VIDEO_DISPLAY_BANNER_TEXT = ' {} {} {}' def __init__(self, tk, video_driver, message_handler, data): @@ -18,6 +18,7 @@ class Display(object): self.display_mode = "SAMPLER" self.control_mode = 'PLAYER' + self.bank_number = 0 self.top_menu_index = 0 self.selected_list_index = self.top_menu_index self.browser_list = self.data.rewrite_browser_list() @@ -48,7 +49,7 @@ class Display(object): self.display_text.pack() def _load_title(self): - self.display_text.insert(END, '================== r_e_c_u_r ================== \n') + self.display_text.insert(END, '================== r_e_c_u_r:beta ============= \n') self.display_text.tag_add("TITLE", 1.19, 1.28) def _load_player(self): @@ -71,20 +72,21 @@ class Display(object): self._highlight_this_row(self.selected_list_index - self.top_menu_index) def _load_sampler(self): - bank_data = self.data.get_sampler_data() + bank_data = self.data.get_sampler_data()[self.bank_number] self.display_text.insert(END, '------------------ ------------------ \n') self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29) - self.display_text.insert(END, '{:^4} {:<22} {:<4} {:<4} {:<4} \n'.format( - 'slot', 'name', 'length', 'start', 'end')) + self.display_text.insert(END, '{:^6} {:<16} {:<4} {:<4} {:<4} {:<4} \n'.format( + '{}-slot'.format(self.bank_number), 'name', 'length', 'start', 'end', 'rate')) for index, slot in enumerate(bank_data): name_without_extension = slot['name'].rsplit('.',1)[0] - self.display_text.insert(END, '{:^4} {:<22} {:<4} {:<4} {:<4} \n'.format( + self.display_text.insert(END, '{:^4} {:<18} {:<4} {:<4} {:<4} {:<4} \n'.format( index, name_without_extension[0:22], self.format_time_value(slot['length']), - self.format_time_value(slot['start']), self.format_time_value(slot['end']))) - if self.video_driver.current_player.slot_number is '-': - self.selected_list_index = 0 + self.format_time_value(slot['start']), self.format_time_value(slot['end']), slot['rate'])) + current_bank , current_slot = self.data.split_bankslot_number(self.video_driver.current_player.bankslot_number) + if current_bank is self.bank_number: + self.selected_list_index = current_slot else: - self.selected_list_index = self.video_driver.current_player.slot_number + self.selected_list_index = 0 def _load_browser(self): browser_list = self.data.return_browser_list() @@ -155,7 +157,7 @@ class Display(object): time_left = self.format_time_value(end - position) return self.VIDEO_DISPLAY_BANNER_TEXT.format(time_been, banner, time_left), \ - self.VIDEO_DISPLAY_TEXT.format(now_slot, now_status, next_slot, next_status) + ' NOW [{}] {} NEXT [{}] {}'.format(now_slot, now_status, next_slot, next_status) @staticmethod def create_video_display_banner(start, end, crop_length, position): diff --git a/video_centre/video_driver.py b/video_centre/video_driver.py index 88843e2..a7e16b5 100644 --- a/video_centre/video_driver.py +++ b/video_centre/video_driver.py @@ -87,7 +87,7 @@ class VideoDriver(object): def get_info_for_player_display(self): if self.has_omx: - return self.current_player.slot_number, self.current_player.status, self.next_player.slot_number, \ + 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 else: diff --git a/video_centre/video_player.py b/video_centre/video_player.py index 9676e85..82b656a 100644 --- a/video_centre/video_player.py +++ b/video_centre/video_player.py @@ -14,9 +14,10 @@ class video_player: self.omx_running = False self.status = 'N/A' self.total_length = 0.0 - self.slot_number = '-' + self.bankslot_number = '*-*' self.start = -1.0 self.end = -1.0 + self.rate = 1 self.crop_length = 0.0 self.location = '' self.load_attempts = 0 @@ -53,9 +54,11 @@ class video_player: if self.start > 0.5: self.set_position(self.start - 0.5) self.pause_at_start() + print('set rate to {}'.format(self.rate)) + self.omx_player.set_rate(self.rate) self.load_attempts = 0 return True - except: + except ValueError: self.message_handler.set_message('ERROR', 'load attempt fail') return False @@ -108,7 +111,8 @@ class video_player: #self.total_length = next_context['length'] self.start = next_context['start'] self.end = next_context['end'] - self.slot_number = next_context['slot_number'] + self.bankslot_number = next_context['bankslot_number'] + self.rate = next_context['rate'] def toggle_pause(self): self.omx_player.play_pause() @@ -123,6 +127,17 @@ class video_player: else: self.message_handler.set_message('INFO', 'can not seek outside range') + def change_rate(self, amount): + new_rate = self.rate + amount + if (new_rate > self.omx_player.minimum_rate() and new_rate < self.omx_player.maximum_rate()): + updated_speed = self.omx_player.set_rate(new_rate) + self.rate = new_rate + print('max rate {} , min rate {} '.format(self.omx_player.maximum_rate() ,self.omx_player.minimum_rate())) + return new_rate + else: + self.message_handler.set_message('INFO', 'can not set speed outside of range') + return self.rate + def set_position(self, position): self.omx_player.set_position(position) @@ -150,7 +165,7 @@ class fake_video_player: self.omx_running = False self.status = 'N/A' self.duration = 0 - self.slot_number = '-' + self.bankslot_number = '*-*' self.start = -1 self.end = -1 self.length = 0