import kivy kivy.require("2.0.0") from kivy.config import Config Config.set("graphics", "width", "480") Config.set("graphics", "height", "320") from audio_player import AudioPlayer from config_handler import ConfigHandler from constants import CONFIG_ENABLE_DARK_MODE_KEY from kivymd.app import MDApp from muezzin_carousel import MuezzinCarousel audio_player = AudioPlayer() config_handler = ConfigHandler() enable_dark_mode = config_handler.get_setting(CONFIG_ENABLE_DARK_MODE_KEY) class MuezzinApp(MDApp): """ Main app for Muezzing """ def build(self): """ Sets the icon and theme parameters of Kivy, and returns an instance of the MuezzinCarousel :return: an instance of MuezzinCarousel """ self.icon = "res/mosque_green.png"
playlist = config.get("audio_playlist", {}) comm["audio_players"] = audio_players_count comm["universe"] = universe comm["address"] = address comm["audio"] = {} artnetReceiver = ArtNetReceiver(universe, comm = comm) for i in range(audio_players_count): # Create Player ap = AudioPlayer(address, playlist, artnetReceiver, comm) # Get Amount of Channels it is using address += ap.getDMXFootprint() or 4 ap.printDMXFootprint() # add player to list audio_players[i] = ap print "Running ArtnetReceiver" artnetReceiver.start() while True: try: time.sleep(5)
class Artemis(QMainWindow, Ui_MainWindow): """Main application class.""" def __init__(self): """Set all connections of the application.""" super().__init__() self.setupUi(self) self.setWindowTitle("ARTΣMIS " + __VERSION__) self.set_initial_size() self.closing = False self.download_window = DownloadWindow() self.download_window.complete.connect(self.action_after_download) self.actionExit.triggered.connect(qApp.quit) self.action_update_database.triggered.connect(self.ask_if_download) self.action_check_db_ver.triggered.connect(self.check_db_ver) self.action_sigidwiki_com.triggered.connect( lambda: webbrowser.open(Constants.SIGIDWIKI)) self.action_add_a_signal.triggered.connect( lambda: webbrowser.open(Constants.ADD_SIGNAL_LINK)) self.action_aresvalley_com.triggered.connect( lambda: webbrowser.open(Constants.ARESVALLEY_LINK)) self.action_forum.triggered.connect( lambda: webbrowser.open(Constants.FORUM_LINK)) self.action_rtl_sdr_com.triggered.connect( lambda: webbrowser.open(Constants.RTL_SDL_LINK)) self.action_github.triggered.connect( lambda: webbrowser.open(Constants.GITHUB_REPO)) self.db = None self.current_signal_name = '' self.signal_names = [] self.total_signals = 0 # Forecast self.forecast_info_btn.clicked.connect( lambda: webbrowser.open(Constants.SPACE_WEATHER_INFO)) self.forecast_data = ForecastData(self) self.update_forecast_bar.clicked.connect(self.start_update_forecast) self.update_forecast_bar.set_idle() self.forecast_data.update_complete.connect(self.update_forecast) # Spaceweather manager self.spaceweather_screen = SpaceWeatherManager(self) self.theme_manager = ThemeManager(self) self.filters = Filters(self) # ####################################################################################### UrlColors = namedtuple("UrlColors", ["inactive", "active", "clicked"]) self.url_button.colors = UrlColors("#9f9f9f", "#4c75ff", "#942ccc") self.category_labels = [ self.cat_mil, self.cat_rad, self.cat_active, self.cat_inactive, self.cat_ham, self.cat_comm, self.cat_avi, self.cat_mar, self.cat_ana, self.cat_dig, self.cat_trunked, self.cat_utility, self.cat_sat, self.cat_navi, self.cat_interf, self.cat_num_stat, self.cat_time_sig ] self.property_labels = [ self.freq_lab, self.band_lab, self.mode_lab, self.modul_lab, self.loc_lab, self.acf_lab, self.description_text ] self.url_button.clicked.connect(self.go_to_web_page_signal) # GFD self.freq_search_gfd_btn.clicked.connect( partial(self.go_to_gfd, GfdType.FREQ)) self.location_search_gfd_btn.clicked.connect( partial(self.go_to_gfd, GfdType.LOC)) self.gfd_line_edit.returnPressed.connect( partial(self.go_to_gfd, GfdType.LOC)) # ########################################################################################## # Left list widget and search bar. self.search_bar.textChanged.connect(self.display_signals) self.signals_list.currentItemChanged.connect(self.display_specs) self.signals_list.itemDoubleClicked.connect(self.set_visible_tab) self.audio_widget = AudioPlayer(self.play, self.pause, self.stop, self.volume, self.loop, self.audio_progress, self.active_color, self.inactive_color) BandLabel = namedtuple("BandLabel", ["left", "center", "right"]) self.band_labels = [ BandLabel(self.elf_left, self.elf, self.elf_right), BandLabel(self.slf_left, self.slf, self.slf_right), BandLabel(self.ulf_left, self.ulf, self.ulf_right), BandLabel(self.vlf_left, self.vlf, self.vlf_right), BandLabel(self.lf_left, self.lf, self.lf_right), BandLabel(self.mf_left, self.mf, self.mf_right), BandLabel(self.hf_left, self.hf, self.hf_right), BandLabel(self.vhf_left, self.vhf, self.vhf_right), BandLabel(self.uhf_left, self.uhf, self.uhf_right), BandLabel(self.shf_left, self.shf, self.shf_right), BandLabel(self.ehf_left, self.ehf, self.ehf_right), ] self.main_tab.currentChanged.connect(self.hide_show_right_widget) self.updates_controller = UpdatesController(__LATEST_VERSION__, self) self.updates_controller.start() self.action_check_software_version.triggered.connect( self.updates_controller.start_verify_software_version) # Final operations. self.theme_manager.start() self.load_db() self.display_signals() def action_after_download(self): """Decide what to do after a successful download. If a new database was downloaded, show the signals.""" if self.download_window.target is DownloadTarget.DATA_FOLDER: self.show_downloaded_signals() @pyqtSlot() def hide_show_right_widget(self): """Hide the audio player when forecast tabs are displayed.""" if self.main_tab.currentWidget() == self.forecast_tab: self.fixed_audio_and_image.setVisible(False) elif not self.fixed_audio_and_image.isVisible(): self.fixed_audio_and_image.setVisible(True) @pyqtSlot() def set_visible_tab(self): """Set the current main tab when double-clicking a signal name. Switch between main and filter tab when double-clicking multiple times.""" set_main = False if self.main_tab.currentWidget() != self.signal_properties_tab: self.main_tab.setCurrentWidget(self.signal_properties_tab) set_main = True if self.signal_tab.currentWidget() != self.signal_main_tab or set_main: self.signal_tab.setCurrentWidget(self.signal_main_tab) else: self.signal_tab.setCurrentWidget(self.filter_tab) @pyqtSlot() def start_update_forecast(self): """Start the update of the 3-day forecast screen. Start the corresponding thread. """ if not self.forecast_data.is_updating: self.update_forecast_bar.set_updating() self.forecast_data.update() @pyqtSlot(bool) def update_forecast(self, status_ok): """Update the 3-day forecast screen after a successful download. If the download was not successful throw a warning. In any case remove the downloaded data. """ self.update_forecast_bar.set_idle() if status_ok: self.forecast_data.update_all_labels() elif not self.closing: pop_up(self, title=Messages.BAD_DOWNLOAD, text=Messages.BAD_DOWNLOAD_MSG).show() self.forecast_data.remove_data() @pyqtSlot() def go_to_gfd(self, by): """Open a browser tab with the GFD site. Make the search by frequency or location. Argument: by -- either GfdType.FREQ or GfdType.LOC. """ query = "/?q=" if by is GfdType.FREQ: value_in_mhz = self.freq_gfd.value() \ * Constants.CONVERSION_FACTORS[self.unit_freq_gfd.currentText()] \ / Constants.CONVERSION_FACTORS["MHz"] query += str(value_in_mhz) elif by is GfdType.LOC: query += self.gfd_line_edit.text() try: webbrowser.open(Constants.GFD_SITE + query.lower()) except Exception: pass def set_initial_size(self): """Handle high resolution screens. Set bigger sizes for all the relevant fixed-size widgets. """ d = QDesktopWidget().availableGeometry() w = d.width() h = d.height() self.showMaximized() if w > 3000 or h > 2000: self.fixed_audio_and_image.setFixedSize(540, 1150) self.fixed_audio_and_image.setMaximumSize(540, 1150) audio_btn_h, audio_btn_w = 90, 90 self.play.setFixedSize(audio_btn_h, audio_btn_w) self.pause.setFixedSize(audio_btn_h, audio_btn_w) self.stop.setFixedSize(audio_btn_h, audio_btn_w) self.loop.setFixedSize(audio_btn_h, audio_btn_w) self.lower_freq_spinbox.setFixedWidth(200) self.upper_freq_spinbox.setFixedWidth(200) self.lower_freq_filter_unit.setFixedWidth(120) self.upper_freq_filter_unit.setFixedWidth(120) self.lower_freq_confidence.setFixedWidth(120) self.upper_freq_confidence.setFixedWidth(120) self.lower_band_spinbox.setFixedWidth(200) self.upper_band_spinbox.setFixedWidth(200) self.lower_band_filter_unit.setFixedWidth(120) self.upper_band_filter_unit.setFixedWidth(120) self.lower_band_confidence.setFixedWidth(120) self.upper_band_confidence.setFixedWidth(120) self.freq_gfd.setFixedWidth(200) self.unit_freq_gfd.setFixedWidth(120) self.mode_tree_widget.setMinimumWidth(500) self.modulation_list.setMinimumWidth(500) self.locations_list.setMinimumWidth(500) self.audio_progress.setFixedHeight(20) self.volume.setStyleSheet(""" QSlider::groove:horizontal { height: 12px; background: #7a7a7a; margin: 0 10px; border-radius: 6px } QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 gray, stop:0.5 white, stop:1.0 gray); border: 1px solid #5c5c5c; width: 28px; margin: -8px -8px; border-radius: 14px; } """) @pyqtSlot() def download_db(self): """Start the database download. Do nothing if already downloading. """ if not self.download_window.isVisible(): self.download_window.activate( get_download_target(DownloadTarget.DATA_FOLDER)) @pyqtSlot() def ask_if_download(self): """Check if the database is at its latest version. If a new database is available automatically start the download. If not ask if should download it anyway. If already downloading do nothing. Handle possible connection errors. """ if not self.download_window.isVisible(): db_path = os.path.join(Constants.DATA_FOLDER, Database.NAME) try: with open(db_path, "rb") as file_db: db = file_db.read() except Exception: self.download_db() else: try: is_checksum_ok = checksum_ok(db, get_db_hash_code()) except Exception: pop_up(self, title=Messages.NO_CONNECTION, text=Messages.NO_CONNECTION_MSG).show() else: if not is_checksum_ok: self.download_db() else: answer = pop_up( self, title=Messages.UP_TO_DATE, text=Messages.UP_TO_DATE_MSG, informative_text=Messages.DOWNLOAD_ANYWAY_QUESTION, is_question=True, default_btn=QMessageBox.No).exec() if answer == QMessageBox.Yes: self.download_db() @pyqtSlot() def check_db_ver(self): """Check if the database is at its latest version. If a new database version is available, ask if it should be downloaded. If a new database version is not available display a message. If already downloading do nothing. Handle possible connection errors. """ if not self.download_window.isVisible(): db_path = os.path.join(Constants.DATA_FOLDER, Database.NAME) answer = None try: with open(db_path, "rb") as file_db: db = file_db.read() except Exception: answer = pop_up( self, title=Messages.NO_DB, text=Messages.NO_DB_AVAIL, informative_text=Messages.DOWNLOAD_NOW_QUESTION, is_question=True).exec() if answer == QMessageBox.Yes: self.download_db() else: try: is_checksum_ok = checksum_ok(db, get_db_hash_code()) except Exception: pop_up(self, title=Messages.NO_CONNECTION, text=Messages.NO_CONNECTION_MSG).show() else: if is_checksum_ok: pop_up(self, title=Messages.UP_TO_DATE, text=Messages.UP_TO_DATE_MSG).show() else: answer = pop_up( self, title=Messages.DB_NEW_VER, text=Messages.DB_NEW_VER_MSG, informative_text=Messages.DOWNLOAD_NOW_QUESTION, is_question=True).exec() if answer == QMessageBox.Yes: self.download_db() @pyqtSlot() def show_downloaded_signals(self): """Load and display the database signal list.""" self.search_bar.setEnabled(True) self.load_db() self.display_signals() def load_db(self): """Load the database from file. Populate the signals list and set the total number of signals. Handle possible missing file error. """ try: self.db = read_csv(os.path.join(Constants.DATA_FOLDER, Database.NAME), sep=Database.DELIMITER, header=None, index_col=0, dtype={name: str for name in Database.STRINGS}, names=Database.NAMES) except FileNotFoundError: self.search_bar.setDisabled(True) answer = pop_up(self, title=Messages.NO_DB, text=Messages.NO_DB_AVAIL, informative_text=Messages.DOWNLOAD_NOW_QUESTION, is_question=True).exec() if answer == QMessageBox.Yes: self.download_db() else: # Avoid a crash if there are duplicated signals self.db = self.db.groupby(level=0).first() self.signal_names = self.db.index self.total_signals = len(self.signal_names) self.db.fillna(Constants.UNKNOWN, inplace=True) self.db[Signal.ACF] = ACFValue.list_from_series( self.db[Signal.ACF]) self.db[Signal.WIKI_CLICKED] = False self.update_status_tip(self.total_signals) self.signals_list.clear() self.signals_list.addItems(self.signal_names) self.signals_list.setCurrentItem(None) self.modulation_list.addItems(self.collect_list(Signal.MODULATION)) self.locations_list.addItems(self.collect_list(Signal.LOCATION)) def collect_list(self, list_property, separator=Constants.FIELD_SEPARATOR): """Collect all the entries of a QListWidget. Handle multiple entries in one item separated by a separator. Keyword argument: separator -- the separator character for multiple-entries items. """ values = self.db[list_property] values = list( set([ x.strip() for value in values[values != Constants.UNKNOWN] for x in value.split(separator) ])) values.sort() values.insert(0, Constants.UNKNOWN) return values @pyqtSlot() def activate_if_toggled(self, radio_btn, *widgets): """If radio_btn is toggled, activate all *widgets. Do nothing otherwise. """ toggled = radio_btn.isChecked() for w in widgets[: -1]: # Neglect the bool coming from the emitted signal. w.setEnabled(toggled) @pyqtSlot() def display_signals(self): """Display all the signal names which matches the applied filters.""" text = self.search_bar.text() available_signals = 0 for index, signal_name in enumerate(self.signal_names): if text.lower() in signal_name.lower() and self.filters.ok( signal_name): self.signals_list.item(index).setHidden(False) available_signals += 1 else: self.signals_list.item(index).setHidden(True) # Remove selected item. self.signals_list.setCurrentItem(None) self.update_status_tip(available_signals) def update_status_tip(self, available_signals): """Display the number of displayed signals in the status tip.""" if available_signals < self.total_signals: self.statusbar.setStyleSheet(f'color: {self.active_color}') else: self.statusbar.setStyleSheet(f'color: {self.inactive_color}') self.statusbar.showMessage( f"{available_signals} out of {self.total_signals} signals displayed." ) @pyqtSlot(QListWidgetItem, QListWidgetItem) def display_specs(self, item, previous_item): """Display the signal properties. 'item' is the item corresponding to the selected signal 'previous_item' is unused. """ self.display_spectrogram() if item is not None: self.current_signal_name = item.text() self.name_lab.setText(self.current_signal_name) self.name_lab.setAlignment(Qt.AlignHCenter) current_signal = self.db.loc[self.current_signal_name] self.url_button.setEnabled(True) if not current_signal.at[Signal.WIKI_CLICKED]: self.url_button.setStyleSheet( f"color: {self.url_button.colors.active};") else: self.url_button.setStyleSheet( f"color: {self.url_button.colors.clicked};") category_code = current_signal.at[Signal.CATEGORY_CODE] undef_freq = is_undef_freq(current_signal) undef_band = is_undef_band(current_signal) if not undef_freq: self.freq_lab.setText( format_numbers(current_signal.at[Signal.INF_FREQ], current_signal.at[Signal.SUP_FREQ])) else: self.freq_lab.setText("Undefined") if not undef_band: self.band_lab.setText( format_numbers(current_signal.at[Signal.INF_BAND], current_signal.at[Signal.SUP_BAND])) else: self.band_lab.setText("Undefined") self.mode_lab.setText(current_signal.at[Signal.MODE]) self.modul_lab.setText(current_signal.at[Signal.MODULATION]) self.loc_lab.setText(current_signal.at[Signal.LOCATION]) self.acf_lab.setText( ACFValue.concat_strings(current_signal.at[Signal.ACF])) self.description_text.setText( current_signal.at[Signal.DESCRIPTION]) for cat, cat_lab in zip(category_code, self.category_labels): if cat == '0': cat_lab.setStyleSheet(f"color: {self.inactive_color};") elif cat == '1': cat_lab.setStyleSheet(f"color: {self.active_color};") self.set_band_range(current_signal) self.audio_widget.set_audio_player(self.current_signal_name) else: self.url_button.setEnabled(False) self.url_button.setStyleSheet( f"color: {self.url_button.colors.inactive};") self.current_signal_name = '' self.name_lab.setText("No Signal") self.name_lab.setAlignment(Qt.AlignHCenter) for lab in self.property_labels: lab.setText(Constants.UNKNOWN) for lab in self.category_labels: lab.setStyleSheet(f"color: {self.inactive_color};") self.set_band_range() self.audio_widget.set_audio_player() def display_spectrogram(self): """Display the selected signal's waterfall.""" default_pic = Constants.DEFAULT_NOT_SELECTED item = self.signals_list.currentItem() if item: spectrogram_name = item.text() path_spectr = os.path.join( Constants.SPECTRA_FOLDER, spectrogram_name + Constants.SPECTRA_EXT) if not QFileInfo(path_spectr).exists(): path_spectr = Constants.DEFAULT_NOT_AVAILABLE else: path_spectr = default_pic self.spectrogram.setPixmap(QPixmap(path_spectr)) def activate_band_category(self, band_label, activate=True): """Highlight the given band_label. If activate is False remove the highlight (default to True). """ color = self.active_color if activate else self.inactive_color for label in band_label: label.setStyleSheet(f"color: {color};") def set_band_range(self, current_signal=None): """Highlight the signal's band labels. If no signal is selected remove all highlights. """ if current_signal is not None and not is_undef_freq(current_signal): lower_freq = safe_cast(current_signal.at[Signal.INF_FREQ], int) upper_freq = safe_cast(current_signal.at[Signal.SUP_FREQ], int) zipped = list(zip(Constants.BANDS, self.band_labels)) for i, w in enumerate(zipped): band, band_label = w if lower_freq >= band.lower and lower_freq < band.upper: self.activate_band_category(band_label) for uband, uband_label in zipped[i + 1:]: if upper_freq > uband.lower: self.activate_band_category(uband_label) else: self.activate_band_category(uband_label, False) break else: self.activate_band_category(band_label, False) else: for band_label in self.band_labels: self.activate_band_category(band_label, False) @pyqtSlot() def go_to_web_page_signal(self): """Go the web page of the signal's wiki. Do nothing if no signal is selected. """ if self.current_signal_name: self.url_button.setStyleSheet( f"color: {self.url_button.colors.clicked}") webbrowser.open(self.db.at[self.current_signal_name, Signal.URL]) self.db.at[self.current_signal_name, Signal.WIKI_CLICKED] = True def closeEvent(self, event): """Extends closeEvent of QMainWindow. Shutdown all active threads and close all open windows.""" self.closing = True if self.download_window.isVisible(): self.download_window.close() if self.space_weather_data.is_updating: self.space_weather_data.shutdown_thread() if self.forecast_data.is_updating: self.forecast_data.shutdown_thread() super().closeEvent(event)
def __init__(self): """Set all connections of the application.""" super().__init__() self.setupUi(self) self.setWindowTitle("ARTΣMIS " + __VERSION__) self.set_initial_size() self.closing = False self.download_window = DownloadWindow() self.download_window.complete.connect(self.action_after_download) self.actionExit.triggered.connect(qApp.quit) self.action_update_database.triggered.connect(self.ask_if_download) self.action_check_db_ver.triggered.connect(self.check_db_ver) self.action_sigidwiki_com.triggered.connect( lambda: webbrowser.open(Constants.SIGIDWIKI)) self.action_add_a_signal.triggered.connect( lambda: webbrowser.open(Constants.ADD_SIGNAL_LINK)) self.action_aresvalley_com.triggered.connect( lambda: webbrowser.open(Constants.ARESVALLEY_LINK)) self.action_forum.triggered.connect( lambda: webbrowser.open(Constants.FORUM_LINK)) self.action_rtl_sdr_com.triggered.connect( lambda: webbrowser.open(Constants.RTL_SDL_LINK)) self.action_github.triggered.connect( lambda: webbrowser.open(Constants.GITHUB_REPO)) self.db = None self.current_signal_name = '' self.signal_names = [] self.total_signals = 0 # Forecast self.forecast_info_btn.clicked.connect( lambda: webbrowser.open(Constants.SPACE_WEATHER_INFO)) self.forecast_data = ForecastData(self) self.update_forecast_bar.clicked.connect(self.start_update_forecast) self.update_forecast_bar.set_idle() self.forecast_data.update_complete.connect(self.update_forecast) # Spaceweather manager self.spaceweather_screen = SpaceWeatherManager(self) self.theme_manager = ThemeManager(self) self.filters = Filters(self) # ####################################################################################### UrlColors = namedtuple("UrlColors", ["inactive", "active", "clicked"]) self.url_button.colors = UrlColors("#9f9f9f", "#4c75ff", "#942ccc") self.category_labels = [ self.cat_mil, self.cat_rad, self.cat_active, self.cat_inactive, self.cat_ham, self.cat_comm, self.cat_avi, self.cat_mar, self.cat_ana, self.cat_dig, self.cat_trunked, self.cat_utility, self.cat_sat, self.cat_navi, self.cat_interf, self.cat_num_stat, self.cat_time_sig ] self.property_labels = [ self.freq_lab, self.band_lab, self.mode_lab, self.modul_lab, self.loc_lab, self.acf_lab, self.description_text ] self.url_button.clicked.connect(self.go_to_web_page_signal) # GFD self.freq_search_gfd_btn.clicked.connect( partial(self.go_to_gfd, GfdType.FREQ)) self.location_search_gfd_btn.clicked.connect( partial(self.go_to_gfd, GfdType.LOC)) self.gfd_line_edit.returnPressed.connect( partial(self.go_to_gfd, GfdType.LOC)) # ########################################################################################## # Left list widget and search bar. self.search_bar.textChanged.connect(self.display_signals) self.signals_list.currentItemChanged.connect(self.display_specs) self.signals_list.itemDoubleClicked.connect(self.set_visible_tab) self.audio_widget = AudioPlayer(self.play, self.pause, self.stop, self.volume, self.loop, self.audio_progress, self.active_color, self.inactive_color) BandLabel = namedtuple("BandLabel", ["left", "center", "right"]) self.band_labels = [ BandLabel(self.elf_left, self.elf, self.elf_right), BandLabel(self.slf_left, self.slf, self.slf_right), BandLabel(self.ulf_left, self.ulf, self.ulf_right), BandLabel(self.vlf_left, self.vlf, self.vlf_right), BandLabel(self.lf_left, self.lf, self.lf_right), BandLabel(self.mf_left, self.mf, self.mf_right), BandLabel(self.hf_left, self.hf, self.hf_right), BandLabel(self.vhf_left, self.vhf, self.vhf_right), BandLabel(self.uhf_left, self.uhf, self.uhf_right), BandLabel(self.shf_left, self.shf, self.shf_right), BandLabel(self.ehf_left, self.ehf, self.ehf_right), ] self.main_tab.currentChanged.connect(self.hide_show_right_widget) self.updates_controller = UpdatesController(__LATEST_VERSION__, self) self.updates_controller.start() self.action_check_software_version.triggered.connect( self.updates_controller.start_verify_software_version) # Final operations. self.theme_manager.start() self.load_db() self.display_signals()
def __init__(self): pygame.mixer.pre_init(frequency=44100, size=-16, channels=2) pygame.init() self.clock = Clock() info = pygame.display.Info() self.size = self.width, self.height = int(info.current_w * .75), info.current_h self.screen = pygame.display.set_mode(self.size, flags=pygame.SCALED | pygame.FULLSCREEN, vsync=True) pygame.display.set_icon(pygame.image.load('img/icon.png')) if isfile('library/saved.library'): self.library = load(open('library/saved.library', 'rb')) else: self.library = Library() pygame.mouse.set_visible(False) self.screen_calls = [ self.close_menu, self.draw_menu, self.draw_settings, self.draw_track_select, self.draw_track_setup, self.draw_new_track, self.draw_edit_track, self.draw_search ] self.delay_time = 2 # Pre-track delay time # Audio player self.audio_device = 1 self.audio_player = AudioPlayer(self.delay_time) self.audio_player.set_device(self.audio_device) self.latency = self.audio_player.device.get_output_latency() * 0 # In-game options self.layers_keys = { 'A': [True, None], 'B': [True, None], 'C': [True, None], 'D': [True, None], 'E': [True, None], 'F': [True, None] } self.prune_unused_layers = False # Difficulty self.preview_length = .6 self.lenience = 0.06 # seconds +/- per beat # Fonts self.large_font = Font('font/unifont.ttf', 36) self.generic_font = Font('font/unifont.ttf', 26) self.small_font = Font('font/unifont.ttf', 16) # Sound Effects self.play_hit_sound = True self.bass_hit_sound_data = pygame.mixer.Sound( open('audio/bass.wav', 'rb').read()) self.high_hit_sound_data = pygame.mixer.Sound( open('audio/high.wav', 'rb').read()) pygame.mixer.set_num_channels(2) # GUI variables self.redraw_screen = True self.current_screen = Menu.TITLE self.last_screen = Menu.TITLE self.track_selection_index = 0 ''' Main menu screen objects ''' self.main_title = self.large_font.render('RIZUMU', True, Menu.WHITE) self.main_title_box = self.main_title.get_rect() self.main_title_box.center = self.width / 2, 200 self.main_play = self.large_font.render('Play', True, Menu.SELECTED_COLOR) self.main_play_box = self.main_play.get_rect() self.main_play_box.center = self.width / 2, 400 self.main_settings = self.large_font.render(f'Settings', True, Menu.WHITE) self.main_settings_box = self.main_settings.get_rect() self.main_settings_box.center = self.width / 2, 500 ''' Settings screen objects ''' ''' Track select screen objects ''' self.selected_tracks = self.library.get_tracks( self.track_selection_index) self.select_track_0 = None self.select_track_1 = None self.select_track_2 = None self.select_track_3 = None self.select_track_4 = None self.select_track_5 = None self.select_track_6 = None self.render_selected_tracks() self.select_track_title = None self.select_track_artist = None self.select_track_album = None self.select_track_high_score = None self.select_track_high_score_accuracy = None self.select_track_high_score_layers = None self.select_track_duration = None self.select_track_difficulty = None self.select_track_num_beats_A = None self.select_track_num_beats_B = None self.select_track_num_beats_C = None self.select_track_num_beats_D = None self.select_track_num_beats_E = None self.select_track_num_beats_F = None self.render_selected_track_data() self.select_edit = self.generic_font.render('e: Edit', True, Menu.WHITE) self.select_new = self.generic_font.render('n: New', True, Menu.WHITE) self.select_back = self.generic_font.render('⌫ : Back', True, Menu.WHITE) self.select_play = self.generic_font.render('⏎ : Play', True, Menu.WHITE) ''' Track setup screen objects ''' self.setup_toggle = self.generic_font.render('⏎ : Select/Toggle', True, Menu.WHITE) self.setup_back = self.select_back ''' New track screen objects ''' self.new_track_edit = self.generic_font.render( '⏎ : Paste from clipboard', True, Menu.WHITE) self.new_track_save = self.generic_font.render('s: Save', True, Menu.WHITE) self.new_track_cancel = self.generic_font.render( '⌫ : Cancel', True, Menu.WHITE) ''' Edit track screen objects ''' self.edit_track_delete = self.generic_font.render( 'd: Delete', True, Menu.WHITE) ''' Search track screen objects ''' # Start drawing self.display_loop()
def process_single_video(video_dir, output_dir, face_detection_model, face_validation_model, speaker_validation, output_video_dir=None): # 将视频音轨导出到临时文件夹中,采样率为16000 audio_tmp = os.path.join(config.temp_dir, 'audio.wav') command = ( "ffmpeg -y -i %s -async 1 -ac 1 -vn -acodec pcm_s16le -ar 16000 %s > %s 2>&1" % (video_dir, audio_tmp, os.path.join(config.log_dir, "ffmpeg.log"))) output = subprocess.call(command, shell=True, stdout=None) sample_rate, audio = wavfile.read(audio_tmp) # print(audio.shape) # 打开标签输出文件 predict_results = open(output_dir, "w") # predict_results = open(os.path.join(os.getcwd(), 'result', POI, POI + '-' + str(config.video_num) + '.txt'), "w") # 初始化临时变量 tracker_list = [] candidates = [] series_id = 0 # 验证视频帧数 cap = cv2.VideoCapture(video_dir) video_fps = cap.get(cv2.CAP_PROP_FPS) video_total_frame = cap.get(7) if config.enable_syncnet: assert video_fps == 25 print("Video FPS:", video_fps) # 是否输出视频,若需要,则需要传入额外参数output_video_dir if config.write_video: videoWriter = cv2.VideoWriter( os.path.join(output_video_dir, 'song.avi'), cv2.VideoWriter_fourcc(*'XVID'), video_fps, (1280, 720)) # 视频宽度大于1280时,缩放至 1280 * 720 if cap.get(cv2.CAP_PROP_FRAME_WIDTH) > 1280: need_to_resize = True else: need_to_resize = False # 跳读n帧 debug 过程中使用,实际运行中不可跳读 # start_frame = 0 # cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame) # shot_count = start_frame - 1 shot_count = 0 print("\033[94mstart process\033[0m") print("total frames: %s.." % (video_total_frame)) video_type = video_dir.split("/")[-2] if config.enable_multi_conf: if video_type == "interview" or video_type == "speech": config.starting_confidence = config.easy_starting_confidence config.patient_confidence = config.easy_patient_confidence elif "entertain" in video_type or "tv" in video_type: config.starting_confidence = config.hard_starting_confidence config.patient_confidence = config.hard_patient_confidence else: config.starting_confidence = config.normal_starting_confidence config.patient_confidence = config.normal_patient_confidence # print("\033[94mthreshold: %s & %s\033[0m" % (str(config.starting_confidence), str(config.patient_confidence))) start_time = time.time() while True: # resize if need_to_resize: success, raw_image = cap.read() if not success: break raw_image = cv2.resize(raw_image, (1280, 720)) else: success, raw_image = cap.read() if not success: break image = raw_image.copy() bboxes, landmarks = face_detection_model.update(raw_image) # track new_tracker_list = [] for tracker in tracker_list: tracked, bbox = tracker.update(raw_image, shot_count) # if target lost, start SyncNet process if tracked is False: if config.debug: print("tracking failed") if config.enable_syncnet: if config.debug: print(16000 * tracker.start_shot // video_fps, 16000 * (tracker.end_shot) // video_fps) # 默认视频帧速率为25时,截取相应音频并验证长度是否合规 part_audio = audio[int(16000 * tracker.start_shot // video_fps):int(16000 * (tracker.end_shot) // video_fps)] if len(part_audio) != len( tracker.sync_seq) * 16000 // video_fps: print("fatal: video and audio does not match") print("startshot", tracker.start_shot) print("endshot", tracker.end_shot) print(tracker.series_name) print(len(tracker.sync_seq)) print(len(part_audio)) # exit(-1)] if config.debug: wavfile.write('temp/segment.wav', 16000, part_audio) player = AudioPlayer('temp/segment.wav') # 分别使用原音轨和空音轨调用 SyncNet,对于空音轨中置信度高于 的部分,将原音轨中计算出的相应置信度置零 offset, confidence, dists_npy = speaker_validation.evaluate( video_fps, tracker.sync_seq, part_audio) silent_audio = np.zeros(part_audio.shape, dtype=audio.dtype) __, conf_silent, __ = speaker_validation.evaluate( video_fps, tracker.sync_seq, silent_audio) # print(conf_silent) confidence[conf_silent > config.conf_silent_threshold] = 0 # confidence = conf_silent # debug 模式下输出额外信息 if config.debug: print("Sequence length:", len(tracker.sync_seq)) debug_cap = cv2.VideoCapture(video_dir) debug_cap.set(1, tracker.start_shot) player.play() for i in range(len(tracker.sync_seq)): if i < 6: if need_to_resize: __, img = debug_cap.read() img = cv2.resize(img, (1280, 720)) else: __, img = debug_cap.read() cv2.imshow('Speaking', img) cv2.waitKey(40) else: if need_to_resize: __, img = debug_cap.read() img = cv2.resize(img, (1280, 720)) else: __, img = debug_cap.read() box = tracker.bbox_seq[i] lip_box = tracker.lip_box_seq[i] try: confidence_caption = 'Conf: %.3f' % ( confidence[i - 6]) clr = int( max(min(confidence[i - 6] * 30, 255), 0)) cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, clr, 255 - clr), 2, cv2.LINE_AA) cv2.rectangle(img, (lip_box[2], lip_box[0]), (lip_box[3], lip_box[1]), (255, 0, 0), 2, cv2.LINE_AA) except: confidence_caption = 'Conf: exceeded' cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 0, 255), 2, cv2.LINE_AA) cv2.putText(img, confidence_caption, (int(box[0]), int(box[1]) + 20), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2) cv2.putText(img, confidence_caption, (int(box[0]), int(box[1]) + 20), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1) cv2.imshow('Speaking', img) cv2.waitKey(40) cv2.waitKey(0) prelabels = speaker_validation.verification( confidence, tracker.start_shot, predict_results) candidates = candidates + prelabels else: new_tracker_list.append(tracker) tracker_list = new_tracker_list # for each face detected for boundary, landmark in zip(bboxes, landmarks): boundary = boundary.astype(np.int) center = [ int((boundary[1] + boundary[3]) / 2), int((boundary[0] + boundary[2]) / 2) ] validation = face_validation_model.confirm_validity( raw_image, boundary=boundary, landmark=landmark) if validation: caption = "Yes" # 验证该人脸是否已经被某个追踪器追踪 tracking = isTracking((center[1], center[0]), tracker_list) lip_center = np.mean(landmark[3:], axis=0) # new target if not tracking: series_id += 1 new_tracker = CV_Tracker(raw_image, boundary, series_id, lip_center, shot_count) tracker_list.append(new_tracker) else: # 验证追踪器是否追踪到该人脸 for tracker in tracker_list: if tracker.valid is True: continue if tracker.is_valid(center): # build lip picture sequence tracker.update_lip_seq(raw_image, boundary, lip_center) else: caption = "No" # showimg 模式下输出人脸检测,识别,追踪信息 if config.showimg: cv2.rectangle(image, (boundary[0], boundary[1]), (boundary[2], boundary[3]), (0, 255, 0), 2, cv2.LINE_AA) index_color = 0 for point in landmark: pos = (point[0], point[1]) cv2.circle(image, pos, 1, (255, 255, 255 / 68 * index_color), -1) index_color = index_color + 1 # lip center lip_center = np.mean(landmark[3:], axis=0) cv2.circle(image, (lip_center[0], lip_center[1]), 1, (0, 0, 0), -1) for tracker in tracker_list: if tracker.tracked is True: bbox = tracker.bbox cv2.rectangle( image, (int(bbox[0]), int(bbox[1])), (int(bbox[2] + bbox[0]), int(bbox[3] + bbox[1])), (255, 0, 0), 2, cv2.LINE_AA) cv2.putText(image, str(tracker.series_name), (int(bbox[0]), int(bbox[1]) - 10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2) cv2.putText(image, str(tracker.series_name), (int(bbox[0]), int(bbox[1]) - 10), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1) else: print("Warning a invalid tracker was not removed") cv2.putText(image, str(caption), (boundary[0], boundary[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2) cv2.putText(image, str(caption), (boundary[0], boundary[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1) # 对于追踪区域中没有人脸的tracker,判断是否需要关闭tracker new_tracker_list = [] for tracker in tracker_list: if tracker.valid is False: tracker.drop_count += 1 tracker.update_lip_seq(raw_image, None, None) if tracker.drop(): tracker.set_end_shot(shot_count) if config.debug: print("tracker missed the target") # 关闭 tracker 前,处理tracker保存的视频序列 if config.enable_syncnet: part_audio = audio[int(16000 // video_fps * tracker.start_shot ):int(16000 // video_fps * (tracker.end_shot - config.patience + 1))] if len(part_audio) != len( tracker.sync_seq[:-config.patience] ) * 16000 // video_fps: print("fatal: video and audio does not match") print("startshot", tracker.start_shot) print("endshot", tracker.end_shot) print(len(tracker.sync_seq)) print(len(part_audio)) # exit(-2) if config.debug: wavfile.write('temp/segment.wav', 16000, part_audio) player = AudioPlayer('temp/segment.wav') offset, confidence, dists_npy = speaker_validation.evaluate( video_fps, tracker.sync_seq[:-config.patience], part_audio) silent_audio = np.zeros(part_audio.shape, dtype=audio.dtype) __, conf_silent, __ = speaker_validation.evaluate( video_fps, tracker.sync_seq[:-config.patience], silent_audio) # print(conf_silent) confidence[conf_silent > config.conf_silent_threshold] = 0 # confidence = conf_silent if config.debug: print("Sequence length:", len(tracker.sync_seq[:-config.patience])) debug_cap = cv2.VideoCapture(video_dir) debug_cap.set(1, tracker.start_shot) player.play() for i in range( len(tracker.sync_seq) - config.patience): if i < 6: if need_to_resize: __, img = debug_cap.read() img = cv2.resize(img, (1280, 720)) else: __, img = debug_cap.read() cv2.imshow('Speaking', img) cv2.waitKey(40) else: if need_to_resize: __, img = debug_cap.read() img = cv2.resize(img, (1280, 720)) else: __, img = debug_cap.read() box = tracker.bbox_seq[i] lip_box = tracker.lip_box_seq[i] try: confidence_caption = 'Conf: %.3f' % ( confidence[i - 6]) clr = int( max(min(confidence[i - 6] * 30, 255), 0)) cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, clr, 255 - clr), 2, cv2.LINE_AA) cv2.rectangle(img, (lip_box[2], lip_box[0]), (lip_box[3], lip_box[1]), (255, 0, 0), 2, cv2.LINE_AA) except: confidence_caption = 'Conf: exceeded' cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 0, 255), 2, cv2.LINE_AA) cv2.putText(img, confidence_caption, (int(box[0]), int(box[1]) + 20), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2) cv2.putText(img, confidence_caption, (int(box[0]), int(box[1]) + 20), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1) cv2.imshow('Speaking', img) cv2.waitKey(40) cv2.waitKey(0) prelabels = speaker_validation.verification( confidence, tracker.start_shot, predict_results) candidates = candidates + prelabels else: new_tracker_list.append(tracker) tracker_list = new_tracker_list # 进度展示 if shot_count % 1000 == 0 and shot_count != 0: print('Shot {:d}, FPS {:.2f} '.format( shot_count, 1000 / (time.time() - start_time)), end='\n') start_time = time.time() if config.showimg: cv2.imshow('Video', image) if config.write_video: videoWriter.write(image) shot_count += 1 # 跳出循环 if cv2.waitKey(10) == 27: break predict_results.close() if config.enable_dataclean: dataclean(output_dir, video_total_frame) # evaluate if config.enable_evaluation: index = video_dir.rfind('.') FPR, Recall = evaluate_result(video_dir[:index] + ".csv", output_dir, video_total_frame)
def _play_song_thread_func(path): a = AudioPlayer() a.play_song(path) return None
class Menu: EXIT = 0 TITLE = 1 SETTINGS = 2 TRACK_SELECT = 3 TRACK_SETUP = 4 NEW_TRACK = 5 EDIT_TRACK = 6 SEARCH = 7 WHITE = (255, 255, 255) GRAY = (128, 128, 128) A_COLOR = (255, 128, 128) B_COLOR = (255, 255, 128) C_COLOR = (128, 255, 128) D_COLOR = (128, 255, 255) E_COLOR = (128, 128, 255) F_COLOR = (255, 128, 255) SELECTED_COLOR = D_COLOR ENABLED_COLOR = C_COLOR DISABLED_COLOR = A_COLOR DIFFICULTY_COLORS = (C_COLOR, C_COLOR, C_COLOR, B_COLOR, B_COLOR, A_COLOR, D_COLOR, E_COLOR, F_COLOR) def __init__(self): pygame.mixer.pre_init(frequency=44100, size=-16, channels=2) pygame.init() self.clock = Clock() info = pygame.display.Info() self.size = self.width, self.height = int(info.current_w * .75), info.current_h self.screen = pygame.display.set_mode(self.size, flags=pygame.SCALED | pygame.FULLSCREEN, vsync=True) pygame.display.set_icon(pygame.image.load('img/icon.png')) if isfile('library/saved.library'): self.library = load(open('library/saved.library', 'rb')) else: self.library = Library() pygame.mouse.set_visible(False) self.screen_calls = [ self.close_menu, self.draw_menu, self.draw_settings, self.draw_track_select, self.draw_track_setup, self.draw_new_track, self.draw_edit_track, self.draw_search ] self.delay_time = 2 # Pre-track delay time # Audio player self.audio_device = 1 self.audio_player = AudioPlayer(self.delay_time) self.audio_player.set_device(self.audio_device) self.latency = self.audio_player.device.get_output_latency() * 0 # In-game options self.layers_keys = { 'A': [True, None], 'B': [True, None], 'C': [True, None], 'D': [True, None], 'E': [True, None], 'F': [True, None] } self.prune_unused_layers = False # Difficulty self.preview_length = .6 self.lenience = 0.06 # seconds +/- per beat # Fonts self.large_font = Font('font/unifont.ttf', 36) self.generic_font = Font('font/unifont.ttf', 26) self.small_font = Font('font/unifont.ttf', 16) # Sound Effects self.play_hit_sound = True self.bass_hit_sound_data = pygame.mixer.Sound( open('audio/bass.wav', 'rb').read()) self.high_hit_sound_data = pygame.mixer.Sound( open('audio/high.wav', 'rb').read()) pygame.mixer.set_num_channels(2) # GUI variables self.redraw_screen = True self.current_screen = Menu.TITLE self.last_screen = Menu.TITLE self.track_selection_index = 0 ''' Main menu screen objects ''' self.main_title = self.large_font.render('RIZUMU', True, Menu.WHITE) self.main_title_box = self.main_title.get_rect() self.main_title_box.center = self.width / 2, 200 self.main_play = self.large_font.render('Play', True, Menu.SELECTED_COLOR) self.main_play_box = self.main_play.get_rect() self.main_play_box.center = self.width / 2, 400 self.main_settings = self.large_font.render(f'Settings', True, Menu.WHITE) self.main_settings_box = self.main_settings.get_rect() self.main_settings_box.center = self.width / 2, 500 ''' Settings screen objects ''' ''' Track select screen objects ''' self.selected_tracks = self.library.get_tracks( self.track_selection_index) self.select_track_0 = None self.select_track_1 = None self.select_track_2 = None self.select_track_3 = None self.select_track_4 = None self.select_track_5 = None self.select_track_6 = None self.render_selected_tracks() self.select_track_title = None self.select_track_artist = None self.select_track_album = None self.select_track_high_score = None self.select_track_high_score_accuracy = None self.select_track_high_score_layers = None self.select_track_duration = None self.select_track_difficulty = None self.select_track_num_beats_A = None self.select_track_num_beats_B = None self.select_track_num_beats_C = None self.select_track_num_beats_D = None self.select_track_num_beats_E = None self.select_track_num_beats_F = None self.render_selected_track_data() self.select_edit = self.generic_font.render('e: Edit', True, Menu.WHITE) self.select_new = self.generic_font.render('n: New', True, Menu.WHITE) self.select_back = self.generic_font.render('⌫ : Back', True, Menu.WHITE) self.select_play = self.generic_font.render('⏎ : Play', True, Menu.WHITE) ''' Track setup screen objects ''' self.setup_toggle = self.generic_font.render('⏎ : Select/Toggle', True, Menu.WHITE) self.setup_back = self.select_back ''' New track screen objects ''' self.new_track_edit = self.generic_font.render( '⏎ : Paste from clipboard', True, Menu.WHITE) self.new_track_save = self.generic_font.render('s: Save', True, Menu.WHITE) self.new_track_cancel = self.generic_font.render( '⌫ : Cancel', True, Menu.WHITE) ''' Edit track screen objects ''' self.edit_track_delete = self.generic_font.render( 'd: Delete', True, Menu.WHITE) ''' Search track screen objects ''' # Start drawing self.display_loop() def render_selected_tracks(self): def get_color(track): if not track: return Menu.WHITE else: return Menu.DIFFICULTY_COLORS[min(8, int(track.difficulty))] self.select_track_0 = self.generic_font.render( f'{self.selected_tracks[0]}', True, get_color(self.selected_tracks[0])) self.select_track_1 = self.generic_font.render( f'{self.selected_tracks[1]}', True, get_color(self.selected_tracks[1])) self.select_track_2 = self.generic_font.render( f'{self.selected_tracks[2]}', True, get_color(self.selected_tracks[2])) self.select_track_3 = self.generic_font.render( f'{self.selected_tracks[3]}', True, get_color(self.selected_tracks[3])) self.select_track_4 = self.generic_font.render( f'{self.selected_tracks[4]}', True, get_color(self.selected_tracks[4])) self.select_track_5 = self.generic_font.render( f'{self.selected_tracks[5]}', True, get_color(self.selected_tracks[5])) self.select_track_6 = self.generic_font.render( f'{self.selected_tracks[6]}', True, get_color(self.selected_tracks[6])) def render_selected_track_data(self): if self.selected_tracks[3]: color = Menu.DIFFICULTY_COLORS[min( 8, int(self.selected_tracks[3].difficulty))] self.select_track_title = self.large_font.render( f'{self.selected_tracks[3].title}', True, color) self.select_track_artist = self.generic_font.render( f'{self.selected_tracks[3].artist}', True, Menu.WHITE) self.select_track_album = self.generic_font.render( f'{self.selected_tracks[3].album}', True, Menu.WHITE) self.select_track_high_score = self.generic_font.render( f'High Score: {self.selected_tracks[3].high_score}', True, Menu.WHITE) self.select_track_high_score_accuracy = self.generic_font.render( f'{self.selected_tracks[3].high_score_accuracy:.3f}%', True, Menu.WHITE) self.select_track_high_score_layers = self.generic_font.render( f'{self.selected_tracks[3].high_score_layers}', True, Menu.WHITE) self.select_track_duration = self.generic_font.render( f'{seconds_to_readable_time(self.selected_tracks[3].duration)}', True, Menu.WHITE) self.select_track_difficulty = self.generic_font.render( f'Difficulty: {self.selected_tracks[3].difficulty}', True, color) self.select_track_num_beats_A = self.generic_font.render( f'{self.selected_tracks[3].num_beats["A"]}', True, Menu.A_COLOR) self.select_track_num_beats_B = self.generic_font.render( f'{self.selected_tracks[3].num_beats["B"]}', True, Menu.B_COLOR) self.select_track_num_beats_C = self.generic_font.render( f'{self.selected_tracks[3].num_beats["C"]}', True, Menu.C_COLOR) self.select_track_num_beats_D = self.generic_font.render( f'{self.selected_tracks[3].num_beats["D"]}', True, Menu.D_COLOR) self.select_track_num_beats_E = self.generic_font.render( f'{self.selected_tracks[3].num_beats["E"]}', True, Menu.E_COLOR) self.select_track_num_beats_F = self.generic_font.render( f'{self.selected_tracks[3].num_beats["F"]}', True, Menu.F_COLOR) def draw_menu(self): label_selection_index = 0 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: self.current_screen = Menu.EXIT return elif event.type == pygame.KEYDOWN: self.redraw_screen = True if event.key == pygame.K_UP: self.main_play = self.large_font.render( 'Play', True, Menu.SELECTED_COLOR) self.main_settings = self.large_font.render( f'Settings', True, Menu.WHITE) label_selection_index = 0 elif event.key == pygame.K_DOWN: self.main_play = self.large_font.render( 'Play', True, Menu.WHITE) self.main_settings = self.large_font.render( f'Settings', True, Menu.SELECTED_COLOR) label_selection_index = 1 elif event.key == pygame.K_RETURN: if label_selection_index == 0: self.current_screen = Menu.TRACK_SELECT elif label_selection_index == 1: self.current_screen = Menu.SETTINGS return elif event.key == pygame.K_BACKSPACE: self.current_screen = Menu.EXIT return if self.redraw_screen: self.redraw_screen = False self.screen.fill((0, 0, 0)) self.screen.blit(self.main_title, self.main_title_box) self.screen.blit(self.main_play, self.main_play_box) self.screen.blit(self.main_settings, self.main_settings_box) pygame.display.flip() self.clock.tick(30) def draw_settings(self): pass # noinspection PyArgumentList def draw_track_select(self): pygame.key.set_repeat(250, 20) while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: self.current_screen = Menu.EXIT return elif event.type == pygame.KEYDOWN: self.redraw_screen = True if event.key == pygame.K_UP: self.track_selection_index = max( self.track_selection_index - 1, 0) self.selected_tracks = self.library.get_tracks( self.track_selection_index) self.render_selected_tracks() self.render_selected_track_data() elif event.key == pygame.K_DOWN: self.track_selection_index = min( self.track_selection_index + 1, len(self.library.saved_tracks) - 1) self.selected_tracks = self.library.get_tracks( self.track_selection_index) self.render_selected_tracks() self.render_selected_track_data() else: if event.key == pygame.K_RETURN: self.current_screen = Menu.TRACK_SETUP return elif event.key == pygame.K_BACKSPACE: self.current_screen = Menu.TITLE return elif event.key == pygame.K_e: self.current_screen = Menu.EDIT_TRACK return elif event.key == pygame.K_n: self.current_screen = Menu.NEW_TRACK return if self.redraw_screen: self.redraw_screen = False self.screen.fill((0, 0, 0)) pygame.draw.rect(self.screen, Menu.GRAY, (15, 220, self.width - 30, 60), 1) pygame.draw.line(self.screen, Menu.GRAY, (0, 500), (self.width, 500)) self.screen.blit(self.select_track_0, (15, 30)) self.screen.blit(self.select_track_1, (30, 100)) self.screen.blit(self.select_track_2, (45, 170)) select_track_3_text_box = self.select_track_3.get_rect() select_track_3_text_box.center = 0, 250 self.screen.blit(self.select_track_3, (60, select_track_3_text_box[1])) self.screen.blit(self.select_track_4, (45, 310)) self.screen.blit(self.select_track_5, (30, 380)) self.screen.blit(self.select_track_6, (15, 450)) self.screen.blit(self.select_edit, (15, self.height - 30)) self.screen.blit(self.select_new, (165, self.height - 30)) self.screen.blit(self.select_back, (self.width - 300, self.height - 30)) self.screen.blit(self.select_play, (self.width - 150, self.height - 30)) if self.selected_tracks[3]: self.screen.blit(self.select_track_title, (15, 525)) self.screen.blit(self.select_track_artist, (15, 600)) self.screen.blit(self.select_track_album, (15, 650)) self.screen.blit(self.select_track_high_score, (15, 700)) self.screen.blit(self.select_track_high_score_accuracy, (self.width * .3, 700)) self.screen.blit(self.select_track_high_score_layers, (self.width * .45, 700)) self.screen.blit(self.select_track_difficulty, (15, 750)) self.screen.blit(self.select_track_num_beats_A, (15, 800)) self.screen.blit(self.select_track_num_beats_B, (90, 800)) self.screen.blit(self.select_track_num_beats_C, (165, 800)) self.screen.blit(self.select_track_num_beats_D, (240, 800)) self.screen.blit(self.select_track_num_beats_E, (315, 800)) self.screen.blit(self.select_track_num_beats_F, (390, 800)) self.screen.blit(self.select_track_duration, (500, 800)) pygame.display.flip() self.clock.tick(60) def draw_track_setup(self): label_selection_index = 0 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: self.current_screen = Menu.EXIT return elif event.type == pygame.KEYDOWN: self.redraw_screen = True if event.key == pygame.K_RETURN: if label_selection_index == 0: pygame.key.set_repeat() self.play_track(self.selected_tracks[3]) self.current_screen = Menu.TRACK_SELECT return elif label_selection_index == 1: # toggle prune unused layers self.prune_unused_layers = not self.prune_unused_layers else: # toggle enable for key self.layers_keys[ALL_LAYERS[ label_selection_index - 2]][0] = not self.layers_keys[ALL_LAYERS[ label_selection_index - 2]][0] elif event.key == pygame.K_BACKSPACE: self.current_screen = Menu.TRACK_SELECT return elif event.key == pygame.K_DOWN: label_selection_index = min(7, label_selection_index + 1) break elif event.key == pygame.K_UP: label_selection_index = max(0, label_selection_index - 1) break elif event.key != pygame.K_ESCAPE and event.key != pygame.K_SPACE: if label_selection_index >= 2: for key, value in self.layers_keys.items(): if value[1] == event.key: self.layers_keys[key][1] = None self.layers_keys[ALL_LAYERS[label_selection_index - 2]][1] = event.key if self.redraw_screen: self.redraw_screen = False self.screen.fill((0, 0, 0)) start_label = self.large_font.render( 'START', True, Menu.SELECTED_COLOR if label_selection_index == 0 else Menu.WHITE) start_label_text_box = start_label.get_rect() start_label_text_box.center = self.width / 2, 200 self.screen.blit(start_label, start_label_text_box) prune_unused_layers_label = self.generic_font.render( 'Prune unused layers:', True, Menu.SELECTED_COLOR if label_selection_index == 1 else Menu.WHITE) prune_unused_layers_enabled_label = self.generic_font.render( f'{self.prune_unused_layers}', True, Menu.ENABLED_COLOR if self.prune_unused_layers else Menu.DISABLED_COLOR) self.screen.blit(prune_unused_layers_label, (25, 275)) self.screen.blit(prune_unused_layers_enabled_label, (325, 275)) # A layer A_label = self.generic_font.render( 'Layer A:', True, Menu.SELECTED_COLOR if label_selection_index == 2 else Menu.WHITE) A_enabled_label = self.generic_font.render( f'{"Enabled" if self.layers_keys["A"][0] else "Disabled"}', True, Menu.ENABLED_COLOR if self.layers_keys["A"][0] else Menu.DISABLED_COLOR) A_key_label = self.generic_font.render( f'Key: {None if self.layers_keys["A"][1] is None else pygame.key.name(self.layers_keys["A"][1])}', True, Menu.WHITE) self.screen.blit(A_label, (25, 350)) self.screen.blit(A_enabled_label, (175, 350)) self.screen.blit(A_key_label, (325, 350)) # B layer B_label = self.generic_font.render( 'Layer B:', True, Menu.SELECTED_COLOR if label_selection_index == 3 else Menu.WHITE) B_enabled_label = self.generic_font.render( f'{"Enabled" if self.layers_keys["B"][0] else "Disabled"}', True, Menu.ENABLED_COLOR if self.layers_keys["B"][0] else Menu.DISABLED_COLOR) B_key_label = self.generic_font.render( f'Key: {None if self.layers_keys["B"][1] is None else pygame.key.name(self.layers_keys["B"][1])}', True, Menu.WHITE) self.screen.blit(B_label, (25, 425)) self.screen.blit(B_enabled_label, (175, 425)) self.screen.blit(B_key_label, (325, 425)) # C layer C_label = self.generic_font.render( 'Layer C:', True, Menu.SELECTED_COLOR if label_selection_index == 4 else Menu.WHITE) C_enabled_label = self.generic_font.render( f'{"Enabled" if self.layers_keys["C"][0] else "Disabled"}', True, Menu.ENABLED_COLOR if self.layers_keys["C"][0] else Menu.DISABLED_COLOR) C_key_label = self.generic_font.render( f'Key: {None if self.layers_keys["C"][1] is None else pygame.key.name(self.layers_keys["C"][1])}', True, Menu.WHITE) self.screen.blit(C_label, (25, 500)) self.screen.blit(C_enabled_label, (175, 500)) self.screen.blit(C_key_label, (325, 500)) # D layer D_label = self.generic_font.render( 'Layer D:', True, Menu.SELECTED_COLOR if label_selection_index == 5 else Menu.WHITE) D_enabled_label = self.generic_font.render( f'{"Enabled" if self.layers_keys["D"][0] else "Disabled"}', True, Menu.ENABLED_COLOR if self.layers_keys["D"][0] else Menu.DISABLED_COLOR) D_key_label = self.generic_font.render( f'Key: {None if self.layers_keys["D"][1] is None else pygame.key.name(self.layers_keys["D"][1])}', True, Menu.WHITE) self.screen.blit(D_label, (25, 575)) self.screen.blit(D_enabled_label, (175, 575)) self.screen.blit(D_key_label, (325, 575)) # E layer E_label = self.generic_font.render( 'Layer E:', True, Menu.SELECTED_COLOR if label_selection_index == 6 else Menu.WHITE) E_enabled_label = self.generic_font.render( f'{"Enabled" if self.layers_keys["E"][0] else "Disabled"}', True, Menu.ENABLED_COLOR if self.layers_keys["E"][0] else Menu.DISABLED_COLOR) E_key_label = self.generic_font.render( f'Key: {None if self.layers_keys["E"][1] is None else pygame.key.name(self.layers_keys["E"][1])}', True, Menu.WHITE) self.screen.blit(E_label, (25, 650)) self.screen.blit(E_enabled_label, (175, 650)) self.screen.blit(E_key_label, (325, 650)) # F layer F_label = self.generic_font.render( 'Layer F:', True, Menu.SELECTED_COLOR if label_selection_index == 7 else Menu.WHITE) F_enabled_label = self.generic_font.render( f'{"Enabled" if self.layers_keys["F"][0] else "Disabled"}', True, Menu.ENABLED_COLOR if self.layers_keys["F"][0] else Menu.DISABLED_COLOR) F_key_label = self.generic_font.render( f'Key: {None if self.layers_keys["F"][1] is None else pygame.key.name(self.layers_keys["F"][1])}', True, Menu.WHITE) self.screen.blit(F_label, (25, 725)) self.screen.blit(F_enabled_label, (175, 725)) self.screen.blit(F_key_label, (325, 725)) self.screen.blit(self.setup_toggle, (self.width - 450, self.height - 30)) self.screen.blit(self.setup_back, (self.width - 150, self.height - 30)) pygame.display.flip() self.clock.tick(30) def draw_new_track(self): label_selection_index = 0 clipboard = paste() new_track_filepath = clipboard if isfile( clipboard) and clipboard[clipboard.rindex('.'):] in ( '.flac', '.opus', '.mp3', '.m4a') else None new_track = Track(new_track_filepath) if new_track_filepath else None while 1: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: if label_selection_index == 0: clipboard = paste() new_track_filepath = clipboard if isfile( clipboard ) and clipboard[clipboard.rindex('.'):] in ( '.flac', '.opus', '.mp3', '.m4a') else None new_track = Track(new_track_filepath ) if new_track_filepath else None break elif label_selection_index == 1: new_track.set_title(paste()) break elif label_selection_index == 2: new_track.set_artist(paste()) break elif label_selection_index == 3: new_track.set_album(paste()) break elif event.key == pygame.K_s: self.current_screen = Menu.TRACK_SELECT if new_track: new_index = self.library.add_track(new_track) self.save_library() if new_index is not None: self.track_selection_index = new_index self.selected_tracks = self.library.get_tracks( self.track_selection_index) self.render_selected_tracks() self.render_selected_track_data() return elif event.key == pygame.K_BACKSPACE: self.current_screen = Menu.TRACK_SELECT return elif event.key == pygame.K_DOWN: label_selection_index = min(3, label_selection_index + 1) break elif event.key == pygame.K_UP: label_selection_index = max(0, label_selection_index - 1) break if self.redraw_screen: self.screen.fill((0, 0, 0)) new_track_file_text = self.generic_font.render( 'Paste filepath from clipboard', True, Menu.SELECTED_COLOR if label_selection_index == 0 else Menu.WHITE) new_track_file_text_box = new_track_file_text.get_rect() new_track_file_text_box.center = self.width / 2, 200 self.screen.blit(new_track_file_text, new_track_file_text_box) clipboard = paste() new_track_clipboard_text = self.small_font.render( f'Clipboard: {clipboard}', True, Menu.WHITE) self.screen.blit(new_track_clipboard_text, (10, self.height - 200)) self.screen.blit(self.new_track_edit, (15, self.height - 30)) self.screen.blit(self.new_track_save, (self.width - 300, self.height - 30)) self.screen.blit(self.new_track_cancel, (self.width - 150, self.height - 30)) self.screen.blit( self.generic_font.render( f'Title: {new_track.title if new_track else "None"}', True, Menu.SELECTED_COLOR if label_selection_index == 1 else Menu.WHITE), (10, 300)) self.screen.blit( self.generic_font.render( f'Artist: {new_track.artist if new_track else "None"}', True, Menu.SELECTED_COLOR if label_selection_index == 2 else Menu.WHITE), (10, 375)) self.screen.blit( self.generic_font.render( f'Album: {new_track.album if new_track else "None"}', True, Menu.SELECTED_COLOR if label_selection_index == 3 else Menu.WHITE), (10, 450)) pygame.display.flip() self.clock.tick(30) def draw_edit_track(self): label_selection_index = 0 track = self.selected_tracks[3] old_title = track.title old_artist = track.artist old_album = track.album while 1: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: if label_selection_index == 0: track.set_title(paste()) break elif label_selection_index == 1: track.set_artist(paste()) break elif label_selection_index == 2: track.set_album(paste()) break elif event.key == pygame.K_d: track.delete_map() self.library.remove_track(self.track_selection_index) self.save_library() if self.track_selection_index >= len( self.library.saved_tracks): self.track_selection_index -= 1 self.selected_tracks = self.library.get_tracks( self.track_selection_index) self.render_selected_tracks() self.render_selected_track_data() self.current_screen = Menu.TRACK_SELECT return elif event.key == pygame.K_s: if track.title != old_title: self.library.add_track( self.library.remove_track( self.track_selection_index)) self.save_library() self.render_selected_tracks() self.render_selected_track_data() self.current_screen = Menu.TRACK_SELECT return elif event.key == pygame.K_BACKSPACE: track.set_title(old_title) track.set_artist(old_artist) track.set_album(old_album) self.current_screen = Menu.TRACK_SELECT return elif event.key == pygame.K_DOWN: label_selection_index = min(2, label_selection_index + 1) break elif event.key == pygame.K_UP: label_selection_index = max(0, label_selection_index - 1) break if self.redraw_screen: self.screen.fill((0, 0, 0)) clipboard = paste() edit_track_clipboard_text = self.small_font.render( f'Clipboard: {clipboard}', True, Menu.WHITE) self.screen.blit(edit_track_clipboard_text, (10, self.height - 200)) self.screen.blit(self.new_track_edit, (15, self.height - 30)) self.screen.blit(self.edit_track_delete, (400, self.height - 30)) self.screen.blit(self.new_track_save, (self.width - 300, self.height - 30)) self.screen.blit(self.new_track_cancel, (self.width - 150, self.height - 30)) self.screen.blit( self.generic_font.render( f'Title: {track.title}', True, Menu.SELECTED_COLOR if label_selection_index == 0 else Menu.WHITE), (10, 300)) self.screen.blit( self.generic_font.render( f'Artist: {track.artist}', True, Menu.SELECTED_COLOR if label_selection_index == 1 else Menu.WHITE), (10, 375)) self.screen.blit( self.generic_font.render( f'Album: {track.album}', True, Menu.SELECTED_COLOR if label_selection_index == 2 else Menu.WHITE), (10, 450)) pygame.display.flip() self.clock.tick(30) def draw_search(self): pass def display_loop(self): while 1: self.screen_calls[self.current_screen]() if self.current_screen == 0: break def play_track(self, track): if isfile(track.audio_filepath) and isfile(track.map_filepath): self.audio_player.idle.wait() enabled_layers_keys = { layer: key[1] for layer, key in self.layers_keys.items() if key[0] } game = Game(self.screen, self.width, self.height, self.audio_player, track, enabled_layers_keys, self.preview_length, self.lenience, self.prune_unused_layers, self.latency, self.play_hit_sound, [self.bass_hit_sound_data, self.high_hit_sound_data]) game.start_game() while game.restart: self.audio_player.idle.wait() game = Game( self.screen, self.width, self.height, self.audio_player, track, enabled_layers_keys, self.preview_length, self.lenience, self.prune_unused_layers, self.latency, self.play_hit_sound, [self.bass_hit_sound_data, self.high_hit_sound_data]) game.start_game() self.save_library() self.render_selected_track_data() def save_library(self): dump(self.library, open('library/saved.library', 'wb')) def close_menu(self): self.save_library() self.audio_player.idle.wait() self.audio_player.close() pygame.display.quit()
assert os.path.exists(args.audio_dir), "audio dir doesn't exist?" assert os.path.isdir(args.audio_dir), "audio dir not a dir?" assert os.path.exists(args.lightning_rpc), "rpc file doesn't exist?" assert os.path.exists("/dev/" + args.blockchain_device), ("device doesn't " "exist?") assert os.path.exists(args.blockchain_dir), "blockchain dir doesn't exist?" assert os.path.isdir(args.blockchain_dir), "blockchain dir not a dir?" r = reactor # setup urwid screen output sui = ScreenUI(r, args.console) # listen on ZMQ for new blocks bc_info = Bitcoind.getblockchaininfo() block_hash = bc_info['bestblockhash'] if bc_info else None queue = NewBlockQueue(r, sui, AudioPlayer(), block_hash) # start periodic timers pu = PeriodicUpdates(sui) r.callLater(0.5, pu.run) sr = SystemResources(r, sui, args.blockchain_dir, args.blockchain_device) sr.run() ni = NodeInfo(r, sui) ni.run() lni = LnNodeInfo(r, sui, args.lightning_rpc) lni.run() j = Jukebox(r, sui, args.audio_dir, args.lightning_rpc) j.run()
def main(): prices = Prices() weather = Weather() def wake_up_routine(number): if number == 1: w1 = Weather() send_message = "God morgen Tommy! I dag kan du forvente følgende temperaturer " + w1.min_max_weather( ) channel = "raspberry-pi" slack_client.api_call("chat.postMessage", channel=channel, text=send_message) audio = AudioPlayer() audio.music_then_radio("random", 10, 300, "random") def send_bitcoin_price(channel): price_bit = prices.get_bitcoin_price() send_msg_bit = "Den nåværende prisen for Bitcoin er: " + price_bit[0] returns_msg_bit = "Din nåværende avkastning på Bitcoin er: " + price_bit[ 1] slack_client.api_call("chat.postMessage", channel=channel, text=send_msg_bit) slack_client.api_call("chat.postMessage", channel=channel, text=returns_msg_bit) def send_dogecoin_price(channel): price_dog = prices.get_dogecoin_price() send_msg_dog = "Den nåværende prisen for Dogecoin er: " + price_dog[0] # returns_msg_dog = "Din nåværende avkastning på Bitcoin er: " + price_dog[1] slack_client.api_call("chat.postMessage", channel=channel, text=send_msg_dog) # slack_client.api_call("chat.postMessage", channel=channel, text=returns_msg_dog) def send_litecoin_price(channel): price_ltc = prices.get_litecoin_price() send_msg_ltc = "Den nåværende prisen for Litecoin er: " + price_ltc[0] returns_msg_ltc = "Din nåværende avkastning på Litecoin er: " + price_ltc[ 1] slack_client.api_call("chat.postMessage", channel=channel, text=send_msg_ltc) slack_client.api_call("chat.postMessage", channel=channel, text=returns_msg_ltc) def morning_messages(): time = datetime.now().time() hour = str(time)[0:2] global sent if hour == "09" and not sent: morning_prices() morning_weather() sent = True if hour == "10" and sent: sent = False def morning_weather(): curr_weather = weather.min_max_weather().split() minimum = curr_weather[0] maximum = curr_weather[1] send_message = f"I dag kan du forvente temperaturer mellom {minimum} og {maximum}." channel = "raspberry-pi" slack_client.api_call("chat.postMessage", channel=channel, text=send_message) def morning_prices(): channel = "raspberry-pi" good_morning_msg = "God morgen Tommy! Håper du får en fin dag :)" slack_client.api_call("chat.postMessage", channel=channel, text=good_morning_msg) send_bitcoin_price(channel) send_dogecoin_price(channel) send_litecoin_price(channel) tokens = {} with open('configs.json') as json_data: tokens = json.load(json_data) slack_client = SlackClient(tokens.get("slack_bot_token")) alarm = Alarm() if slack_client.rtm_connect(auto_reconnect=True): print("Connected!") while True: morning_messages() try: messages = slack_client.rtm_read() except: print("Disconnected.") print("Reconnecting...") time.sleep(20) slack_client.rtm_connect() messages = slack_client.rtm_read() if alarm.alarm_active(): if alarm.check_alarm(): wake_up_routine(1) # print(messages) if messages: for message in messages: if message.get("subtype") is None and message.get( 'user') is not None and message.get( 'text' ) is not None and "BOT TEST" in message.get( 'text'): channel = message["channel"] send_message = "Responding to `BOT TEST` message sent by user <@%s>" % message[ "user"] slack_client.api_call("chat.postMessage", channel=channel, text=send_message) if message.get("subtype") is None and message.get( 'user') is not None and message.get( 'text') is not None and "audio" in message.get( 'text'): command = message.get('text') command_lst = command.split() command = " ".join(command_lst[1:]) au1 = AudioPlayer() au1.audio_handler(command) if message.get("subtype") is None and message.get( 'user') is not None and message.get( 'text' ) is not None and "weather_now" in message.get( 'text'): command = message.get('text') command_lst = command.split() command = " ".join(command_lst[1:]) weather = Weather() send_message = weather.weather_handler(command) channel = message["channel"] slack_client.api_call("chat.postMessage", channel=channel, text=send_message) if message.get("subtype") is None and message.get( 'user') is not None and message.get( 'text' ) is not None and "weather_min_max" in message.get( 'text'): weather = Weather() send_message = weather.min_max_weather() channel = message["channel"] slack_client.api_call("chat.postMessage", channel=channel, text=send_message) if message.get("subtype") is None and message.get( 'user') is not None and message.get( 'text' ) is not None and "set_alarm" in message.get( 'text'): command = message.get('text') command_lst = command.split() alarm.set_alarm(int(command_lst[1]), int(command_lst[2]), int(command_lst[3]), int(command_lst[4])) if message.get("subtype") is None and message.get( 'user' ) is not None and message.get( 'text' ) is not None and "get_bitcoin_price" in message.get( 'text'): send_bitcoin_price(message["channel"]) if message.get("subtype") is None and message.get( 'user' ) is not None and message.get( 'text' ) is not None and "get_dogecoin_price" in message.get( 'text'): send_dogecoin_price(message["channel"]) if message.get("subtype") is None and message.get( 'user' ) is not None and message.get( 'text' ) is not None and "get_litecoin_price" in message.get( 'text'): send_litecoin_price(message["channel"]) if message.get("subtype") is None and message.get( 'user' ) is not None and message.get( 'text' ) is not None and "get_crypto_price" in message.get( 'text'): channel = message["channel"] send_bitcoin_price(channel) send_dogecoin_price(channel) send_litecoin_price(channel) time.sleep(4) else: print("Connection Failed")
def __init__(self): "初始化" dir = os.path.dirname(game_settings['save_folder']) if not os.path.exists(dir): os.makedirs(dir) self.initGameSettings() #读取设置文件 loadPrcFile("config/PandaConfig.prc") loadPrcFileData( '', 'win-size ' + str(game_settings['screen_resolution'][0]) + ' ' + str(game_settings['screen_resolution'][1])) #构造Panda3D的ShowBase ShowBase.__init__(self) #Retrieving available resolutions #self.makeDefaultPipe() di = self.pipe.getDisplayInformation() self.supportedResolutions = [] for index in range(di.getTotalDisplayModes()): self.supportedResolutions.append((di.getDisplayModeWidth(index), di.getDisplayModeHeight(index))) color_themes.initStyles() props = WindowProperties(self.win.getProperties()) props.setSize(int(game_settings['screen_resolution'][0]), int(game_settings['screen_resolution'][1])) if game_settings['full_screen'] and not props.getFullscreen(): props.setFullscreen(True) props.setTitle(game_settings['window_title']) self.win.requestProperties(props) self.cam2dp.node().getDisplayRegion(0).setSort( -20) #Set render2dp to background self.disableMouse() #Disable panda3d's default mouse control self.cam.node().getDisplayRegion(0).setActive( 0) #disable default camera self.audioPlayer = AudioPlayer() self.focusStack = [] #a stack that shows windowstop window gets focus self._loadReadText() self._loadGlobalData() #add event handlers self.accept('alt-enter', self.toggleFullScreen) self.accept('save_data', self.save) self.accept('load_data', self.load) self.accept('load_memory', self.loadMemory) self.accept('request_focus', self.grantFocus) self.accept('remove_focus', self.cancelFocus) self.accept('return_to_title', self.returnToTitle) self.accept('start_game', self.startGame) self.accept('load_game', self.loadGame) self.accept('config_form', self.showConfig) self.accept('exit_game', self.exit) self.accept('quick_save', self.quickSave) self.accept('quick_load', self.quickLoad) self.accept('auto_save', self.autoSave) self.accept('print_screen', self.takeScrnShot) self.accept('f10', self.takeScrnShot) #Font setting self.textFont = color_themes.default_font #背景设置 self.setBackgroundColor(0, 0, 0, 1) self.backgroundImage = None self.initGameWindows() self.mainMenu = None self.storyManager = None
class SogalBase(ShowBase): """The ShowBase of the sogal Attributes: supportedResolutions: player's system supported resolutions, Note that it is constructed after the initialization of ShowBase. """ def __init__(self): "初始化" dir = os.path.dirname(game_settings['save_folder']) if not os.path.exists(dir): os.makedirs(dir) self.initGameSettings() #读取设置文件 loadPrcFile("config/PandaConfig.prc") loadPrcFileData( '', 'win-size ' + str(game_settings['screen_resolution'][0]) + ' ' + str(game_settings['screen_resolution'][1])) #构造Panda3D的ShowBase ShowBase.__init__(self) #Retrieving available resolutions #self.makeDefaultPipe() di = self.pipe.getDisplayInformation() self.supportedResolutions = [] for index in range(di.getTotalDisplayModes()): self.supportedResolutions.append((di.getDisplayModeWidth(index), di.getDisplayModeHeight(index))) color_themes.initStyles() props = WindowProperties(self.win.getProperties()) props.setSize(int(game_settings['screen_resolution'][0]), int(game_settings['screen_resolution'][1])) if game_settings['full_screen'] and not props.getFullscreen(): props.setFullscreen(True) props.setTitle(game_settings['window_title']) self.win.requestProperties(props) self.cam2dp.node().getDisplayRegion(0).setSort( -20) #Set render2dp to background self.disableMouse() #Disable panda3d's default mouse control self.cam.node().getDisplayRegion(0).setActive( 0) #disable default camera self.audioPlayer = AudioPlayer() self.focusStack = [] #a stack that shows windowstop window gets focus self._loadReadText() self._loadGlobalData() #add event handlers self.accept('alt-enter', self.toggleFullScreen) self.accept('save_data', self.save) self.accept('load_data', self.load) self.accept('load_memory', self.loadMemory) self.accept('request_focus', self.grantFocus) self.accept('remove_focus', self.cancelFocus) self.accept('return_to_title', self.returnToTitle) self.accept('start_game', self.startGame) self.accept('load_game', self.loadGame) self.accept('config_form', self.showConfig) self.accept('exit_game', self.exit) self.accept('quick_save', self.quickSave) self.accept('quick_load', self.quickLoad) self.accept('auto_save', self.autoSave) self.accept('print_screen', self.takeScrnShot) self.accept('f10', self.takeScrnShot) #Font setting self.textFont = color_themes.default_font #背景设置 self.setBackgroundColor(0, 0, 0, 1) self.backgroundImage = None self.initGameWindows() self.mainMenu = None self.storyManager = None def initGameWindows(self): ''' Initializing the common save, load and config forms if you want better customization with them, override this! ''' self.saveForm = SaveForm() self.loadForm = LoadForm() self.configForm = ConfigForm() def initGameSettings(self): ''' Initializing game settings some complex game settings can be written here This will run before panda3d ShowBase constructed ''' loadDefaultSettings('config/default.sconf') self._loadSettings() def initMainMenu(self, customMainMenu=None): '''Call this to initialize and show main menu''' if not self.mainMenu: if not customMainMenu: self.mainMenu = MainMenu() else: self.mainMenu = customMainMenu self.mainMenu.open() def isStarted(self): return bool(self.storyManager) def getCurrentFocus(self): if len(self.focusStack) > 0: return self.focusStack[-1] else: return None def hasFocus(self, obj): '''returns whether the object is the current focus''' return self.getCurrentFocus() == obj def grantFocus(self, obj): pre = self.getCurrentFocus() if obj in self.focusStack: self.focusStack.remove(obj) self.focusStack.append(obj) else: self.focusStack.append(obj) if pre != obj: if pre: pre.defocused() obj.focused() def cancelFocus(self, obj): if obj in self.focusStack: self.focusStack.remove(obj) obj.defocused() cur = self.getCurrentFocus() if cur != obj and cur: cur.focused() def setGameBackgroundImage(self, path): ''' Load a total background image ''' if self.backgroundImage: self.backgroundImage.destroy() self.backgroundImage = OnscreenImage(parent=aspect2dp, image=path) # @UndefinedVariable def save(self, saving, fileName, message): info = SavingInfo(message, datetime.now()) try: save_data( game_settings['save_folder'] + fileName + game_settings['save_type'], saving) save_data( game_settings['save_folder'] + fileName + game_settings['save_infotype'], info) except Exception as error: safeprint(error) return self.saveForm.reloadMember(fileName) self.loadForm.reloadMember(fileName) self._saveReadText() self._saveGlobalData() def quickSave(self, saving, message): global_data['currentQuicksave'] += 1 if global_data['currentQuicksave'] > MAX_QUICKSAVE: global_data['currentQuicksave'] = 1 currentqs = global_data['currentQuicksave'] self.save(saving, 'quick_save' + str(currentqs), message) def autoSave(self, saving, message): global_data['currentAutosave'] += 1 if global_data['currentAutosave'] > MAX_AUTOSAVE: global_data['currentAutosave'] = 1 currentas = global_data['currentAutosave'] self.save(saving, 'auto_save' + str(currentas), message) def load(self, fileName): try: savedData = load_data(game_settings['save_folder'] + fileName + game_settings['save_type']) except Exception as error: safeprint(error) return if self.mainMenu: self.mainMenu.close() if self.storyManager: self.storyManager.destroy() self.audioPlayer.stopAll(0.5) restoreRuntimeData(savedData) self.audioPlayer.reload() self.storyManager = StoryManager() def quickLoad(self): if self.hasQuickData(): self.load('quick_save' + str(global_data['currentQuicksave'])) def hasQuickData(self): return exists(game_settings['save_folder'] + 'quick_save' + str(global_data['currentQuicksave']) + game_settings['save_type']) def loadMemory(self, dumped): try: loaded = pickle.loads(dumped) except Exception as exp: safeprint(exp) return self.storyManager.destroy() self.audioPlayer.stopAll(0.5) restoreRuntimeData(loaded) self.audioPlayer.reload() self.storyManager = StoryManager() def getStyle(self, sheet=None): return rgetStyle(sheet) def setStyle(self, value): return rsetStyle(value) def toggleFullScreen(self): props = WindowProperties(self.win.getProperties()) if not props.getFullscreen(): props.setSize(int(game_settings['screen_resolution'][0]), int(game_settings['screen_resolution'][1])) props.setFullscreen(True) else: props.setFullscreen(False) self.win.requestProperties(props) game_settings['full_screen'] = not game_settings['full_screen'] if self.configForm: self.configForm.refreshSettings() messenger.send('window-event', [self]) def exitfunc(self, *args, **kwargs): self._saveReadText() self._saveGlobalData() self._saveSettings() return ShowBase.exitfunc(self, *args, **kwargs) def startGame(self, scene): if self.mainMenu: self.mainMenu.close() if self.storyManager: self.storyManager.destroy() self.audioPlayer.stopAll(0.5) self.storyManager = StoryManager() self.storyManager.beginScene(scene) def loadGame(self): self.loadForm.show() def showConfig(self): self.configForm.show() def exit(self): sys.exit() def returnToTitle(self): if self.storyManager: self.storyManager.destroy() self.audioPlayer.stopAll(0.5) if self.mainMenu: self.mainMenu.open() def takeScrnShot(self): '''Take a screenshot''' dir = os.path.dirname('screenshots/') if not os.path.exists(dir): os.makedirs(dir) self.screenshot(namePrefix='screenshots/screenshot', defaultFilename=1) def setScreenResolution(self, resolution=None, fullscreen=None): game_settings['screen_resolution'] = resolution or game_settings[ 'screen_resolution'] if fullscreen is not None: game_settings['full_screen'] = fullscreen self._applyScreenResolution() def _loadReadText(self): if not exists(game_settings['save_folder'] + 'read.dat'): return try: read = load_data(game_settings['save_folder'] + 'read.dat') except Exception as exp: safeprint(exp) return restoreReadText(read) def _loadGlobalData(self): if not exists(game_settings['save_folder'] + 'global.dat'): return try: gdata = load_data(game_settings['save_folder'] + 'global.dat') except Exception as exp: safeprint(exp) return restoreGlobalData(gdata) def _loadSettings(self): if not exists(game_settings['save_folder'] + 'config.dat'): return try: settings = load_data(game_settings['save_folder'] + 'config.dat') except Exception as error: safeprint(error) return restoreSettings(settings) def _saveReadText(self): try: save_data(game_settings['save_folder'] + 'read.dat', read_text) except Exception as exp: safeprint(exp) def _saveGlobalData(self): try: save_data(game_settings['save_folder'] + 'global.dat', global_data) except Exception as exp: safeprint(exp) def _saveSettings(self): try: save_data(game_settings['save_folder'] + 'config.dat', game_settings) except Exception as exp: safeprint(exp) def _applyScreenResolution(self): props = WindowProperties(self.win.getProperties()) if not props.getFullscreen: props.setSize(int(game_settings['screen_resolution'][0]), int(game_settings['screen_resolution'][1])) props.setFullscreen(game_settings['full_screen']) else: props.setFullscreen(game_settings['full_screen']) props.setSize(int(game_settings['screen_resolution'][0]), int(game_settings['screen_resolution'][1])) self.win.requestProperties(props) if self.configForm: self.configForm.refreshSettings() messenger.send('window-event', [self])
def __init__(self): "初始化" dir = os.path.dirname(game_settings['save_folder']) if not os.path.exists(dir): os.makedirs(dir) self.initGameSettings() #读取设置文件 loadPrcFile("config/PandaConfig.prc") loadPrcFileData('', 'win-size ' + str(game_settings['screen_resolution'][0]) + ' ' + str(game_settings['screen_resolution'][1]) ) #构造Panda3D的ShowBase ShowBase.__init__(self) #Retrieving available resolutions #self.makeDefaultPipe() di = self.pipe.getDisplayInformation() self.supportedResolutions = [] for index in range(di.getTotalDisplayModes()): self.supportedResolutions.append((di.getDisplayModeWidth(index), di.getDisplayModeHeight(index))) color_themes.initStyles() props = WindowProperties( self.win.getProperties() ) props.setSize(int(game_settings['screen_resolution'][0]),int(game_settings['screen_resolution'][1])) if game_settings['full_screen'] and not props.getFullscreen(): props.setFullscreen(True) props.setTitle(game_settings['window_title']) self.win.requestProperties(props) self.cam2dp.node().getDisplayRegion(0).setSort(-20) #Set render2dp to background self.disableMouse() #Disable panda3d's default mouse control self.cam.node().getDisplayRegion(0).setActive(0) #disable default camera self.audioPlayer = AudioPlayer() self.focusStack = [] #a stack that shows windowstop window gets focus self._loadReadText() self._loadGlobalData() #add event handlers self.accept('alt-enter', self.toggleFullScreen) self.accept('save_data', self.save) self.accept('load_data', self.load) self.accept('load_memory', self.loadMemory) self.accept('request_focus', self.grantFocus) self.accept('remove_focus', self.cancelFocus) self.accept('return_to_title', self.returnToTitle) self.accept('start_game', self.startGame) self.accept('load_game', self.loadGame) self.accept('config_form', self.showConfig) self.accept('exit_game', self.exit) self.accept('quick_save', self.quickSave) self.accept('quick_load', self.quickLoad) self.accept('auto_save', self.autoSave) self.accept('print_screen', self.takeScrnShot) self.accept('f10', self.takeScrnShot) #Font setting self.textFont = color_themes.default_font #背景设置 self.setBackgroundColor(0,0,0,1); self.backgroundImage = None self.initGameWindows() self.mainMenu = None self.storyManager = None
class SogalBase(ShowBase): """The ShowBase of the sogal Attributes: supportedResolutions: player's system supported resolutions, Note that it is constructed after the initialization of ShowBase. """ def __init__(self): "初始化" dir = os.path.dirname(game_settings['save_folder']) if not os.path.exists(dir): os.makedirs(dir) self.initGameSettings() #读取设置文件 loadPrcFile("config/PandaConfig.prc") loadPrcFileData('', 'win-size ' + str(game_settings['screen_resolution'][0]) + ' ' + str(game_settings['screen_resolution'][1]) ) #构造Panda3D的ShowBase ShowBase.__init__(self) #Retrieving available resolutions #self.makeDefaultPipe() di = self.pipe.getDisplayInformation() self.supportedResolutions = [] for index in range(di.getTotalDisplayModes()): self.supportedResolutions.append((di.getDisplayModeWidth(index), di.getDisplayModeHeight(index))) color_themes.initStyles() props = WindowProperties( self.win.getProperties() ) props.setSize(int(game_settings['screen_resolution'][0]),int(game_settings['screen_resolution'][1])) if game_settings['full_screen'] and not props.getFullscreen(): props.setFullscreen(True) props.setTitle(game_settings['window_title']) self.win.requestProperties(props) self.cam2dp.node().getDisplayRegion(0).setSort(-20) #Set render2dp to background self.disableMouse() #Disable panda3d's default mouse control self.cam.node().getDisplayRegion(0).setActive(0) #disable default camera self.audioPlayer = AudioPlayer() self.focusStack = [] #a stack that shows windowstop window gets focus self._loadReadText() self._loadGlobalData() #add event handlers self.accept('alt-enter', self.toggleFullScreen) self.accept('save_data', self.save) self.accept('load_data', self.load) self.accept('load_memory', self.loadMemory) self.accept('request_focus', self.grantFocus) self.accept('remove_focus', self.cancelFocus) self.accept('return_to_title', self.returnToTitle) self.accept('start_game', self.startGame) self.accept('load_game', self.loadGame) self.accept('config_form', self.showConfig) self.accept('exit_game', self.exit) self.accept('quick_save', self.quickSave) self.accept('quick_load', self.quickLoad) self.accept('auto_save', self.autoSave) self.accept('print_screen', self.takeScrnShot) self.accept('f10', self.takeScrnShot) #Font setting self.textFont = color_themes.default_font #背景设置 self.setBackgroundColor(0,0,0,1); self.backgroundImage = None self.initGameWindows() self.mainMenu = None self.storyManager = None def initGameWindows(self): ''' Initializing the common save, load and config forms if you want better customization with them, override this! ''' self.saveForm = SaveForm() self.loadForm = LoadForm() self.configForm = ConfigForm() def initGameSettings(self): ''' Initializing game settings some complex game settings can be written here This will run before panda3d ShowBase constructed ''' loadDefaultSettings('config/default.sconf') self._loadSettings() def initMainMenu(self,customMainMenu = None): '''Call this to initialize and show main menu''' if not self.mainMenu: if not customMainMenu: self.mainMenu = MainMenu() else: self.mainMenu = customMainMenu self.mainMenu.open() def isStarted(self): return bool(self.storyManager) def getCurrentFocus(self): if len(self.focusStack) > 0: return self.focusStack[-1] else: return None def hasFocus(self,obj): '''returns whether the object is the current focus''' return self.getCurrentFocus() == obj def grantFocus(self,obj): pre = self.getCurrentFocus() if obj in self.focusStack: self.focusStack.remove(obj) self.focusStack.append(obj) else: self.focusStack.append(obj) if pre != obj: if pre: pre.defocused() obj.focused() def cancelFocus(self,obj): if obj in self.focusStack: self.focusStack.remove(obj) obj.defocused() cur = self.getCurrentFocus() if cur != obj and cur: cur.focused() def setGameBackgroundImage(self,path): ''' Load a total background image ''' if self.backgroundImage: self.backgroundImage.destroy() self.backgroundImage = OnscreenImage(parent=aspect2dp, image=path) # @UndefinedVariable def save(self,saving,fileName,message): info = SavingInfo(message,datetime.now()) try: save_data(game_settings['save_folder'] + fileName + game_settings['save_type'], saving) save_data(game_settings['save_folder'] + fileName + game_settings['save_infotype'], info) except Exception as error: safeprint(error) return self.saveForm.reloadMember(fileName) self.loadForm.reloadMember(fileName) self._saveReadText() self._saveGlobalData() def quickSave(self, saving, message): global_data['currentQuicksave'] += 1 if global_data['currentQuicksave'] > MAX_QUICKSAVE: global_data['currentQuicksave'] = 1 currentqs = global_data['currentQuicksave'] self.save(saving, 'quick_save' + str(currentqs), message) def autoSave(self, saving, message): global_data['currentAutosave'] += 1 if global_data['currentAutosave'] > MAX_AUTOSAVE: global_data['currentAutosave'] = 1 currentas = global_data['currentAutosave'] self.save(saving, 'auto_save' + str(currentas), message) def load(self,fileName): try: savedData = load_data(game_settings['save_folder'] + fileName + game_settings['save_type']) except Exception as error: safeprint(error) return if self.mainMenu: self.mainMenu.close() if self.storyManager: self.storyManager.destroy() self.audioPlayer.stopAll(0.5) restoreRuntimeData(savedData) self.audioPlayer.reload() self.storyManager = StoryManager() def quickLoad(self): if self.hasQuickData(): self.load('quick_save' + str(global_data['currentQuicksave'])) def hasQuickData(self): return exists(game_settings['save_folder'] + 'quick_save' + str(global_data['currentQuicksave']) + game_settings['save_type']) def loadMemory(self,dumped): try: loaded = pickle.loads(dumped) except Exception as exp: safeprint(exp) return self.storyManager.destroy() self.audioPlayer.stopAll(0.5) restoreRuntimeData(loaded) self.audioPlayer.reload() self.storyManager = StoryManager() def getStyle(self, sheet = None): return rgetStyle(sheet) def setStyle(self,value): return rsetStyle(value) def toggleFullScreen(self): props = WindowProperties( self.win.getProperties() ) if not props.getFullscreen(): props.setSize(int(game_settings['screen_resolution'][0]),int(game_settings['screen_resolution'][1])) props.setFullscreen(True) else: props.setFullscreen(False) self.win.requestProperties(props) game_settings['full_screen'] = not game_settings['full_screen'] if self.configForm: self.configForm.refreshSettings() messenger.send('window-event', [self]) def exitfunc(self, *args, **kwargs): self._saveReadText() self._saveGlobalData() self._saveSettings() return ShowBase.exitfunc(self, *args, **kwargs) def startGame(self,scene): if self.mainMenu: self.mainMenu.close() if self.storyManager: self.storyManager.destroy() self.audioPlayer.stopAll(0.5) self.storyManager = StoryManager() self.storyManager.beginScene(scene) def loadGame(self): self.loadForm.show() def showConfig(self): self.configForm.show() def exit(self): sys.exit() def returnToTitle(self): if self.storyManager: self.storyManager.destroy() self.audioPlayer.stopAll(0.5) if self.mainMenu: self.mainMenu.open() def takeScrnShot(self): '''Take a screenshot''' dir = os.path.dirname('screenshots/') if not os.path.exists(dir): os.makedirs(dir) self.screenshot(namePrefix = 'screenshots/screenshot', defaultFilename = 1) def setScreenResolution(self, resolution = None, fullscreen = None): game_settings['screen_resolution'] = resolution or game_settings['screen_resolution'] if fullscreen is not None: game_settings['full_screen'] = fullscreen self._applyScreenResolution() def _loadReadText(self): if not exists(game_settings['save_folder']+ 'read.dat'): return try: read = load_data(game_settings['save_folder']+ 'read.dat') except Exception as exp: safeprint(exp) return restoreReadText(read) def _loadGlobalData(self): if not exists(game_settings['save_folder']+ 'global.dat'): return try: gdata = load_data(game_settings['save_folder']+ 'global.dat') except Exception as exp: safeprint(exp) return restoreGlobalData(gdata) def _loadSettings(self): if not exists(game_settings['save_folder']+ 'config.dat'): return try: settings = load_data(game_settings['save_folder'] + 'config.dat') except Exception as error: safeprint(error) return restoreSettings(settings) def _saveReadText(self): try: save_data(game_settings['save_folder']+ 'read.dat', read_text) except Exception as exp: safeprint(exp) def _saveGlobalData(self): try: save_data(game_settings['save_folder']+ 'global.dat', global_data) except Exception as exp: safeprint(exp) def _saveSettings(self): try: save_data(game_settings['save_folder']+ 'config.dat', game_settings) except Exception as exp: safeprint(exp) def _applyScreenResolution(self): props = WindowProperties( self.win.getProperties() ) if not props.getFullscreen: props.setSize(int(game_settings['screen_resolution'][0]),int(game_settings['screen_resolution'][1])) props.setFullscreen(game_settings['full_screen']) else: props.setFullscreen(game_settings['full_screen']) props.setSize(int(game_settings['screen_resolution'][0]),int(game_settings['screen_resolution'][1])) self.win.requestProperties(props) if self.configForm: self.configForm.refreshSettings() messenger.send('window-event', [self])
from audio_player import AudioPlayer from audio_recorder import AudioRecorder import time import os if __name__ == "__main__": # Usage example for pyaudio while True: # play the audio a = AudioPlayer("sample_1202.wav") print("Start Playing: {}".format(time.time())) os.system("ping -c 1 1.1.1.1") # punch play start a.play(start=0, end=11.5) print("End Playing: {}".format(time.time())) os.system("ping -c 1 8.8.4.4") # punch play end a.close() # Start recording b = AudioRecorder() print("Waiting") print() time.sleep(180)