def add_replay_gain(cls, filenames, progress=None): """Adds ReplayGain values to a list of filename strings. All the filenames must be of this AudioFile type. Raises ValueError if some problem occurs during ReplayGain application. """ tracks = [track for track in open_files(filenames) if isinstance(track, cls)] if (len(tracks) > 0): for (track, track_gain, track_peak, album_gain, album_peak) in calculate_replay_gain(tracks, progress): metadata = track.get_metadata() if (metadata is None): metadata = WavPackAPEv2([]) metadata["replaygain_track_gain"] = ApeTagItem.string( "replaygain_track_gain", u"%+1.2f dB" % (track_gain)) metadata["replaygain_track_peak"] = ApeTagItem.string( "replaygain_track_peak", u"%1.6f" % (track_peak)) metadata["replaygain_album_gain"] = ApeTagItem.string( "replaygain_album_gain", u"%+1.2f dB" % (album_gain)) metadata["replaygain_album_peak"] = ApeTagItem.string( "replaygain_album_peak", u"%1.6f" % (album_peak)) track.set_metadata(metadata)
def add_replay_gain(cls, filenames, progress=None): """Adds ReplayGain values to a list of filename strings. All the filenames must be of this AudioFile type. Raises ValueError if some problem occurs during ReplayGain application. """ track_names = [track.filename for track in open_files(filenames) if isinstance(track, cls)] if (progress is not None): progress(0, 1) if ((len(track_names) > 0) and BIN.can_execute(BIN['vorbisgain'])): devnull = file(os.devnull, 'ab') sub = subprocess.Popen([BIN['vorbisgain'], '-q', '-a'] + track_names, stdout=devnull, stderr=devnull) sub.wait() devnull.close() if (progress is not None): progress(1, 1)
def add_replay_gain(cls, filenames): """Adds ReplayGain values to a list of filename strings. All the filenames must be of this AudioFile type. Raises ValueError if some problem occurs during ReplayGain application. """ tracks = [ track for track in open_files(filenames) if isinstance(track, cls) ] if (len(tracks) > 0): for (track, track_gain, track_peak, album_gain, album_peak) in calculate_replay_gain(tracks): metadata = track.get_metadata() if (metadata is None): metadata = WavPackAPEv2([]) metadata["replaygain_track_gain"] = ApeTagItem.string( "replaygain_track_gain", u"%+1.2f dB" % (track_gain)) metadata["replaygain_track_peak"] = ApeTagItem.string( "replaygain_track_peak", u"%1.6f" % (track_peak)) metadata["replaygain_album_gain"] = ApeTagItem.string( "replaygain_album_gain", u"%+1.2f dB" % (album_gain)) metadata["replaygain_album_peak"] = ApeTagItem.string( "replaygain_album_peak", u"%1.6f" % (album_peak)) track.set_metadata(metadata)
def audiofiles(paths, messenger): directories = [p for p in paths if os.path.isdir(p)] files = [p for p in paths if os.path.isfile(p)] for f in audiotools.open_files(files, messenger=messenger): yield f for d in directories: for f in audiotools.open_directory(d, messenger=messenger): yield f
def get_changeform_initial_data(self, request): data = super(AlbumAdmin, self).get_changeform_initial_data(request) init_path = data.get('path') if (init_path): same_path_albums = models.Album.objects.filter(path=init_path) filenames = [] if init_path and same_path_albums.count() == 0: abs_path = settings.MUSIC_LIBRARY_PATH + init_path if os.path.isdir(abs_path) and os.path.exists(abs_path): for root, dirs, files in os.walk(abs_path): for file in files: if file.endswith(".flac"): filenames.append(audiotools.Filename.from_unicode(os.path.join(root, file))) album_initial = {} self.tracks_initial = [] artists = [] for track in audiotools.open_files(filenames): track_meta = track.get_metadata() album_initial['title'] = track_meta.album_name if track_meta.year: try: album_initial['date'] = datetime.date(int(track_meta.year), 1, 1) except ValueError: pass if track_meta.artist_name: artists.append(track_meta.artist_name) self.tracks_initial.append({ 'path': os.path.relpath( track.filename.decode('UTF-8'), settings.MUSIC_LIBRARY_PATH + init_path), 'track_num': track_meta.track_number, 'track_artist': track_meta.artist_name, 'title': track_meta.track_name }) from collections import Counter artists_counter = Counter(artists) album_artist = None most_common_artist = artists_counter.most_common(1) if len(most_common_artist) and most_common_artist[0][1] > len(self.tracks_initial) / 2: album_artist = most_common_artist[0][0] if album_artist: if not album_initial.get('artist'): try: album_initial['artist'] = models.Artist.objects.get(name__iexact=album_artist) except models.Artist.DoesNotExist: pass for track_initial in self.tracks_initial: if track_initial['track_artist'] == album_artist: del track_initial['track_artist'] data.update(album_initial) return data
def read_file(self): u''' read the file ''' files = audiotools.open_files( [ self.input_file ] ) self.audio_file = files[0]
def add_intro_outtro(self): ''' Please add the intro and outro clips. http://audiotools.sourceforge.net/install.html prepend intro.flac append outro.flac ''' output_filename = self.get_filename() + ".flac" if (os.path.exists(output_filename)): return output_filename =audiotools.Filename(output_filename) intro = audiotools.open_files( [ 'intro.flac' ]) content = audiotools.open_files( [ self.input_file ]) outro = audiotools.open_files( [ 'outro.flac' ]) audiofiles = [ intro[0], content[0], outro[0], ] AudioType = audiotools.filename_to_type("intro.flac") metadata = content[0].get_metadata() output_class = AudioType #print audiofiles pcms = ([af.to_pcm() for af in audiofiles]) #print [r.bits_per_sample for r in pcms] encoded = output_class.from_pcm( str(output_filename), audiotools.PCMReaderProgress( audiotools.PCMCat(pcms), sum([af.total_frames() for af in audiofiles]), progress_update), #output_quality, total_pcm_frames=sum([af.total_frames() for af in audiofiles])) encoded.set_metadata(metadata) self.set_intro_added()
def add_intro_outtro(self): ''' Please add the intro and outro clips. http://audiotools.sourceforge.net/install.html prepend intro.flac append outro.flac ''' output_filename = self.get_filename() + ".flac" if (os.path.exists(output_filename)): return output_filename = audiotools.Filename(output_filename) intro = audiotools.open_files(['intro.flac']) content = audiotools.open_files([self.input_file]) outro = audiotools.open_files(['outro.flac']) audiofiles = [ intro[0], content[0], outro[0], ] AudioType = audiotools.filename_to_type("intro.flac") metadata = content[0].get_metadata() output_class = AudioType #print audiofiles pcms = ([af.to_pcm() for af in audiofiles]) #print [r.bits_per_sample for r in pcms] encoded = output_class.from_pcm( str(output_filename), audiotools.PCMReaderProgress( audiotools.PCMCat(pcms), sum([af.total_frames() for af in audiofiles]), progress_update), #output_quality, total_pcm_frames=sum([af.total_frames() for af in audiofiles])) encoded.set_metadata(metadata) self.set_intro_added()
def walk_dirs(dir): num_song = 0 songs = [] for dirname, dirnames, filenames in os.walk(dir, followlinks=True): # print path to all subdirectories for subdirname in dirnames: songs.extend(walk_dirs(subdirname)) options = {"verbosity":"normal"} msg = audiotools.Messenger("music_crawler", options) # print path to all filenames for filename in filenames: file_extension = os.path.splitext(filename)[1] if file_extension in MUSIC_FILE_TYPES: song = {} song["full_path"] = os.path.join(os.path.abspath(dirname), filename) song[file_extension[1:]] = song["full_path"] try: #using open_files because it supports a messenger object song_audio_file = audiotools.open_files([song["full_path"]], messenger=msg) if len(song_audio_file) > 0: song_audio_file = song_audio_file[0] else: print "couldn't open dat file: "+filename continue except Exception as e: print "Could not open file: "+song["full_path"]+". Error: "+str(e) continue #skip song try: song_metadata = song_audio_file.get_metadata() except Exception as e: print "Could not open get file metadata: "+song["full_path"]+". Error: "+str(e) continue #skip song if song_metadata is None: song["title"] = os.path.splitext(filename)[0] song["artist"] = "Unknown artist" song["album"] = "Unknown album" song["number"] = "" song["year"] = "" else: song["title"] = song_metadata.track_name if song_metadata.track_name else filename song["artist"] = song_metadata.artist_name if song_metadata.artist_name else "Unknown artist" song["album"] = song_metadata.album_name if song_metadata.album_name else "Unknown album" song["number"] = song_metadata.track_number if song_metadata.track_number else "" song["year"] = song_metadata.year if song_metadata.year else "" if len(song["year"]) > 4: song["year"] = song["year"][:4] #if len(song.items()) > 2: #only store the song if there is information besides pathname and extension songs.append(song) return songs
def add_replay_gain(cls, filenames): track_names = [track.filename for track in open_files(filenames) if isinstance(track,cls)] if ((len(track_names) > 0) and (BIN.can_execute(BIN['mp3gain']))): devnull = file(os.devnull,'ab') sub = subprocess.Popen([BIN['mp3gain'],'-f','-k','-q','-r'] + \ track_names, stdout=devnull, stderr=devnull) sub.wait() devnull.close()
def compute_gain(self, fnames: Iterable[str], album: bool = True) -> Dict[str, Dict[str, float]]: fnames = list(fnames) audio_files = audiotools.open_files(fnames) if len(audio_files) != len(fnames): raise Exception("Could not load some files") rginfo = {} tag_order = ( "replaygain_track_gain", "replaygain_track_peak", "replaygain_album_gain", "replaygain_album_peak", ) for rg in audiotools.calculate_replay_gain(audio_files): rginfo[rg[0].filename] = dict(zip(tag_order, rg[1:])) return rginfo
def get_redirect_url(self, *args, **kwargs): album = get_object_or_404(Album, pk=kwargs['pk']) filenames = [] album_tracks = album.track_set.all() for track in album_tracks: filenames.append(audiotools.Filename.from_unicode(track.get_fullpath())) at_files = audiotools.open_files(filenames, False) rg_list = audiotools.calculate_replay_gain(at_files) for index, rg in enumerate(rg_list): track = album_tracks[index] track.rg_gain = rg[1] track.rg_peak = rg[2] track.save() if index == 0: album.rg_gain = rg[3] album.rg_peak = rg[4] album.save() return super(AlbumRecalculateRGView, self).get_redirect_url(kwargs['pk'])
def add_replay_gain(cls, filenames): """Adds ReplayGain values to a list of filename strings. All the filenames must be of this AudioFile type. Raises ValueError if some problem occurs during ReplayGain application. """ track_names = [track.filename for track in open_files(filenames) if isinstance(track, cls)] if ((len(track_names) > 0) and (BIN.can_execute(BIN['mp3gain']))): devnull = file(os.devnull, 'ab') sub = subprocess.Popen([BIN['mp3gain'], '-f', '-k', '-q', '-r'] + \ track_names, stdout=devnull, stderr=devnull) sub.wait() devnull.close()
def add_replay_gain(cls, filenames, progress=None): """adds ReplayGain values to a list of filename strings all the filenames must be of this AudioFile type raises ValueError if some problem occurs during ReplayGain application """ track_names = [track.filename for track in open_files(filenames) if isinstance(track, cls)] if progress is not None: progress(0, 1) if (len(track_names) > 0) and BIN.can_execute(BIN["vorbisgain"]): devnull = file(os.devnull, "ab") sub = subprocess.Popen([BIN["vorbisgain"], "-q", "-a"] + track_names, stdout=devnull, stderr=devnull) sub.wait() devnull.close() if progress is not None: progress(1, 1)
def add_replay_gain(cls, filenames, progress=None): """Adds ReplayGain values to a list of filename strings. All the filenames must be of this AudioFile type. Raises ValueError if some problem occurs during ReplayGain application. """ track_names = [track.filename for track in open_files(filenames) if isinstance(track, cls)] if progress is not None: progress(0, 1) # helpfully, aacgain is flag-for-flag compatible with mp3gain if (len(track_names) > 0) and (BIN.can_execute(BIN["aacgain"])): devnull = file(os.devnull, "ab") sub = subprocess.Popen([BIN["aacgain"], "-k", "-q", "-r"] + track_names, stdout=devnull, stderr=devnull) sub.wait() devnull.close() if progress is not None: progress(1, 1)
def get_changeform_initial_data(self, request): data = super(AlbumAdmin, self).get_changeform_initial_data(request) init_path = data.get('path') if (init_path): same_path_albums = models.Album.objects.filter(path=init_path) filenames = [] if init_path and same_path_albums.count() == 0: abs_path = settings.MUSIC_LIBRARY_PATH + init_path if os.path.isdir(abs_path) and os.path.exists(abs_path): for root, dirs, files in os.walk(abs_path): for file in files: if file.endswith(".flac"): filenames.append( audiotools.Filename.from_unicode( os.path.join(root, file))) album_initial = {} self.tracks_initial = [] artists = [] for track in audiotools.open_files(filenames): track_meta = track.get_metadata() album_initial['title'] = track_meta.album_name if track_meta.year: try: album_initial['date'] = datetime.date( int(track_meta.year), 1, 1) except ValueError: pass if track_meta.artist_name: artists.append(track_meta.artist_name) self.tracks_initial.append({ 'path': os.path.relpath(track.filename.decode('UTF-8'), settings.MUSIC_LIBRARY_PATH + init_path), 'track_num': track_meta.track_number, 'track_artist': track_meta.artist_name, 'title': track_meta.track_name }) from collections import Counter artists_counter = Counter(artists) album_artist = None most_common_artist = artists_counter.most_common(1) if len(most_common_artist) and most_common_artist[0][1] > len( self.tracks_initial) / 2: album_artist = most_common_artist[0][0] if album_artist: if not album_initial.get('artist'): try: album_initial['artist'] = models.Artist.objects.get( name__iexact=album_artist) except models.Artist.DoesNotExist: pass for track_initial in self.tracks_initial: if track_initial['track_artist'] == album_artist: del track_initial['track_artist'] data.update(album_initial) return data
def audiotools_audiofile(self): audiotools_filename = audiotools.Filename.from_unicode(self.abs_path()) audiofile = audiotools.open_files((audiotools_filename, ))[0] return audiofile
def read_file(self): u''' read the file ''' files = audiotools.open_files([self.input_file]) self.audio_file = files[0]
if (options.quality == 'help'): audiotools.ui.show_available_qualities(msg, AudioType) sys.exit(0) elif (options.quality is None): options.quality = audiotools.__default_quality__(AudioType.NAME) elif (options.quality not in AudioType.COMPRESSION_MODES): msg.error(_.ERR_UNSUPPORTED_COMPRESSION_MODE % {"quality": options.quality, "type": AudioType.NAME}) sys.exit(1) #grab the list of AudioFile objects we are converting from input_filenames = set([]) try: audiofiles = audiotools.open_files(args, messenger=msg, no_duplicates=True, opened_files=input_filenames) except audiotools.DuplicateFile, err: msg.error(_.ERR_DUPLICATE_FILE % (err.filename,)) sys.exit(1) if (len(audiofiles) < 1): msg.error(_.ERR_FILES_REQUIRED) sys.exit(1) if ((options.sample_rate is not None) and (options.sample_rate < 1)): msg.error(_.ERR_INVALID_SAMPLE_RATE) sys.exit(1) if ((options.channels is not None) and
def add_replay_gain(cls, filenames, progress=None): """Adds ReplayGain values to a list of filename strings. All the filenames must be of this AudioFile type. Raises ValueError if some problem occurs during ReplayGain application. """ from audiotools.replaygain import ReplayGain, ReplayGainReader import tempfile wave_files = [track for track in open_files(filenames) if isinstance(track, cls)] track_gains = [] total_frames = sum([track.total_frames() for track in wave_files]) * 2 processed_frames = 0 #first, calculate the Gain and Peak values from our files for original_wave in wave_files: try: rg = ReplayGain(original_wave.sample_rate()) except ValueError: track_gains.append((None, None)) pcm = original_wave.to_pcm() try: try: frame = pcm.read(BUFFER_SIZE) while (len(frame) > 0): processed_frames += frame.frames if (progress is not None): progress(processed_frames, total_frames) rg.update(frame) frame = pcm.read(BUFFER_SIZE) track_gains.append(rg.title_gain()) except ValueError: track_gains.append((None, None)) finally: pcm.close() #then, apply those Gain and Peak values to our files #rewriting the originals in the process for (original_wave, (gain, peak)) in zip(wave_files, track_gains): if (gain is None): continue temp_wav_file = tempfile.NamedTemporaryFile(suffix=".wav") try: (header, footer) = original_wave.pcm_split() temp_wav_file.write(header) replaygain_pcm = ReplayGainReader(original_wave.to_pcm(), gain, peak) frame = replaygain_pcm.read(BUFFER_SIZE) while (len(frame) > 0): processed_frames += frame.frames if (progress is not None): progress(processed_frames, total_frames) temp_wav_file.write(frame.to_bytes( False, original_wave.bits_per_sample() > 8)) frame = replaygain_pcm.read(BUFFER_SIZE) temp_wav_file.write(footer) temp_wav_file.seek(0, 0) new_wave = open(original_wave.filename, 'wb') transfer_data(temp_wav_file.read, new_wave.write) new_wave.close() finally: temp_wav_file.close()
def audiotools_audiofile(self): audiotools_filename = audiotools.Filename.from_unicode(self.abs_path()) audiofile = audiotools.open_files((audiotools_filename,))[0] return audiofile