def __filter_play_files(self): """ Filters the list of playfiles to see if there's cover art to remove from the list. """ if (not self.__play_files): return now = time.time() size = len(self.__play_files) img_size = len([ f for f in self.__play_files if f.mimetype in mimetypes.get_image_types() ]) ratio = img_size / float(size) if (ratio < 0.5): self.__play_files = [ f for f in self.__play_files if not f.mimetype in mimetypes.get_image_types() ] self.__random_files = [ f for f in self.__random_files if f in self.__play_files ] logging.profile(now, "[navigator] filtered items to play " \ "(removed cover art)")
def __load_file(self, f, is_manual): """ Loads the given file. """ #if (f.mimetype == "application/x-applet"): # applet_id = f.resource # self.call_service(msgs.CORE_SVC_LAUNCH_APPLET, applet_id) stopwatch = logging.stopwatch() if (f.mimetype == f.CONFIGURATOR): cfg_name = f.resource self.emit_message(msgs.UI_ACT_SHOW_DIALOG, cfg_name) else: if (is_manual): self.__show_dialog("player.PlayerWindow") #if (not f.mimetype in mimetypes.get_image_types()): self.emit_message(msgs.MEDIA_ACT_STOP) self.emit_message(msgs.MEDIA_ACT_LOAD, f) # update set of play files self.__current_file = f folder = self.__browser.get_current_folder() if (is_manual and folder != self.__play_folder): self.__play_folder = folder self.__random_files = [] self.__invalidate_play_files() logging.profile(stopwatch, "[navigator] loaded file")
def __load_track_info(self, item): stopwatch = logging.stopwatch() tags = tagreader.get_tags(item) logging.profile(stopwatch, "[audioplayer] retrieved audio tags") gobject.timeout_add(0, self.__on_track_info, item, tags)
def __parse_playlist(self, url): """ Parses the playlist at the given URL and returns a list of URLs. """ uris = [] try: stopwatch = logging.stopwatch() fd = urllib.urlopen(url) logging.profile(stopwatch, "[mediaplayer] retrieved playlist") except: return uris data = fd.read() fd.close() filelines = [ l for l in data.splitlines() if l.startswith("File") ] httplines = [ l for l in data.splitlines() if l.startswith("http") ] for line in filelines: idx = line.find("=") uri = line[idx + 1:].strip() uris.append(uri) #end for for line in httplines: uri = line.strip() uris.append(uri) #end for return uris
def on_child(f, token, path, entries): # abort if the user has changed the directory inbetween if (token != self.__token): return False profile_now = time.time() if (f): #self.set_message("Loading") # (%d items)" % len(self.get_files())) entries.append(f) try: self.__add_file(f) self.emit_event(self.EVENT_FOLDER_PROGRESS, self.get_current_folder(), f) except: print logging.stacktrace() else: message = self.get_current_folder().message if (message): self.set_message(message) else: self.set_message("") # mark folder as complete self.__path_stack[-1][1] = _STATUS_OK self.invalidate() self.emit_event(self.EVENT_FOLDER_COMPLETE, self.get_current_folder()) # now is a good time to collect garbage import gc gc.collect() #end if # give visual feedback while loading the visible part of a folder if (len(entries) == 16 or not f): #not f or len(entries) == 12): profile_now3 = time.time() self.invalidate() self.render() logging.profile(profile_now3, "[browser] rendered list view") #while (gtk.events_pending()): # gtk.main_iteration(True) #end if # don't block UI while loading non-local folders #t = int((time.time() - open_time) * 10) if (time.time() > open_time + 3 and len(entries) % 2 == 0): while (gtk.events_pending()): gtk.main_iteration(False) if (not f): # last item has been reached logging.profile(open_time, "[browser] loaded %d items", len(entries)) return False else: # continue loading next item #logging.profile(profile_now, "[browser] added %dth item", # len(entries)) return True
def __connect(self, host, port): """ Opens an asynchronous connection to the given host and port. """ logging.debug("[conn %s] new HTTP connection: %s", self._get_id(), "http://%s:%d" % (host, port)) if (self.__sock): self.__sock.close() now = time.time() _connection_resource.acquire() self.__finished.clear() try: self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except: #import traceback; traceback.print_exc() return try: self.__sock.connect((host, port or 80)) except: #import traceback; traceback.print_exc() self.__emit(self.__abort, "Could not resolve hostname") return logging.profile(now, "[conn %s] connected to: %s", self._get_id(), "http://%s:%d" % (host, port)) self.__socket_connected = True
def __load(self, uri): #, ctx_id = -1): """ Loads and plays the given file. @param uri: URI of the file @param ctx_id: context ID to use; for internal use only @return: context ID """ if (uri.startswith("http") and not uri.startswith("http://127.0.0.1")): stopwatch = logging.stopwatch() s_type = self.__stream_analyzer.analyze(uri) logging.profile(stopwatch, "[mediaplayer] analyzed stream type") else: s_type = StreamAnalyzer.STREAM if (s_type == StreamAnalyzer.PLAYLIST): uris = self.__parse_playlist(uri) if (uris): uri = uris[0] else: uri = "" # new context id is needed self.__state_machine.set_property("context id", self._new_context_id()) self.__state_machine.set_property("suspension point", None) self.__state_machine.set_property("uri", uri) self.__state_machine.set_property("load time", time.time()) gobject.idle_add(self.__state_machine.send_input, _INPUT_LOAD) return self.__state_machine.get_property("context id")
def __invalidate_play_files(self): """ Invalidates the play files and random files and rebuilds them. """ profile_now = time.time() prev_play_files = self.__play_files self.__play_files = [ f for f in self.__play_folder.get_children() if not f.mimetype.endswith("-folder") ] size = len(self.__play_files) img_size = len([ f for f in self.__play_files if f.mimetype in mimetypes.get_image_types() ]) ratio = img_size / float(size) if (ratio < 0.5): self.__play_files = [ f for f in self.__play_files if not f.mimetype in mimetypes.get_image_types() ] new_files = [f for f in self.__play_files if not f in prev_play_files] self.__random_files = [ f for f in self.__random_files if f in self.__play_files ] + new_files logging.profile(profile_now, "[navigator] invalidated list of files " \ "to play")
def __save_playlists(self): """ Saves all playlists. """ now = time.time() for n, pl in self.__lists: pl.save() logging.profile(now, "[playlist] saved playlists")
def __playback_cb(self, renderer, user_data, err): if (self.__load_time): logging.profile(self.__load_time, "[mafw] loaded media") self.__load_time = 0 print "MAFW PLAYBACK", renderer, user_data, err if (err): print err[0].message
def set_theme(self, name): """ Changes the current theme. @since: 0.96 @param name: name of new theme """ now = time.time() self.__set_theme(name) logging.profile(now, "[theme] loaded")
def __prerender_item(self, t): """ Takes an item from the queue and prerenders it. """ if (self.__items_to_prerender): item = self.__items_to_prerender.pop(0) #print "prerendering", item.get_name() item.render_at(None, 0, 0) return True else: self.__prerender_handler = None logging.profile(t, "[browser] finished prerendering items") return False
def __go_previous(self): now = time.time() if (not self.__play_files): self.__invalidate_play_files() try: idx = self.__play_files.index(self.__current_file) except ValueError: return False if (idx > 0): next_item = self.__play_files[idx - 1] self.__load_file(next_item, False) logging.profile(now, "[navigator] loaded previous item")
def save_as(self, path): """ Saves the playlist to the given file. """ if (not self.__is_modified): return now = time.time() items = [ (f.full_path, f.name) for f in self.__files ] m3u.save(path, items) self.__path = path self.__is_modified = False logging.profile(now, "[playlist] saved playlist: %s", self.__name)
def __on_loaded_cover(self, pbuf, ctx_id, stopwatch): if (ctx_id == self.__context_id and not self.__have_cover): self.__cover = None if (pbuf): self.__set_cover(pbuf) self.emit_message(msgs.MEDIA_EV_TAG, "PICTURE", pbuf) self.__have_cover = True else: self.__cover = None self.__cover_scaled = None self.emit_message(msgs.MEDIA_EV_TAG, "PICTURE", None) if (self.__offscreen_buffer): self.render_buffered(self.__offscreen_buffer) #end if logging.profile(stopwatch, "[audioplayer] loaded cover art")
def query(self, qs, *query_args): """ Parses and performs a given query. The query uses prefix notation to avoid brackets. Returns a set of value-tuples. """ if (self.__is_dirty): self.__save_index() stopwatch = logging.stopwatch() # normalize argument strings (replace unsafe chars) qas = [] for q in query_args: if (type(q) == type("")): qas.append(q.replace("'", "\\'")) else: qas.append(q) #end for qas = tuple(qas) if (qas): qs = qs % qas logging.debug("[fileindex] query: %s", qs) wrapped_qs = [qs] filter_props = self.__parse_filter(wrapped_qs) all_eids = set(self.__entries.keys()) entry_ids = self.__parse_condition(wrapped_qs, all_eids) out = set() for eid in entry_ids: entry = self.__entries[eid] values = (entry.get(key, "") for key in filter_props) out.add(tuple(values)) #end for if (len(out) < 100): logging.debug("[fileindex] result: %d items\n%s", len(out), out) else: logging.debug("[fileindex] result: %d items", len(out)) logging.profile(stopwatch, "[fileindex] query: %s (yields %d items)", str(qs), len(out)) return out
def __load_playlists(self): """ Loads the available playlists. """ def cb(pl, name, location): f = self.call_service(msgs.CORE_SVC_GET_FILE, location) if (f): pl.append(f) else: # insert a placeholder for files that are currently # not available f = File(self) f.name = name f.info = location pl.append(f) # create playlist folder if it does not yet exist if (not os.path.exists(_PLAYLIST_DIR)): try: os.makedirs(_PLAYLIST_DIR) except: pass now = time.time() # load playlists self.__lists = [] files = [f for f in os.listdir(_PLAYLIST_DIR) if f.endswith(".m3u")] for f in files: path = os.path.join(_PLAYLIST_DIR, f) pl = Playlist() pl.load_from_file(path, cb) self.__lists.append((pl.get_name(), pl)) #end for self.__ensure_special_playlists() # sort by name self.__lists.sort(lambda a, b: cmp(a[0], b[0])) self.__current_list = self.__lists[0][1] self.__current_folder = None logging.profile(now, "[playlist] loaded playlists")
def __on_enter_loaded(self, sm): logging.debug("[mediaplayer] entering state LOADED") # clear tags sm.get_property("tags").clear() # resume from suspension point susp = sm.get_property("suspension point") if (susp): uri, pos = susp else: uri = sm.get_property("uri") # load file self._load(uri) load_time = sm.get_property("load time") logging.profile(load_time, "[mediaplayer] loaded media")
def load_from_file(self, path, cb): """ Loads the playlist from the given file. """ now = time.time() self.__files = [] for location, name in m3u.load(path): cb(self, name, location) self.__path = path self.__is_modified = False self.__name = urlquote.unquote( os.path.splitext(os.path.basename(path))[0]) logging.profile(now, "[playlist] loaded playlist: %s", self.__name)
def handle_COM_EV_APP_STARTED(self): logging.profile(values.START_TIME, "[app] startup complete") # load state try: path, play_files, play_folder, current_file = state.load( _STATEFILE) path_stack = [] for p in path: f = self.call_service(msgs.CORE_SVC_GET_FILE, p) if (f): path_stack.append(f) self.emit_message(msgs.CORE_EV_FOLDER_VISITED, f) #end if #end for self.__browser.set_path_stack(path_stack) #self.__play_files = [ self.call_service(msgs.CORE_SVC_GET_FILE, p) # for p in play_files # if self.call_service(msgs.CORE_SVC_GET_FILE, p) ] self.__play_folder = self.call_service(msgs.CORE_SVC_GET_FILE, play_folder) self.__current_file = self.call_service(msgs.CORE_SVC_GET_FILE, current_file) except: logging.warning("could not restore navigator state:\n%s", logging.stacktrace()) self.__arr.set_visible(True) self.render() if (values.uri and (values.uri.startswith("http://") or os.path.exists(values.uri))): ext = os.path.splitext(values.uri)[1] mimetype = mimetypes.ext_to_mimetype(ext) f = self.call_service( msgs.CORE_SVC_GET_FILE, "adhoc://" + File.pack_path("/", values.uri, mimetype)) self.__load_file(f, True)
def handle_PLAYLIST_ACT_APPEND(self, pl_name, *files): if (self.__needs_playlist_reload): self.__load_playlists() self.__needs_playlist_reload = False playlist = None if (not pl_name): dlg = OptionDialog("Select a Playlist") playlists = [ pl for n, pl in self.__lists if not n in [_PLAYLIST_RECENT_50] ] for pl in playlists: dlg.add_option(None, pl.get_name()) if (dlg.run() == 0): choice = dlg.get_choice() playlist = playlists[choice] else: playlist = self.__lookup_playlist(pl_name) #end if if (playlist): now = time.time() self.emit_message(msgs.UI_ACT_SHOW_INFO, u"Adding %d items to %s" \ % (len(files), playlist.get_name())) count = [0] for f in files: self.__add_item_to_playlist(playlist, f, count) logging.profile(now, "[playlist] added %d items to %s", count[0], playlist.get_name()) playlist.save() self.emit_message(msgs.CORE_EV_FOLDER_INVALIDATED, self.__current_folder)
def __on_track_info(self, item, tags): logging.debug("[audioplayer] processing track info") title = tags.get("TITLE") or item.name artist = tags.get("ARTIST") or "-" album = tags.get("ALBUM") or "-" self.__trackinfo.set_title(title) self.__trackinfo.set_album(album) self.__trackinfo.set_artist(artist) if (self.__offscreen_buffer): self.render_buffered(self.__offscreen_buffer) # load cover art self.call_service(msgs.COVERSTORE_SVC_GET_COVER, item, self.__on_loaded_cover, self.__context_id, logging.stopwatch()) stopwatch = logging.stopwatch() self.emit_message(msgs.MEDIA_EV_TAG, "TITLE", title) self.emit_message(msgs.MEDIA_EV_TAG, "ARTIST", artist) self.emit_message(msgs.MEDIA_EV_TAG, "ALBUM", album) logging.profile(stopwatch, "[audioplayer] propagated audio tags")
def __go_next(self): stopwatch = logging.stopwatch() if (not self.__play_files): self.__invalidate_play_files() repeat_mode = mb_config.repeat_mode() shuffle_mode = mb_config.shuffle_mode() if (repeat_mode == mb_config.REPEAT_MODE_NONE): if (shuffle_mode == mb_config.SHUFFLE_MODE_NONE): self.__play_next(False) elif (shuffle_mode == mb_config.SHUFFLE_MODE_ONE): self.__play_shuffled(False) elif (shuffle_mode == mb_config.SHUFFLE_MODE_ALL): self.__play_shuffled(True) elif (repeat_mode == mb_config.REPEAT_MODE_ONE): if (self.__current_file): self.__play_same() else: self.__play_next(True) elif (repeat_mode == mb_config.REPEAT_MODE_ALL): if (shuffle_mode == mb_config.SHUFFLE_MODE_NONE): self.__play_next(True) elif (shuffle_mode == mb_config.SHUFFLE_MODE_ONE): self.__play_shuffled(False) elif (shuffle_mode == mb_config.SHUFFLE_MODE_ALL): self.__play_shuffled(True) logging.profile(stopwatch, "[navigator] loaded next item")
def load(self, f): self.__lyrics = "" self.__have_cover = False stopwatch = logging.stopwatch() self.__player = self.call_service(msgs.MEDIA_SVC_GET_OUTPUT) self.__player.connect_status_changed(self.__on_change_player_status) self.__player.connect_volume_changed(self.__on_change_player_volume) self.__player.connect_position_changed(self.__on_update_position) self.__player.connect_tag_discovered(self.__on_discovered_tags) self.__player.connect_error(self.__on_error) logging.profile(stopwatch, "[audioplayer] connected audio output") try: stopwatch = logging.stopwatch() self.__context_id = self.__player.load_audio(f) logging.profile(stopwatch, "[audioplayer] loaded media file: %s", f) except: logging.error("error loading media file: %s\n%s", f, logging.stacktrace()) stopwatch = logging.stopwatch() self.__current_file = f logging.profile(stopwatch, "[audioplayer] loaded track info") # load bookmarks self.__progress.set_bookmarks(media_bookmarks.get_bookmarks(f)) self.emit_message(msgs.MEDIA_EV_LOADED, self, f) t = threading.Thread(target = self.__load_track_info, args = [f]) t.setDaemon(True) gobject.idle_add(lambda *x:t.start() and False) if (self.__offscreen_buffer): self.render_buffered(self.__offscreen_buffer)