def _copy_music_changed(self): for x in self.music_changed: ext_left = self.music_left[x]['ext'] full_path_left = os.path.join(self.base_path_left, f'{x}{ext_left}') if ext_left.lower() == '.flac': music_thing_left = flac.FLAC(full_path_left) tags_left = music_thing_left.tags.as_dict() elif ext_left.lower() == '.mp3': music_thing_left = mp3.MP3(full_path_left) tags_left = id3_tags_as_dict(music_thing_left.tags) else: raise Exception('What is this thing?') ext_right = self.music_right[x]['ext'] assert ext_right == '.mp3', 'Target file is not .mp3' full_path_right = os.path.join(self.base_path_right, f'{x}{ext_right}') music_thing_right = mp3.MP3(full_path_right) tags_right = id3_tags_as_dict(music_thing_right.tags) if tags_left != tags_right: print_if_not_silent(f'copying tags {full_path_left}') copy_tag_dict_to_mp3(music_thing_right, tags_left) else: if ext_left.lower() == '.flac': print_if_not_silent(f'encoding {full_path_left} to mp3') flac_to_mp3(full_path_left, full_path_right, tag_dict=tags_left) else: print_if_not_silent(f'copying {full_path_left} to right') shutil.copy2(full_path_left, full_path_right)
def loadFile(self, _filePath): self.tags = None self.info = None self.filePath = _filePath self.isCorrect = False self.isSave = False self.isNeedUpdate = False try: self.tags = id3.ID3( uni.trEncode(self.filePath, fu.fileSystemEncoding)) self.info = mp3.MP3( uni.trEncode(self.filePath, fu.fileSystemEncoding)).info except id3.error: self.isNeedUpdate = True self.isSave = True self.tags = id3.ID3() self.tags.add(id3.TPE1(encoding=3, text="")) self.tags.save(uni.trEncode(self.filePath, fu.fileSystemEncoding)) self.tags = id3.ID3( uni.trEncode(self.filePath, fu.fileSystemEncoding)) self.info = mp3.MP3( uni.trEncode(self.filePath, fu.fileSystemEncoding)).info except: self.tags = id3.ID3(self.filePath) self.info = mp3.MP3(self.filePath).info if self.tags.version is not (2, 4, 0): self.isNeedUpdate = True self.isSave = True
def search_dataset(): ''' Asks the user what to search Finds relevant dataset from Queensland OpenAPI Tells the user the datasets names Returns names and resource_ids /!\ Gives only the first 5 datasets. Otherwise, that would be a lot for someone to remember. ''' # Ask the user what to search print('What do you want to search in one word?') tts = gTTS(text='What do you want to search in one word?', lang="en") tts.save("search.mp3") os.startfile("search.mp3") time.sleep(mp3.MP3('search.mp3').info.length) # Listen to the user's answer with sr.Microphone() as source: audio = r.listen(source) text = r.recognize_google(audio, language="en") print('You have searched {}'.format(text)) # Request search results from the API url = BASE_URL + 'package_search?q={}'.format(text) fileobj = urllib.request.urlopen(url) datasets = json.loads(fileobj.read()) if datasets['result']['count'] == 0: return '', [] else: # Find the relevant datasets datasets = datasets['result']['results'] # Get the names of to_say = 'There are {} datasets.'.format(len(datasets)) to_add = [ 'Dataset number {}. name: {}'.format( i + 1, datasets[i]['resources'][0]['name']) for i in range(len(datasets)) ] to_add = '. '.join( to_add[:5] ) # Take 5 datasets maximum, otherwise it's a lot to remember to_say += to_add # Say the datasets name tts = gTTS(text=to_say, lang="en") tts.save("datasets.mp3") os.startfile("datasets.mp3") time.sleep(mp3.MP3('datasets.mp3').info.length) # Get the names and resource_ids to return names = [ '{}'.format(datasets[i]['resources'][0]['name']) for i in range(len(datasets)) ] ids = [datasets[i]['resources'][0]['id'] for i in range(len(datasets))] return names, ids
def init(filename): audio = mp3.MP3(filename) print(int(audio.info.length), end='') tags = id3.ID3(filename, v2_version=3) available_tags = { 'TIT2': 'Title', 'APIC': 'Artwork', 'TPE1': 'Artist', 'TPE2': 'AlbumArtist', 'TALB': 'Album', 'TYER': 'Year', 'TRCK': 'Track', 'TPOS': 'Disc', 'USLT': 'Lyric', 'TCON': 'Genre', } save_tags = [] delete_tags = [] for tag_name in tags: if tag_name[:4] in available_tags.keys(): tag = tags.getall(tag_name) if tag_name[:4] != 'APIC': tag[0].encoding = id3.Encoding.UTF16 tag = [tag[0]] save_tags.append((tag_name, tag)) else: delete_tags.append(tag_name) for tag in save_tags: tags.setall(tag[0], tag[1]) for tag_name in delete_tags: tags.delall(tag_name) tags.save(v1=id3.ID3v1SaveOptions.REMOVE, v2_version=3)
def Building(sql, connection): pipe = Queue() animation = Thread(target=Loading, args=(pipe, )) sortedfiles = sorted([line for line in listdir(Directory.library) ]) # Sort files for database animation.start() try: for n, mpfile in enumerate( sortedfiles ): # Only .mp3 extensions will be inserted in the database if mpfile.endswith(".mp3"): try: artist, song, album = mpfile.rpartition('.')[0].split('-') except ValueError: print( "Music {} not inserted in database, due to format error" .format(mpfile)) length = ("{0:.2f}".format( mp3.MP3(path.join(Directory.library, mpfile)).info.length / 60)).replace('.', ':') sql.execute('insert into Library values(NULL, ?, ?, ?, ?, ?)', (artist, song, album, length, mpfile)) connection.commit() pipe.put(n + 1, block=True) except KeyboardInterrupt: pass pipe.put(False, block=True) animation.join() # Wait for thread end to prevent output damage
async def tag(path, metadata, session=None): audio = mp3.MP3(path) audio.tags = id3.ID3() for maker in tagmaker.tag_makers: tag = maker(metadata) if tag: audio.tags.add(tag) if keys.IMAGE_LINK in metadata: url = metadata.get(keys.IMAGE_LINK) if session: mime, _ = mimetypes.guess_type(url) async with session.get(url) as response: data = await response.read() audio.tags.add( id3.APIC(encoding=id3.Encoding.UTF8, mime=mime, type=id3.PictureType.COVER_FRONT, desc='Front cover', data=data)) else: # In practice, this is unsupported by most media players # But there's no reason not to do it audio.tags.add(id3.APIC(data=url, mime='-->')) audio.save()
def download_track(track): download_dir = settings.getSetting('folder') downloaded, path, folder = getTrackPath(download_dir, track, codec) if not downloaded: checkFolder(folder) info = get_track_download_info(track, codec, high_res) log("download: %s, %s" % (info.codec, info.bitrate_in_kbps)) info.download(fixPath(path)) if codec == "mp3": audio = mp3.MP3(path, ID3=easyid3.EasyID3) audio["title"] = track.title audio["length"] = str(track.duration_ms) if track.artists: audio["artist"] = track.artists[0].name if track.albums: audio["album"] = track.albums[0].title audio["tracknumber"] = str( track.albums[0].track_position.index) audio["date"] = str(track.albums[0].year) audio["genre"] = track.albums[0].genre audio.save() elif codec == "aac": log("TODO: add tags to aac files") # notify("Download", "Done: %s" % path, 1) return path
def mp3_get_samples(mp3_source_file): """ Reads samples from an mp3 file as a numpy array of floats, with channels along the first axis and samples along the second axis. Args: mp3_source_file: file-like - A file-like object containing mp3 data. Return: np.ndarray - An array of shape (channels, samples) containing the audio sample data as floats in the range [-1.0, 1.0] """ # First get the number of channels for later n_channels = mp3.MP3(mp3_source_file).info.channels # Get an in memory wav object in_mem_file = mp3_to_wav(mp3_source_file) # Read in wav data audio = wave.open(in_mem_file, 'rb') num_frames = audio.getnframes() data = audio.readframes(num_frames) audio.close() data = struct.unpack( wav_packing_string(num_frames, n_channels, WAV_BIT_DEPTH), data) return_array = np.zeros((n_channels, num_frames)) for channel in range(n_channels): return_array[channel, :] = np.array( data[channel::n_channels]) / (2.0**WAV_BIT_DEPTH) return return_array
def get_file(filename): extension = filename[filename.rfind('.'):len(filename)] if extension == '.mp3': return mp3.MP3(filename), 'mp3' if extension == '.mp4' or extension == '.m4a': return mp4.MP4(filename), 'mp4'
def get_tags(filename): """ The get_tags function extracts the ID3 metadata from the data object. :param filename: the path and name to the data object. :return: tags and headers, tags is a dictionary containing ID3 metadata and headers are the order of keys for the CSV output. """ # Set up CSV headers header = [ 'Path', 'Name', 'Size', 'Filesystem CTime', 'Filesystem MTime', 'Title', 'Subtitle', 'Artist', 'Album', 'Album/Artist', 'Length (Sec)', 'Year', 'Category', 'Track Number', 'Comments', 'Publisher', 'Bitrate', 'Sample Rate', 'Encoding', 'Channels', 'Audio Layer' ] tags = {} tags['Path'] = filename tags['Name'] = os.path.basename(filename) tags['Size'] = utility.convert_size(os.path.getsize(filename)) tags['Filesystem CTime'] = strftime('%m/%d/%Y %H:%M:%S', gmtime(os.path.getctime(filename))) tags['Filesystem MTime'] = strftime('%m/%d/%Y %H:%M:%S', gmtime(os.path.getmtime(filename))) # MP3 Specific metadata audio = mp3.MP3(filename) if 'TENC' in audio.keys(): tags['Encoding'] = audio['TENC'][0] tags['Bitrate'] = audio.info.bitrate tags['Channels'] = audio.info.channels tags['Audio Layer'] = audio.info.layer tags['Length (Sec)'] = audio.info.length tags['Sample Rate'] = audio.info.sample_rate # ID3 embedded metadata tags id = id3.ID3(filename) if 'TPE1' in id.keys(): tags['Artist'] = id['TPE1'][0] if 'TRCK' in id.keys(): tags['Track Number'] = id['TRCK'][0] if 'TIT3' in id.keys(): tags['Subtitle'] = id['TIT3'][0] if 'COMM::eng' in id.keys(): tags['Comments'] = id['COMM::eng'][0] if 'TDRC' in id.keys(): tags['Year'] = id['TDRC'][0] if 'TALB' in id.keys(): tags['Album'] = id['TALB'][0] if 'TIT2' in id.keys(): tags['Title'] = id['TIT2'][0] if 'TCON' in id.keys(): tags['Category'] = id['TCON'][0] if 'TPE2' in id.keys(): tags['Album/Artist'] = id['TPE2'][0] if 'TPUB' in id.keys(): tags['Publisher'] = id['TPUB'][0] return tags, header
def addlength(self): logging.info("start") for elem in self.list_mp3: self.list_mp3[elem]["length"] = str( datetime.timedelta(seconds=mp3.MP3( os.path.join(self.music_folder_path, str( elem))).info.length))[2:7] logging.info("end")
def mp3info(self): """ MP3(ID3)の曲情報を取得 """ self.tags = mp3.MP3(self.filepath).tags # ID3タグが存在しない場合 if self.tags == None: # 空のID3オブジェクトを作成 self.tags = id3.ID3() self.id3info()
def play_song(file_name): ''' Takes in an mp3 file name and uses pygame mixer to play the song ''' mp_3 = mp3.MP3(file_name) mixer.init(frequency=mp_3.info.sample_rate) mixer.music.load(file_name) mixer.music.play()
def get_duration(self, audio_data: bytes, mode: Literal["mp3", "wav"]) -> float: audio_file = BytesIO(audio_data) if mode == "mp3": return mutagen.MP3(BytesIO(audio_data)).info.length segment = AudioSegment.from_file_using_temporary_files(audio_file) return len(segment) / 1000 # type: ignore
def identify_filetype(file): """Identify the given file as either MP3 or FLAC and return a Mutagen object.""" if file.endswith('.mp3'): audio_file = mp3.MP3(file, ID3=easyid3.EasyID3) elif file.endswith('.flac'): audio_file = flac.FLAC(file) return audio_file
def say_table_name(name): ''' Gives back the dataset's name Info: harder than it looks through the API. Insight Without Sight makes it easier even if you're not blind. ''' tts = gTTS(text=name, lang="en") tts.save("row.mp3") os.startfile("row.mp3") time.sleep(mp3.MP3('row.mp3').info.length)
def play() : global x, play, pause if pause == True : f = mu.MP3(x) m.init(frequency = f.info.sample_rate) m.music.load(x) m.music.play() l4.config(text = 'Playing Music') play = True pause = False
def count_MP3_length_directory(mp3_filelist): x = 0 ls = [] for mp3_file in mp3_filelist: try: audio = mp3.MP3(mp3_file) x += audio.info.length except mp3.HeaderNotFoundError: os.remove(mp3_file) ls.append(mp3_file) return x, ls
def __getAudioLengthFromBytes(self): audio = "" try: if (self.__mime.endswith("mpeg")): audio = mp3.MP3(io.BytesIO(self.__data)) elif (self.__mime.endswith('wav')): audio = wave.WAVE(io.BytesIO(self.__data)) except: raise AudioFormatDetectionException( "failed to detect audio format") self.__length = audio.info.length
def initUI(self, current_item, media_path): ''' Initialize the media player ''' self.resize(550, 150) vbox = QVBoxLayout() hbox = QHBoxLayout() self.media_player = QMediaPlayer(self) media_url = QUrl.fromLocalFile(media_path) media_content = QMediaContent(media_url) self.media_player.setMedia(media_content) media_mp3 = mp3.MP3(media_path) media_length = media_mp3.info.length # set potentiona error message self.error_label = QLabel(self) self.error_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # set play/pause button self.action_button = QPushButton(self) self.action_button.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.action_button.setEnabled(True) # media slider self.media_slider = QSlider(Qt.Horizontal, self) self.media_slider.setEnabled(True) self.media_slider.setRange(0, media_length) self.media_slider.setFocusPolicy(Qt.NoFocus) # display time self.end_time = str(datetime.timedelta(seconds=round(media_length))) self.display_time = QLabel('{}/{}'.format( str(datetime.timedelta(seconds=0)), self.end_time)) # current item name self.current_item = QLabel(current_item) # set layouts vbox.addWidget(self.current_item) hbox.addWidget(self.action_button) hbox.addWidget(self.media_slider) hbox.addWidget(self.display_time) vbox.addLayout(hbox) vbox.addWidget(self.error_label) self.setLayout(vbox) # set up signals self.action_button.clicked.connect(self.trigger_action) self.media_slider.sliderMoved.connect(self.slider_value_changed) self.media_player.stateChanged.connect(self.media_state_changed) self.media_player.positionChanged.connect(self.position_changed)
def is_mp3(file_path: Path) -> bool: """ Return true if a file is an mp3. :param file_path: file to be checked """ try: return not mp3.MP3(str(file_path)).info.sketchy except mp3.HeaderNotFoundError: pass except FileNotFoundError: pass return False
def count_MP3_length_directory(mp3_filelist, **kwargs): verbose = kwargs.get("verbose", False) x = 0 try: for mp3_file in mp3_filelist: audio = mp3.MP3(mp3_file) x += audio.info.length except mp3.HeaderNotFoundError: os.remove(mp3_file) if (verbose): print("Media read error") return x
def say_headers(headers): ''' Tells the users the headers of the dataset ''' to_say = [ 'row {}: {}'.format(i + 1, headers[i]) for i in range(len(headers)) ] to_say = ', '.join(to_say) print(to_say) tts = gTTS(text=to_say, lang="en") tts.save("header.mp3") os.startfile("header.mp3") time.sleep(mp3.MP3('header.mp3').info.length)
def load(self, filename): audio_file = mp3.MP3(filename) frames = audio_file.tags or {} metadata = Metadata() metadata["duration"] = audio_file.info.length metadata["bitrate"] = audio_file.info.bitrate for processor in self._all_processors: processor.process_frames(metadata, frames) return metadata
def say_stats_qualitative(table): ''' Asks which column Performs a simple categorial statistic (ex: column takes female/male. Returns 60% female) Tells the user the result. Ex: Column takes only for values 'Female' or 'Male'. Counts the number of 'Female' and the number of 'Male' Return the proportion of 'Female' and the proportion of 'Male' ''' # Ask the user which column to study tts = gTTS(text='Which column do you need stats on?', lang="en") tts.save("ask_col.mp3") os.startfile("ask_col.mp3") time.sleep(mp3.MP3('row.mp3').info.length) # Get the user's answer with sr.Microphone() as source: audio = r.listen(source) text = r.recognize_google(audio, language="en") print('You chose column number {}'.format(text)) # Extract the column and get the category's statistics data = [table.iloc[i][int(text) - 1] for i in range(len(table))] unique = list(set(data)) percentages = [data.count(i) / len(data) for i in unique] # Tell the user the category's statistics to_say = [ '{}: {}'.format(unique[i], percentages[i]) for i in range(len(unique)) ] to_say = ', '.join(to_say) to_say = 'Proportions for columns {}: '.format( headers[int(text) - 1]) + to_say tts = gTTS(text=to_say, lang="en") tts.save("to_say.mp3") os.startfile("to_say.mp3") time.sleep(mp3.MP3('to_say.mp3').info.length) return to_say
async def get_tts(self, message: discord.Message, text: str, lang: str) -> Optional[Tuple[bytes, int]]: lang = lang.split("-")[0] if self.bot.blocked: make_espeak_func = make_func(make_espeak, text, lang, self.max_length) return await self.bot.loop.run_in_executor(self.bot.executor, make_espeak_func) cached_mp3 = await self.bot.cache.get(text, lang, message.id) if cached_mp3: return cached_mp3, int( mutagen.MP3(BytesIO(cached_mp3)).info.length) try: audio = await self.bot.gtts.get(text=text, lang=lang) except asyncgTTS.RatelimitException: if self.bot.blocked: return self.bot.blocked = True if await self.bot.check_gtts() is not True: await self.handle_rl() else: self.bot.blocked = False return await self.get_tts(message, text, lang) except asyncgTTS.easygttsException as e: if str(e)[:3] != "400": raise return file_length = int(mutagen.MP3(BytesIO(audio)).info.length) await self.bot.cache.set(text, lang, message.id, audio) return audio, file_length
def metadata(file): """Create a list of all the media file's extracted metadata.""" audio_file = identify_filetype(file) file_metadata = extract_metadata(file) album = file_metadata.get('album', '??') artist = file_metadata.get('artist', '??') title = file_metadata.get('title', '??') track_number = file_metadata.get('tracknumber', '??') date = file_metadata.get('date', '') genre = file_metadata.get('genre', '') description = file_metadata.get('description', '') sample_rate = "{} Hz" .format(audio_file.info.sample_rate) artwork = utilities.resource_filename('mosaic.images', 'nocover.png') try: # Bitrate only applies to mp3 files bitrate = "{} kb/s" .format(audio_file.info.bitrate // 1000) bitrate_mode = "{}" .format(audio_file.info.bitrate_mode) except AttributeError: bitrate = '' bitrate_mode = '' try: # Bits per sample only applies to flac files bits_per_sample = "{}" .format(audio_file.info.bits_per_sample) except AttributeError: bits_per_sample = '' try: # Searches for cover art in flac files artwork = QByteArray().append(audio_file.pictures[0].data) except (IndexError, flac.FLACNoHeaderError): artwork = utilities.resource_filename('mosaic.images', 'nocover.png') except AttributeError: # Searches for cover art in mp3 files for tag in mp3.MP3(file): if 'APIC' in tag: artwork = QByteArray().append(mp3.MP3(file)[tag].data) return [album, artist, title, track_number, date, genre, description, sample_rate, bitrate, bitrate_mode, bits_per_sample, artwork]
def extract(path): if open(path, 'rb').read(4) == binascii.a2b_hex('664C6143'): audio = flac.FLAC(path) identifier = audio['description'] else: audio = mp3.MP3(path) identifier = [ text for item in audio.tags.getall('COMM') for text in item.text ] identifier = max(identifier, key=len) identifier = base64.b64decode(identifier[22:]) cryptor = AES.new(key, AES.MODE_ECB) meta = unpad(cryptor.decrypt(identifier), 16).decode('utf8') return json.loads(meta[6:])
def load_files(path): ''' Load files from a given folder :return: list of MP3 files ''' mp3_files = [] files = glob.glob(pathname=path + '/**/*.*', recursive=True) for file in files: try: if os.path.isdir(file): raise mp3.HeaderNotFoundError() mp3_files.append(mp3.MP3(file)) except mp3.HeaderNotFoundError: print('Error: Invalid MP3, skipping - ' + file) print(str(len(mp3_files)) + ' MP3 files found.') return mp3_files
def play(song): global playing, playbut, pauimg, thread, playlabel, t, artimg, v #pygame.init() try: pygame.mixer.quit() mp = mp3.MP3(song) pygame.mixer.init(frequency=mp.info.sample_rate) clock = pygame.time.Clock() pygame.mixer.music.set_volume(v) pygame.mixer.music.load(song) pygame.mixer.music.play() albumart(song) playlabel.config(image=artimg) playing = True playbut.config(image=pauimg) except Exception as e: pass