def write_basic_tags(self, modify_tags, set_artist_to_album, set_version): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if modify_tags: if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate if set_artist_to_album: audio.tags['artist'] = self.album if type(audio) is EasyMP3: audio.save(v2_version=set_version) else: # Not actually audio audio.save()
def tag(self): data = self.get_parent_instance().metadata() with tempfile.NamedTemporaryFile(suffix='-musicdb.mp3') as f: # Download with default_storage.open(self.file.location) as g: contents = g.read() f.write(contents) f.flush() f.seek(0) audio = MutagenFile(f.name) audio.delete() if isinstance(audio, mp3.MP3): audio.tags = easyid3.EasyID3() audio.update(data) audio.save() self.length = int(audio.info.length) # Copy it back default_storage.delete(self.file.location) dst = default_storage.save(self.file.location, DjangoFile(f)) assert dst == self.file.location
class TFileType(TestCase): def setUp(self): self.vorbis = File(os.path.join(DATA_DIR, "empty.ogg")) fd, filename = mkstemp(".mp3") os.close(fd) shutil.copy(os.path.join(DATA_DIR, "xing.mp3"), filename) self.mp3_notags = File(filename) self.mp3_filename = filename def tearDown(self): os.remove(self.mp3_filename) def test_delitem_not_there(self): self.failUnlessRaises(KeyError, self.vorbis.__delitem__, "foobar") def test_add_tags(self): self.failUnlessRaises(NotImplementedError, FileType().add_tags) def test_delitem(self): self.vorbis["foobar"] = "quux" del(self.vorbis["foobar"]) self.failIf("quux" in self.vorbis) def test_save_no_tags(self): self.assertTrue(self.mp3_notags.tags is None) self.mp3_notags.save() self.assertTrue(self.mp3_notags.tags is None)
def write_basic_tags(self, modify_tags, set_artist_to_album, set_version): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if modify_tags: if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.subtitle is not None: audio.tags['subtitle'] = self.subtitle if self.subtitle is not None: audio.tags['comments'] = self.subtitle if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate if set_artist_to_album: audio.tags['artist'] = self.album if type(audio) is EasyMP3: audio.save(v2_version=set_version) else: # Not actually audio audio.save()
def fix_cover(audio: File): """ Transfers album cover from audio key APIC:XXXX to APIC: Example audio['APIC: Payday 2.jpg'] = APIC() becomes audio['APIC:'] = APIC() """ restart = False for k in audio.keys(): if k.startswith('APIC:') and k != 'APIC:': apic = audio.pop(k) apic.desc = '' apic.encoding = 0 audio['APIC:'] = apic audio.save() restart = True break elif k == 'APIC:' and audio[k].encoding != 0: apic = audio.pop(k) apic.desc = '' apic.encoding = 0 audio[k] = apic audio.save() restart = True break if restart: fix_cover(audio)
def write_info2file(self, info): # open file with mutagen audio = File(info['filename'], easy=True) if audio is None: return # write title+album information into audio files if audio.tags is None: audio.add_tags() # write album+title if info['album'] is not None: audio.tags['album'] = info['album'] if info['title'] is not None: audio.tags['title'] = info['title'] # write genre tag if self.container.config.genre_tag is not None: audio.tags['genre'] = self.container.config.genre_tag else: audio.tags['genre'] = '' # write pubDate if info['pubDate'] is not None: audio.tags['date'] = info['pubDate'] audio.save()
def set_info(file, sformat, art='', alb='', img='', nam=''): if sformat == 'm4a': mu = File(file) if art: mu['©ART'] = art if alb: mu['©alb'] = alb if img: mu['covr'] = [MP4Cover(img)] if nam: mu['©nam'] = nam mu.save() elif sformat == 'mp3': audio = ID3(file) if img: #img: audio['APIC'] = APIC(encoding=3, mime='image/jpeg', sformat=3, desc=u'Cover', data=img) if nam: #title audio['TIT2'] = TIT2(encoding=3, text=[nam]) if art: #art: audio['TPE1'] = TPE1(encoding=3, text=[art]) if alb: #album: audio['TALB'] = TALB(encoding=3, text=[alb]) audio.save()
def generate_music(self): if 'attachments' in self.post: log.info('[AP] Извлечение аудио...') log.info('[AP] Данная функция находится в стадии тестирования.') n = 0 session.http.cookies.update(dict(remixmdevice=self.remixmdevice)) user_id = api_vk.users.get()[0]['id'] for attachment in self.post['attachments']: if attachment['type'] == 'audio': post_url = 'https://m.vk.com/wall%(owner_id)s_%(id)s' % self.post soup = BeautifulSoup(session.http.get(post_url).text, 'html.parser') track_list = [decode_audio_url(track.get('value'), user_id) for track in soup.find_all(type='hidden') if 'mp3' in track.get('value')] dur_list = [dur.get('data-dur') for dur in soup.find_all('div') if dur.get('data-dur')] name = sub(r"[/\"?:|<>*]", '', attachment['audio']['artist'] + ' - ' + attachment['audio']['title'] + '.mp3') try: file = download(track_list[n], out=name) except urllib.error.URLError: continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = attachment['audio']['title'] music['artist'] = attachment['audio']['artist'] music.save() del music self.tracks.append((name, dur_list[n])) n += 1
def ensure_id3_tag_present(filepath): try: meta = EasyID3(filepath) except ID3NoHeaderError: meta = File(filepath, easy=True) meta.add_tags() meta.save()
class TFileType(TestCase): def setUp(self): self.vorbis = File(os.path.join(DATA_DIR, "empty.ogg")) filename = get_temp_copy(os.path.join(DATA_DIR, "xing.mp3")) self.mp3_notags = File(filename) self.mp3_filename = filename def tearDown(self): os.remove(self.mp3_filename) def test_delitem_not_there(self): self.failUnlessRaises(KeyError, self.vorbis.__delitem__, "foobar") def test_add_tags(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") self.failUnlessRaises(NotImplementedError, FileType().add_tags) def test_delitem(self): self.vorbis["foobar"] = "quux" del(self.vorbis["foobar"]) self.failIf("quux" in self.vorbis) def test_save_no_tags(self): self.assertTrue(self.mp3_notags.tags is None) self.assertTrue(self.mp3_notags.filename) self.mp3_notags.save() self.assertTrue(self.mp3_notags.tags is None)
def cleanup_tags(self) -> None: '''Delete any ReplayGain tags from track. This dicards any unsaved changes, then modifies and saves the track's tags on disk and then reloads the new tags from disk. ''' tags_to_clean = set(rg_tags) # type: Set[str] tags_to_clean.update('QuodLibet::' + tag for tag in rg_tags) tags_to_clean.update('TXXX:' + tag for tag in rg_tags) tags_to_clean.update(['RVA2:track', 'RVA2:album']) tags_to_clean = { tag.lower() for tag in tags_to_clean } # Need a non-easy interface for proper ID3 cleanup t = MusicFile(self.filename, easy=False) tags_to_delete = [] for k in t.keys(): if k.lower() in tags_to_clean: tags_to_delete.append(k) for k in tags_to_delete: logger.debug("Deleting tag: %s", repr(k)) del t[k] t.save() # Re-init to pick up tag changes new_track = type(self.track)(self.filename) self.track = new_track
def _write_flac_tags(self, path, track, tags=None): if "DATA" in track: track = track["DATA"] if not tags: tags = self.get_track_tags(track) audio = File(path) audio.delete() cover = tags["_albumart"] del tags["_albumart"] if cover: pic = mutagen.flac.Picture() pic.data = cover["image"] audio.clear_pictures() audio.add_picture(pic) for key, val in tags.items(): if val: audio[key] = str(val) audio.save() return True
class TFileType(TestCase): def setUp(self): self.vorbis = File(os.path.join(DATA_DIR, "empty.ogg")) filename = get_temp_copy(os.path.join(DATA_DIR, "xing.mp3")) self.mp3_notags = File(filename) self.mp3_filename = filename def tearDown(self): os.remove(self.mp3_filename) def test_delitem_not_there(self): self.failUnlessRaises(KeyError, self.vorbis.__delitem__, "foobar") def test_add_tags(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") self.failUnlessRaises(NotImplementedError, FileType().add_tags) def test_delitem(self): self.vorbis["foobar"] = "quux" del (self.vorbis["foobar"]) self.failIf("quux" in self.vorbis) def test_save_no_tags(self): self.assertTrue(self.mp3_notags.tags is None) self.assertTrue(self.mp3_notags.filename) self.mp3_notags.save() self.assertTrue(self.mp3_notags.tags is None)
def saveAlbumInfo(self): """ 保存专辑信息 """ # 禁用小部件 # self.__setWidgetEnable(False) # 显示动图 # self.__showLoadingGif() # 更新标签信息 self.albumInfo['album'] = self.albumNameLineEdit.text() self.albumInfo['songer'] = self.albumSongerLineEdit.text() self.albumInfo['tcon'] = self.tconLineEdit.text() for songInfo, songInfoWidget in zip(self.songInfo_list, self.songInfoWidget_list): album_list = adjustAlbumName(self.albumNameLineEdit.text()) songInfo['album'] = album_list[0] songInfo['modifiedAlbum'] = album_list[-1] songInfo['songName'] = songInfoWidget.songNameLineEdit.text() songInfo['songer'] = songInfoWidget.songerLineEdit.text() songInfo['tcon'] = self.tconLineEdit.text() # 根据后缀名选择曲目标签的写入方式 songInfo['tracknumber'] = songInfoWidget.trackNumLineEdit.text() # 实例化标签卡 id_card = File(songInfo['songPath']) modifySongInfo(id_card, songInfo) try: id_card.save() except MutagenError: self.__saveErrorSlot(songInfoWidget) songInfoWidget.setSaveSongInfoErrorMsgHidden(False) break if not self.saveErrorHappened: self.saveAlbumCover() self.saveInfoSig.emit(self.albumInfo) self.parent().deleteLater() self.saveErrorHappened = False
def add_metadata(filename: str, args): """Add metadata to an existing file.""" f = File(filename) f.add_tags() for title, tag in METADATA_FIELDS.items(): f.tags.add(tag(encoding=Encoding.UTF8, text=[getattr(args, title)])) f.save()
def generate_music(self): if 'audio' in self.attachments_types: log.info('[AP] Извлечение аудио...') n = 0 self.session.http.cookies.update(dict(remixmdevice=self.remixmdevice)) user_id = self.api_vk.users.get()[0]['id'] for attachment in self.post['attachments']: if attachment['type'] == 'audio': post_url = 'https://m.vk.com/wall%(owner_id)s_%(id)s' % self.post soup = BeautifulSoup(self.session.http.get(post_url).text, 'html.parser') track_list = [decode_audio_url(track.get('value'), user_id) for track in soup.find_all(type='hidden') if 'mp3' in track.get('value')] dur_list = [dur.get('data-dur') for dur in soup.find_all('div') if dur.get('data-dur')] name = sub(r"[/\"?:|<>*]", '', attachment['audio']['artist'] + ' - ' + attachment['audio']['title'] + '.mp3') try: file = download(track_list[n], out=name) except (urllib.error.URLError, IndexError): log.exception('[AP] Не удалось скачать аудиозапись. Пропускаем ее...') continue if getsize(file) > 52428800: log.warning('[AP] Файл весит более 50 МиБ. Пропускаем его...') continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = attachment['audio']['title'] music['artist'] = attachment['audio']['artist'] music.save() del music self.tracks.append((name, dur_list[n])) n += 1
def tag(filename, data): audio = File(filename) audio.delete() if isinstance(audio, mp3.MP3): audio.tags = easyid3.EasyID3() audio.update(data) audio.save()
def postProcessSong(self, song): if self.shouldGenerateTags: try: name = self.getSongPath(song) localList = song.name.split("- ") #The song should be split as "artist - title". If not, it won't be recognized artist = localList[0] if len(localList) > 1 else self.defaultArtist #The artist is usually first if its there. Otherwise no artist if self.allSongsDefaultArtist: artist = self.defaultArtist title = localList[1] if len(localList) > 1 else localList[0] #If there is no artist, the whole name is the title artist = artist.lstrip().rstrip() title = title.lstrip().rstrip() #Appreciate this. It took upwards of 5 hours to get the damn software to do this. try: songID = EasyID3(name) except ID3NoHeaderError: songID = MutagenFile(name, easy = True) songID.add_tags() songID['artist'] = artist songID['title'] = title songID.save() songID = ID3(name, v2_version=3) #EasyID3 doesn't support saving as 2.3 to get Windows to recognize it songID.update_to_v23() songID.save(v2_version=3) except FileNotFoundError: debug("File not found for: ", name)
def generate_music(self): if 'audio' in self.attachments_types: log.info('[AP] Извлечение аудио...') user_id = self.api_vk.users.get()[0]['id'] response = self.audio_session._vk.http.get(self.post_url) tracks = scrap_data(response.text, user_id, filter_root_el={'class': 'audios_list'}) for track in tracks: name = sub(r"[^a-zA-Z '#0-9.а-яА-Я()-]", '', track['artist'] + ' - ' + track['title'] + '.mp3') try: file = download(track['url'], out=name) except (urllib.error.URLError, IndexError): log.exception( '[AP] Не удалось скачать аудиозапись. Пропускаем ее...' ) continue if getsize(file) > 52428800: log.warning( '[AP] Файл весит более 50 МиБ. Пропускаем его...') continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = track['title'] music['artist'] = track['artist'] music.save() del music self.tracks.append((name, track['duration']))
def set_OPUS_data(song, song_path): """ Set the data into an OPUS container according to the passed data. """ COVER_ADDED = False try: SONG_PATH = os.path.join(defaults.DEFAULT.SONG_TEMP_DIR, song_path) mutagen_file = File(SONG_PATH) # Try adding the tags container try: mutagen_file.add_tags() except Exception: # If exception is thrown, the tags already exist pass # Clear out the tags from the file mutagen_file.clear() # Try adding the cover if dwCover(song): imagedata = open(defaults.DEFAULT.COVER_IMG, 'rb').read() picture = Picture() picture.data = imagedata picture.type = PictureType.COVER_FRONT picture.mime = "image/jpeg" encoded_data = b64encode(picture.write()) mutagen_file["metadata_block_picture"] = encoded_data.decode( "ascii") # Remove the image os.remove(defaults.DEFAULT.COVER_IMG) COVER_ADDED = True # Add the tags now # Refer to https://www.programcreek.com/python/example/63675/mutagen.File # for more information on it mutagen_file["Title"] = song.track_name mutagen_file["Album"] = song.collection_name mutagen_file["Artist"] = song.artist_name mutagen_file["Date"] = song.release_date mutagen_file["Genre"] = song.primary_genre_name mutagen_file.save() defaults.DEFAULT.SONG_NAME_TO_SAVE = song.track_name + '.opus' # Rename the downloaded file os.rename(SONG_PATH, os.path.join( defaults.DEFAULT.SONG_TEMP_DIR, defaults.DEFAULT.SONG_NAME_TO_SAVE )) return COVER_ADDED except Exception as e: return e
def fixup_ID3(fname: Union[str, MusicFileType]) -> None: '''Convert RVA2 tags to TXXX:replaygain_* tags. Argument should be an MusicFile (instance of mutagen.FileType) or a string, which will be loaded by mutagen.MusicFile. If it is an instance of mutagen.id3.ID3FileType, the ReplayGain information in the RVA2 tags (if any) will be propagated to 'TXXX:replaygain_*' tags. Thus the resulting file will have the ReplayGain information encoded both ways for maximum compatibility. If the track is an instance of 'mutagen.mp3.EasyMP3', it will be re-opened as the non-easy equivalent, since EasyMP3 maps the replaygain tags to RVA2, preventing the editing of the TXXX tags. This function modifies the file on disk. ''' # Make sure we have the non-easy variant. if isinstance(fname, MusicFileType): fname = fname.filename # type: ignore track = MusicFile(fname, easy=False) # Only operate on ID3 if not isinstance(track, id3.ID3FileType): return # Get the RVA2 frames try: track_rva2 = track['RVA2:track'] if track_rva2.channel != 1: track_rva2 = None except KeyError: track_rva2 = None try: album_rva2 = track['RVA2:album'] if album_rva2.channel != 1: album_rva2 = None except KeyError: album_rva2 = None # Add the other tags based on RVA2 values if track_rva2: track['TXXX:replaygain_track_peak'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_track_peak', text=format_peak(track_rva2.peak)) track['TXXX:replaygain_track_gain'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_track_gain', text=format_gain(track_rva2.gain)) if album_rva2: track['TXXX:replaygain_album_peak'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_album_peak', text=format_peak(album_rva2.peak)) track['TXXX:replaygain_album_gain'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_album_gain', text=format_gain(album_rva2.gain)) track.save()
def fixup_ID3(fname: Union[str, MusicFileType]) -> None: '''Convert RVA2 tags to TXXX:replaygain_* tags. Argument should be an MusicFile (instance of mutagen.FileType) or a string, which will be loaded by mutagen.MusicFile. If it is an instance of mutagen.id3.ID3FileType, the ReplayGain information in the RVA2 tags (if any) will be propagated to 'TXXX:replaygain_*' tags. Thus the resulting file will have the ReplayGain information encoded both ways for maximum compatibility. If the track is an instance of 'mutagen.mp3.EasyMP3', it will be re-opened as the non-easy equivalent, since EasyMP3 maps the replaygain tags to RVA2, preventing the editing of the TXXX tags. This function modifies the file on disk. ''' # Make sure we have the non-easy variant. if isinstance(fname, MusicFileType): fname = fname.filename track = MusicFile(fname, easy=False) # Only operate on ID3 if not isinstance(track, id3.ID3FileType): return # Get the RVA2 frames try: track_rva2 = track['RVA2:track'] if track_rva2.channel != 1: track_rva2 = None except KeyError: track_rva2 = None try: album_rva2 = track['RVA2:album'] if album_rva2.channel != 1: album_rva2 = None except KeyError: album_rva2 = None # Add the other tags based on RVA2 values if track_rva2: track['TXXX:replaygain_track_peak'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_track_peak', text=format_peak(track_rva2.peak)) track['TXXX:replaygain_track_gain'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_track_gain', text=format_gain(track_rva2.gain)) if album_rva2: track['TXXX:replaygain_album_peak'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_album_peak', text=format_peak(album_rva2.peak)) track['TXXX:replaygain_album_gain'] = \ id3.TXXX(encoding=id3.Encoding.UTF8, desc='replaygain_album_gain', text=format_gain(album_rva2.gain)) track.save()
def set_tags(cls, audiobook, file_name): tags = getattr(audiobook, "%s_tags" % cls.ext)['tags'] if not tags.get('flac_sha1'): tags['flac_sha1'] = audiobook.get_source_sha1() audio = File(file_name) for k, v in tags.items(): audio[k] = v audio.save()
def saving(file: File): """ calls save method on the object :param file: file to be saved :type file: File """ yield file file.save(v2_version=3, v1=2)
def set_track_metadata(self, track = None, filename = None, url = None): """Find and set all metadata for a track""" if url == None or track == None: return None if filename == None: filename = get_track_filename(url) # id3 is only for mp3 if not filename.endswith(".mp3"): if filename.endswith(".wav"): filename = self.convert_wav_to_mp3(filename) else: return None # Set title try: meta = ID3(filename) except ID3NoHeaderError: try: meta = File(filename, easy=True) meta.add_tags() meta.save() meta = ID3(filename) except: return except IOError: return try: meta.add(TIT2(encoding=3, text=track.title)) meta.add(TCON(encoding=3, text=track.genre)) meta.add(TCOM(encoding=3, text=track.user["username"])) meta.save() artwork_filename = wget.download(track.artwork_url) audio = MP3(filename, ID3=ID3) # add ID3 tag if it doesn't exist try: audio.add_tags() except error: pass audio.tags.add( APIC( encoding=3, # 3 is for utf-8 mime='image/jpeg', # image/jpeg or image/png type=3, # 3 is for the cover image desc=u'Cover', data=open(artwork_filename).read() ) ) audio.save() except: return
class Tag(object): def __init__(self, filename): self.tags = File(filename, easy=True) if self.tags == None: raise TagTypeError() @property def album(self): return self.tags.get('album') @album.setter def album(self, value): self.tags['album'] = value @album.deleter def album(self): del self.tags['album'] @property def artist(self): return self.tags.get('artist') @artist.setter def artist(self, value): self.tags['artist'] = value @artist.deleter def artist(self): del self.tags['artist'] @property def title(self): return self.tags.get('title') @title.setter def title(self, value): self.tags['title'] = value @title.deleter def title(self): del self.tags['title'] @property def track(self): return self.tags.get('tracknumber') @track.setter def track(self, value): self.tags['tracknumber'] = value @track.deleter def track(self): del self.tags['tracknumber'] def save(self): self.tags.save();
def add_tags(self): self.logger.debug("Started adding tags to YouTube tracks") tag_count = 0 downloaded_track: DownloadedTrack for downloaded_track in self.all_tracks_to_download: if "name" in downloaded_track.youtube_tags: file_path = Path(downloaded_track.youtube_tags["filepath"]) try: tagged_file = ID3() except mutagen.id3.ID3NoHeaderError: tagged_file = File() tagged_file.add_tags() tagged_file.save() tagged_file = ID3() if downloaded_track.youtube_tags["name"]: tagged_file["TIT2"] = TIT2( encoding=3, text=downloaded_track.youtube_tags["name"]) if downloaded_track.youtube_tags["track_number"]: try: tagged_file["TRCK"] = TRCK( encoding=3, text=str( downloaded_track.youtube_tags["track_number"])) except: tagged_file["TRCK"] = TRCK(encoding=3, text=u"1") if downloaded_track.youtube_tags["album"]: tagged_file["TALB"] = TALB( encoding=3, text=downloaded_track.youtube_tags["album"]) if downloaded_track.youtube_tags["artist"]: tagged_file["TPE1"] = TPE1( encoding=3, text=downloaded_track.youtube_tags["artist"]) tagged_file.save(file_path) while True: try: file_path.rename(file_path) except: continue break new_path = Path(file_path.parent / Path( util.clean_path_child( f"{downloaded_track.youtube_tags['artist']} - {downloaded_track.youtube_tags['name']}.mp3" ))) os.rename(file_path, new_path) downloaded_track.download_location = new_path downloaded_track.store_to_master_file() tag_count += 1 self.logger.debug( f"Finished adding tags to {tag_count} YouTube tracks")
def add_flac_cover(filename, albumart): audio = File(str(filename)) image = Picture() image.type = 3 image.mime = "image/jpeg" with open(albumart, 'rb') as f: image.data = f.read() audio.add_picture(image) audio.save()
def update_album_cover(filename, new_cover): conf = get_or_create_config() bak_conf = conf.copy() song_album = '' for album in bak_conf['library']: for i, song in enumerate(bak_conf['library'][album]['songs']): if song == filename: song_album = album image = Image.open(new_cover) output = StringIO.StringIO() image.save(output, format="JPEG") data = output.getvalue() output.close() audio = File(filename) audio.tags.add( APIC( encoding=3, # 3 is for utf-8 mime='image/jpeg', # image/jpeg or image/png type=3, # 3 is for the cover image desc=u'', data=data ) ) #from PyQt4.QtCore import pyqtRemoveInputHook #pyqtRemoveInputHook() #from IPython.Shell import IPShellEmbed; IPShellEmbed()() audio.save() break if song_album: break covers = set() for i, song in enumerate(bak_conf['library'][song_album]['songs']): covers.add(get_full_song_info(song)[4]) if len(covers) == 1: data = covers.pop() #print data if data: #all new cover are the same, updating album cover song_file = File(filename) album_name = get_cover_hash(song_file) iconpath = os.path.join(ROOT_PATH,'cover_cache',album_name+'.png') iconpath_jpg = os.path.join(ROOT_PATH,'cover_cache',album_name+'.jpg') with open(iconpath_jpg, 'wb') as img: img.write(data) im = Image.open(iconpath_jpg) #im = im.resize((cover_size, cover_size), Image.ANTIALIAS) im.thumbnail((cover_size,cover_size), Image.ANTIALIAS) im.save(iconpath) try: os.remove(iconpath_jpg) except: pass conf['library'][song_album]['cover'] = getCoverArt(filename)[0] save_config(conf)
def metadata(self): """ Updates metadata """ print("Starting to update metadata") glib = self.glib db = self.db man = self.man mMeta = {} for g in man.getAllMeta(): mMeta[g[0]] = {'title':g[1], 'artist':g[3], 'albumArtist':g[4], 'album':g[2], 'genre':g[6], 'trackNumber':g[7], 'totalTrackCount':g[8], 'diskNumber':g[9], 'totalDiskCount':g[10]} for i in glib: lid = db.getGLID(i['id']) if not lid: continue ipath = db.getPath(lid) try: m = mMeta[i['id']] except KeyError: db.addGID(lid, None) continue tags = [t for t in m for j in i if t == j] nMatch = [] for t in tags: if m[t] != i[t]: nMatch += [t] if nMatch: if '.mp3' in ipath or '.m4a' in ipath: try: sng = GLB(ipath, easy=True) except IOError: db.remove(lid) continue else: continue for n in nMatch: if '.mp3' in ipath and n == 'albumArtist': sng['performer'] = [i['albumArtist']] man.setMeta(i['id'], 'MusicAlbumArtist', i['albumArtist']) else: if n in ('trackNumber', 'totalTrackCount', 'diskNumber', 'totalDiskCount'): if n in ('trackNumber', 'totalTrackCount'): sng['tracknumber'] = [str(i['trackNumber']) + '/' + str(i['totalTrackCount'])] man.setMeta(i['id'], 'MusicTrackNumber', int(i['trackNumber'])) man.setMeta(i['id'], 'MusicTrackCount', int(i['totalTrackCount'])) else: sng['disknumber'] = [str(i['diskNumber']) + '/' + str(i['totalDiskCount'])] man.setMeta(i['id'], 'MusicDiscNumber', int(i['discNumber'])) man.setMeta(i['id'], 'MusicDiscCount', int(i['totalDiscCount'])) else: sng[n.lower()] = [i[n]] man.setMeta(i['id'], n.lower().replace('title', 'MusicName').replace('albumArtist', 'MusicAlbumArtist').replace('album', 'MusicAlbum').replace('artist', 'MusicArtist').replace('genre', 'MusicGenre'), i[n]) db.setUpMeta(lid) sng.save() print("Finished updating metadata")
def get_tag(args): abs_path = os.path.abspath(args.path) try: id3_tag = easyid3.EasyID3(abs_path) except id3.ID3NoHeaderError: id3_tag = File(abs_path, easy=True) id3_tag.add_tags() id3_tag.save() return id3_tag
def tag_file(filename, **kwargs): """Use mutagen to tag MP3 files.""" try: tag = EasyID3(filename) except ID3NoHeaderError: tag = File(filename, easy=True) tag.add_tags() for arg, value in kwargs.items(): tag[arg] = value tag.save(filename)
def send_song(self, chat_id, link) -> None: # Load video time.sleep(10) print(link) video = pytube.YouTube(link) # Check if video length is greater than 10 minutes if video.length > self.max_song_len: return None # Stream the video and set the title. It saves as mp4 even though it's only audio stream = video.streams.filter(only_audio=True).first() bio = BytesIO() stream.stream_to_buffer(bio) bio.name = video.title bio.seek(0) if " - " in bio.name: artist_name = bio.name[:bio.name.index(" - ")] song_name = bio.name[bio.name.index(" - ") + len(" - "):] album_name = video.author else: artist_name = video.author song_name = bio.name album_name = video.author # Get thumbnail as a BytesIO object thumb = self.get_thumb(video.thumbnail_url) # When I save the song to music on my phone, the meta tags don't save # So here I do it manually by setting it into the audio itself audio = File(bio) audio["\xa9alb"] = album_name # Album name audio["\xa9nam"] = song_name # Song name audio["\xa9ART"] = artist_name # Artist name audio["covr"] = [ MP4Cover(thumb.read(), imageformat=MP4Cover.FORMAT_JPEG) ] # Thumbnail audio.save(bio) # Reset to 0 bio.seek(0) thumb.seek(0) # Send it logging.debug( f"Sending audio {artist_name} - {song_name} (album {album_name})") Config.bot.send_audio(chat_id, bio, duration=video.length, title=song_name + ".mp3", performer=artist_name, thumb=thumb, timeout=1000) # self.bot.send_document(chat_id, bio, bio.name, timeout=1000) return None
def insert_coverart(self): audio = File(self.filename) if self.cover.endswith('png'): cover_format = MP4Cover.FORMAT_PNG else: cover_format = MP4Cover.FORMAT_JPEG data = open(self.cover, 'rb').read() audio.tags['covr'] = [MP4Cover(data, cover_format)] audio.save()
def writeAlbumCover(songPath: str, coverPath: str, picData=None): """ 给音频文件写入封面 Parameters ---------- songPath: 音频文件路径\n coverPath: 封面图片路径\n picData: 封面图片二进制数据 """ id_card = File(songPath) # 读取封面数据 if not picData: with open(coverPath, 'rb') as f: picData = f.read() # 获取音频数据和图片数据后缀名 audioSuffix = id_card.mime[0].split('/')[-1] try: picSuffix = imghdr.what(None, picData) except: picSuffix = 'jpeg' mimeType = 'image/' + picSuffix # 开始写入封面 if audioSuffix == 'mp3': keyName = 'APIC:' keyName_list = [] # 获取可能已经存在的封面键名 for key in id_card.tags.keys(): if key.startswith('APIC'): keyName = key keyName_list.append(key) # 弹出所有旧标签才能写入新数据 for key in keyName_list: id_card.pop(key) id_card[keyName] = APIC(encoding=0, mime=mimeType, type=3, desc='', data=picData) elif audioSuffix == 'flac': # 创建Picture实例 picture = Picture() # 设置属性值 picture.mime = mimeType picture.data = picData picture.type = 0 # 清除原来的图片数据 id_card.clear_pictures() # 添加图片 id_card.add_picture(picture) elif audioSuffix == 'mp4': try: id_card['covr'][0] = picData except: id_card['covr'] = [picData] # 没有键时需要创建一个 id_card.save()
def fix_cover(audio: File): """ Transfers album cover from audio key APIC:XXXX to APIC: Example audio['APIC: Payday 2.jpg'] = APIC() becomes audio['APIC:'] = APIC() """ for k in audio.keys(): if k.startswith('APIC:') and k != 'APIC:': audio['APIC:'] = audio.pop(k) audio.save() break
def get_id3_tags(self, file_name): try: self.audio_id3 = ID3(self.search_dir + "/" + file_name, v2_version=3) except _util.ID3NoHeaderError: file = File(self.search_dir + "/" + file_name) file.add_tags() file.save() self.audio_id3 = ID3(self.search_dir + "/" + file_name, v2_version=3) for tag in self.audio_id3: if tag.startswith("APIC") and (PictureType.COVER_FRONT == 3): image = QImage() image.loadFromData(self.audio_id3[tag].data) self.artwork_id3_label.setPixmap( QPixmap(image).scaled(150, 150)) break else: #TODO: default image should be stored as raw data self.artwork_id3_label.setPixmap(QPixmap("default.jpg")) if "TPE1" in self.audio_id3: self.artist_id3_edit.setText(str(self.audio_id3["TPE1"])) else: self.artist_id3_edit.clear() if "TIT2" in self.audio_id3: self.title_id3_edit.setText(str(self.audio_id3["TIT2"])) else: self.title_id3_edit.clear() if "TCON" in self.audio_id3: self.genre_id3_edit.setText(str(self.audio_id3["TCON"])) else: self.genre_id3_edit.clear() if "TALB" in self.audio_id3: self.album_id3_edit.setText(str(self.audio_id3["TALB"])) else: self.album_id3_edit.clear() if "TYER" in self.audio_id3: self.release_year_id3_edit.setText(str(self.audio_id3["TYER"])) else: self.release_year_id3_edit.clear() if "TRCK" in self.audio_id3: self.track_no_id3_edit.setText(str(self.audio_id3["TRCK"])) else: self.track_no_id3_edit.clear()
def on_episode_downloaded(self, episode): # exit if mutagen is not installed if not mutagen_installed: return # read filename (incl. file path) from gPodder database filename = episode.local_filename(create=False, check_only=True) if filename is None: return # open file with mutagen audio = File(filename, easy=True) if audio is None: return # read title+album from gPodder database album = episode.channel.title title = episode.title if (strip_album_from_title and title and album and title.startswith(album)): title = title[len(album):].lstrip() # convert pubDate to string try: pubDate = datetime.datetime.fromtimestamp( episode.pubDate).strftime('%Y-%m-%d %H:%M') except: pubDate = None # write title+album information into audio files if audio.tags is None: audio.add_tags() # write album+title if album is not None: audio.tags['album'] = album if title is not None: audio.tags['title'] = title # write genre tag if genre_tag is not None: audio.tags['genre'] = genre_tag else: audio.tags['genre'] = '' # write pubDate if pubDate is not None: audio.tags['date'] = pubDate audio.save() log(u'tagging.on_episode_downloaded(%s/%s)' % (episode.channel.title, episode.title))
class Tagging: def __init__(self, io): """ """ try: self.fileObj = io if self.fileObj.url.rsplit('.')[-1] != 'mp3': raise ExtensionException('Not Expecting file extension') self.audio = EasyID3(self.fileObj.path) except mutagen.id3.ID3NoHeaderError as err: self.audio = File(self.fileObj.path, easy=True) self.audio.add_tags() self.audio.save(self.fileObj.path, v1=2) except (mutagen.MutagenError, ExtensionException) as err: self.audio = None def add_tag(self, tags, image): if tags is not None: for key, value in tags.items(): if value is not None or value != '': if key != 'cover': self.audio[u'{}'.format(key)] = value self.audio.save(self.fileObj.path, v1=2) if image is not None: img = image.path fileObj = open(img.path, 'rb').read() img_ext = img.name.rsplit('.')[-1] multipart = [('jpg', 'image/jpeg'), ('png', 'image/png'), ('jpeg', 'image/jpeg')] img_typ = '' for typ in multipart: if img_ext in typ: img_typ = typ[1] break id3 = ID3(self.fileObj.path) id3.add(APIC(3, img_typ, 3, 'Front Cover', fileObj)) id3.save(v2_version=3) def tags(self): tags = {} if self.audio is not None: for key, value in self.audio.items(): tags[key] = value[0] return tags
def tag(input_file, metadata): try: audio = EasyID3(input_file) except ID3NoHeaderError: # If file does not currently have an id3 header # then create one. audio = File(input_file, easy=True) audio.add_tags() audio['title'] = metadata['title'] audio['artist'] = metadata['artist'] audio['album'] = metadata['album'] audio.save()
def update_id3_tags(self): """ Update ID3 tags of downloaded song """ # Must init ID3 tags for appropriate header settings audio = File(self.tags._title+'.mp3', easy=True) audio.add_tags() # Save new tags audio['title'] = self.tags._title audio['artist'] = self.tags._artist audio['album'] = self.tags._album audio.save(self.tags._title+'.mp3')
def tag_save(file: mutagen.File, destination_stream: t.IO[bytes]) -> t.IO[bytes]: """ Write the specified :class:`mutagen.File` to the passed destination stream (which can be any writeable file-like object), using no padding for the tag section. :param file: The file to save. :param destination_stream: The file-like object to save the file to. .. important:: The destination stream must be the same exact one that was used to create the ``file``, otherwise :mod:`mutagen` won't work! """ file.save(fileobj=destination_stream, padding=lambda _: 0) return destination_stream
def on_episode_downloaded(self, episode): # exit if mutagen is not installed if not mutagen_installed: return # read filename (incl. file path) from gPodder database filename = episode.local_filename(create=False, check_only=True) if filename is None: return # open file with mutagen audio = File(filename, easy=True) if audio is None: return # read title+album from gPodder database album = episode.channel.title title = episode.title if (strip_album_from_title and title and album and title.startswith(album)): title = title[len(album):].lstrip() # convert pubDate to string try: pubDate = datetime.datetime.fromtimestamp(episode.pubDate).strftime('%Y-%m-%d %H:%M') except: pubDate = None # write title+album information into audio files if audio.tags is None: audio.add_tags() # write album+title if album is not None: audio.tags['album'] = album if title is not None: audio.tags['title'] = title # write genre tag if genre_tag is not None: audio.tags['genre'] = genre_tag else: audio.tags['genre'] = '' # write pubDate if pubDate is not None: audio.tags['date'] = pubDate audio.save() log(u'tagging.on_episode_downloaded(%s/%s)' % (episode.channel.title, episode.title))
def run(self): while not self.__was_stopped: if self.downloader is not None and self.downloader.ended: f = File(self.downloader.downloaded_path(), easy=True) if not re.search('[a-zA-Z0-9]', self.queue[0].artist): if re.search('[a-zA-Z0-9]', f.get("artist", "")): self.queue[0].artist = f["artist"] else: self.queue[0].artist = "Unknown" f["artist"] = self.queue[0].artist else: f["artist"] = self.queue[0].artist if not re.search('[a-zA-Z0-9]', self.queue[0].album): if re.search('[a-zA-Z0-9]', f.get("album", "")): self.queue[0].album = f["album"] else: self.queue[0].album = "Unknown" f["album"] = self.queue[0].album else: f["album"] = self.queue[0].album if not re.search('[a-zA-Z0-9]', self.queue[0].track): if re.search('[a-zA-Z0-9]', f.get("title", "")): self.queue[0].track = f["title"] else: self.queue[0].track = join(self.downloader.downloaded_path().split("/")[-1].split(".")[0:-1], '.') f["title"] = self.queue[0].track else: f["title"] = self.queue[0].track print f.tags f.save() target_dir = join([config.download_path, safe_filename(self.queue[0].artist), safe_filename(self.queue[0].album)], "/") if not os.path.exists(target_dir): os.makedirs(target_dir) file_path = target_dir + "/" + safe_filename(self.queue[0].track) + "_" + random_string() + "." + \ self.downloader.downloaded_path().split(".")[-1] shutil.move(self.downloader.downloaded_path(), file_path) library.add_track(TrackInfo(file_path)) del self.queue[0] self.downloader = None if len(self.queue) > 0: self.start_download() time.sleep(1)
def tag(self): try: data = self.get_parent_instance().metadata() filename = os.path.join(settings.MEDIA_LOCATION, self.file.location) audio = MutagenFile(filename) audio.delete() if isinstance(audio, mp3.MP3): audio.tags = easyid3.EasyID3() audio.update(data) audio.save() except: self.tags_dirty = None self.save() raise finally: self.tags_dirty = False self.save()
def download(self, path: str, web_driver: WebDriver = None, service_url: str = '', lyrics='', website='', comment=''): file_path = super().download(path) try: meta = id3.ID3(file_path) except id3.ID3NoHeaderError: meta = File(file_path) meta.add_tags() if web_driver: lyrics = self.load_lyrics(web_driver) meta['TPE1'] = id3._frames.TPE1(text=[self.artist]) meta['TIT2'] = id3._frames.TIT2(text=[self.title]) meta['USLT'] = id3._frames.USLT(text=lyrics) meta['WORS'] = id3._frames.WORS(text=[website]) meta['COMM'] = id3._frames.COMM(text=[comment]) meta.save() return file_path
def convert_file(self, full_path): try: out_path = self.get_out_path(full_path) lame_options = self.lame_options or ['--preset', 'standard', '-h'] metadata = FLAC(full_path) try: os.makedirs(os.path.dirname(out_path)) except OSError as e: if e.errno != 17: raise # only raise if not "file exists" error flac_p = subprocess.Popen( [self.flac, '-s', '-d', '--stdout', full_path], stdout=subprocess.PIPE, preexec_fn=ignore_sigint) lame_cmd = [self.lame] + lame_options + ['--quiet', '-', out_path] lame_p = subprocess.Popen(lame_cmd, stdin=flac_p.stdout, preexec_fn=ignore_sigint) flac_p.wait() lame_p.wait() # now apply gain if self.apply_mp3gain: mp3gain_cmd = [self.mp3gain, '-q', '-T', '-r', '-k', out_path] subprocess.check_call(mp3gain_cmd, stdout=open('/dev/null', 'wb')) # finally, correct the tags id3data = File(out_path, easy=True) for attr in ('title', 'artist', 'album', 'date', 'genre', 'tracknumber'): id3data[attr] = metadata.get(attr) id3data.save() except Exception as e: status_queue.put(('ERROR', full_path, str(e))) if os.path.exists(out_path): os.unlink(out_path) else: status_queue.put(('OK', full_path, out_path))
def write_basic_tags(self): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate audio.save()
def transfer_tags(flacfile, wavpackfile): """docstring for transfer_tags""" fl = File(flacfile) wv = File(wavpackfile) wv.update(fl) try: wv["track"] = wv["tracknumber"] del wv["tracknumber"] if wv["totaltracks"]: wv["track"] = wv["track"][0] + "/" + wv["totaltracks"][0] del wv["totaltracks"] wv["disc"] = wv["discnumber"] del wv["discnumber"] if wv["totaldiscs"]: wv["disc"] = wv["disc"][0] + "/" + wv["totaldiscs"][0] del wv["totaldiscs"] except KeyError: pass wv.save()
def write_basic_tags(self): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate if self.container.config.set_artist_to_album: audio.tags['artist'] = self.album audio.save()
def complete_album(fileset, targetcodec, outfiles): newreplaygain = False metas = [] for file in fileset: meta = file.meta.copy() if not (file.lossless and targetcodec.lossless): for key in rg_keys: if key in meta: del meta[key] for key in rg_keys: if key not in meta: newreplaygain = True break metas.append(meta) if targetcodec.has_replaygain and newreplaygain: metas = (yield targetcodec.add_replaygain(outfiles, metas)) or metas outfile_objs = [] fromdir = set() sourcefiles = set() sourcepaths = [] for meta, outfile in zip(metas, outfiles): fromdir.add(meta["dir"]) sourcefiles.add(meta["name"]) sourcepaths.append(meta["path"]) outfile_obj = File(outfile) meta.apply(outfile_obj) outfile_obj.save() outfile_objs.append(outfile_obj) if len(fromdir) == 1: fromdir = fromdir.pop() ignorefiles = frozenset(sourcefiles) else: fromdir = False ignorefiles = False copy_rename_files(outfile_objs, fromdir, ignorefiles, sourcepaths, "move") for outfile in outfiles: if os.path.exists(outfile): err(consoleformat="Temporary file %(file)r still exists after it should have been renamed.", file=outfile)
def add_metadata(self, path, link, genre): if os.path.isfile(path): fn = path.split('/')[-1] vi = fn.split('__')[0] vidinfo = re.sub("[\(\[].*?[\)\]]", "", vi) if '-' in vidinfo: artist = vidinfo.split('-')[0] fulltitle = vidinfo.split('-')[1] title = fulltitle.split('__')[0] else: title = vidinfo artist = '' if '?' in link: link = link.split('?')[0] try: song = EasyID3(path) except ID3NoHeaderError: song = File(path, easy=True) song['title'] = title song['artist'] = artist song['genre'] = genre song['website'] = link song.save()
def etiquetas(self): etiquetas = None try: etiquetas = mutagen.id3.ID3(self.archivo) except mutagen.id3.ID3NoHeaderError: etiquetas = mutagen.id3.ID3() finally: try: etiquetas['TIT2'] except KeyError: etiquetas['TIT2'] = mutagen.id3.TIT2(encoding=3, text=self.nombre) try: etiquetas['TALB'] except KeyError: etiquetas['TALB'] = mutagen.id3.TALB(encoding=3, text=self.album) try: etiquetas['TPE2'] except KeyError: etiquetas['TPE2'] = mutagen.id3.TPE2(encoding=3, text=self.artista) try: etiquetas['TDRC'] except KeyError: etiquetas['TDRC'] = mutagen.id3.TDRC(encoding=3, text=str(self.fecha)) try: etiquetas['TCON'] except KeyError: etiquetas['TCON'] = mutagen.id3.TCON(encoding=3, text=self.genero) etiquetas.save(self.archivo) if self.cover['archivo'].endswith('jpg'): audio = File(self.archivo) try: audio.tags['APIC:'] except KeyError: data = open(self.cover['archivo'], 'rb').read() audio.tags.add(mutagen.id3.APIC(encoding=3, mime='image/jpeg', type=3, desc=u'Cover', data=data)) audio.save()
def append_metadata(track_file, expected_tags): if track_file is None or expected_tags is None: return metadata = File(track_file, easy=True) # print unicode(track_file), "=============>", if 'musicName' in expected_tags: if 'title' in metadata and len(metadata['title']) > 0: metadata['title'][0] = expected_tags['musicName'] else: title = list() title.append(expected_tags['musicName']) metadata['title'] = title if 'album' in expected_tags: if 'album' in metadata and len(metadata['album']) > 0: metadata['album'][0] = expected_tags['album'] else: album = list() album.append(expected_tags['album']) metadata['album'] = album # album artist is not correct if 'artist' in expected_tags: artists = [] artist_array = expected_tags['artist'] for artist in artist_array: artists.append(artist[0]) metadata['performer'] = artists if 'genre' in metadata: del(metadata['genre']) if 'copyright' in metadata: del(metadata['copyright']) metadata.save()
def split_item(item, DIGITAL_FOLDER=mp3_folder, DROPBOX_COPY=False): logging.info('BLOOOAAARRRRGHHGGGGHHHHH!!! (Please hold...)') audio = wave.open(item.path) audio.params = audio.getparams() # Load AudioSegment for encoded segments if item.digital_ext is not 'wav': audio_segment = AudioSegment.from_wav(item.path) # Loop through cues and write regions (assumes start and end markers) for i, track in enumerate(item.tracks): # Build track filename digital_track_name = '{0} - {1} - {2}'.format(item.digital_file_name, str(i + 1), track.title) digital_track_name = ''.join([c for c in digital_track_name if c.isalpha() or c.isdigit() or c in "'- ._()!@#$%^&*"]).rstrip('. ') digital_track_path = os.path.join(DIGITAL_FOLDER, digital_track_name) + '.' + item.digital_ext logging.info('Region {0} | {1} -> {2}'.format(i + 1, track.duration, digital_track_path)) # Split, export track if 'wav' not in item.digital_ext: digital_track = audio_segment[(item.cues[i] / 44.1):(item.cues[i + 1] / 44.1)] tags = {'title':track.title, 'artist':item.artist, 'albumartist':item.artist, 'album':(item.album or item.artist), 'track':(i + 1)} digital_track.export(out_f=digital_track_path, format=item.digital_ext, bitrate='192k', tags=tags) # Add cover art if item.thumb and (item.digital_ext == 'mp3'): mutagen_audio = MP3(digital_track_path, ID3=ID3) try: # Add ID3 tag if it doesn't exist mutagen_audio.add_tags() except error: pass mutagen_audio.tags.add( APIC( encoding=3, # 3 is for utf-8 mime='image/jpeg', # image/jpeg or image/png type=3, # 3 is for the cover image desc=u'Cover', data=open(item.thumb_path, 'rb').read() ) ) mutagen_audio.save() elif item.thumb and (item.digital_ext == 'flac'): mutagen_audio = File(digital_track_path) flac_image = Picture() flac_image.type = 3 mime = 'image/jpeg' flac_image.desc = 'Cover' with open(item.thumb_path, 'rb') as f: flac_image.data = f.read() mutagen_audio.add_picture(flac_image) mutagen_audio.save() else: logging.warning('No cover found for item {0}'.format(item.name)) else: digital_track = wave.open(digital_track_path, 'w') digital_track.setparams(audio.params) region_length = item.cues[i + 1] - item.cues[i] digital_track.writeframes(audio.readframes(region_length)) digital_track.close() if DROPBOX_COPY: # Copy finished digital file to Dropbox order folder shutil.copy2(digital_track_path, item.dropbox_order_folder) audio.close()