def on_episode_downloaded(self, episode): log(u'on_episode_downloaded(%s/%s)' % (episode.channel.title, episode.title)) filename = episode.local_filename(create=False, check_only=True) if filename is None: return basename, extension = os.path.splitext(filename) if episode.file_type() == 'audio' and extension.lower() == '.ogg': log(u'trying to remove cover from %s' % filename) found = False try: ogg = OggVorbis(filename) for key in ogg.keys(): if key.startswith('cover'): found = True ogg[key]='' if found: log(u'removed cover from the ogg file successfully') ogg.save() else: log(u'there was no cover to remove in the ogg file') except: None
def rm_ogg_cover(self, episode): filename = episode.local_filename(create=False) if filename is None: return basename, extension = os.path.splitext(filename) if episode.file_type() != 'audio': return if extension.lower() != '.ogg': return try: ogg = OggVorbis(filename) found = False for key in ogg.keys(): if key.startswith('cover'): found = True ogg.pop(key) if found: logger.info('Removed cover art from OGG file: %s', filename) ogg.save() except Exception, e: logger.warn('Failed to remove OGG cover: %s', e, exc_info=True)
def download_and_fix_ogg(ogg, audio_metadata, cover_art_file): global DRY_RUN if DRY_RUN: print "This is a dry run. So pretending to download the ogg..." return "/tmp/ogg" print "Now downloading the ogg in order to set the metadata in it..." if not LIVE and len(sys.argv) >= 6 and os.path.exists(sys.argv[5]): ogg_local_fn = sys.argv[5] print "(using presupplied file %s)" % ogg_local_fn else: f, metadata = client.get_file_and_metadata(ogg) ogg_local_fn = fetch_file(f, metadata) print "Successfully downloaded (to %s): now editing metadata..." % ogg_local_fn audio = OggVorbis(ogg_local_fn) for k in audio_metadata.keys(): audio[k] = audio_metadata[k] # add cover art im=Image.open(cover_art_file) w,h=im.size p=Picture() imdata=open(cover_art_file,'rb').read() p.data=imdata p.type=3 p.desc='' p.mime='image/jpeg'; p.width=w; p.height=h p.depth=24 dt=p.write(); enc=base64.b64encode(dt).decode('ascii'); audio['metadata_block_picture']=[enc]; audio.save() print "Successfully updated metadata." return ogg_local_fn
class _EasyPythonMutagenOggVorbis(object): '''An interface like EasyId3, but for OggVorbis files.''' def __init__(self, filename): from mutagen.oggvorbis import OggVorbis self.obj = OggVorbis(filename) self.map = { 'album': 'album', 'comment': 'comment', 'artist': 'artist', 'title': 'title', 'albumartist': 'albumartist', 'tracknumber': 'tracknumber', 'discnumber': 'discnumber', 'composer': 'composer', 'genre': 'genre', 'description': 'description', 'website': 'www'} def __getitem__(self, key): return self.obj[self.map[key]] def __setitem__(self, key, val): self.obj[self.map[key]] = val def __contains__(self, key): return key in self.map and self.map[key] in self.obj def save(self): self.obj.save()
def main(args=None): ap = create_argparser() try: args = parse_args(ap, args) except ValueError: parser.print_help(sys.stderr) return 2 logging.basicConfig(format="%(name)s: %(levelname)s - %(message)s", level=logging.WARNING if args.quiet else logging.INFO) oggfile = OggVorbis(args.inputfile) if args.write and args.tag: oggfile.tags.clear() for name, value in args.tag or []: if args.append: value = oggfile.tags[name.upper()] + [value] oggfile.tags[name.upper()] = value if args.write or args.append: oggfile.save(args.outputfile) if args.list or not any((args.tag, args.write, args.append)): for tag, value in sorted(oggfile.tags): print("{}: {}".format(tag, value)) return 0
class _EasyPythonMutagenOggVorbis(object): '''An interface like EasyId3, but for OggVorbis files.''' def __init__(self, filename): from mutagen.oggvorbis import OggVorbis self.obj = OggVorbis(filename) self.map = { 'album': 'album', 'comment': 'comment', 'artist': 'artist', 'title': 'title', 'albumartist': 'albumartist', 'tracknumber': 'tracknumber', 'discnumber': 'discnumber', 'composer': 'composer', 'genre': 'genre', 'description': 'description', 'website': 'www'} def __getitem__(self, key): return self.obj[self.map[key]] def __setitem__(self, key, val): self.obj[self.map[key]] = val def __contains__(self, key): return key in self.map and self.map[key] in self.obj def save(self): self.obj.save()
def on_episode_downloaded(self, episode): filename = episode.local_filename(create=False, check_only=True) if filename is None: return (basename, extension) = os.path.splitext(filename) if episode.file_type() == 'audio' and extension.lower().endswith( 'ogg'): log(u'trying to remove cover from %s' % filename) found = False try: ogg = OggVorbis(filename) for key in ogg.keys(): if key.startswith('cover'): found = True ogg[key] = '' if found: log(u'removed cover from the ogg file successfully') ogg.save() else: log(u'there was no cover to remove in the ogg file') except: None
def set_start(filename, start_time): """ Writes the start of the song section to file """ song_meta = OggVorbis(filename) song_meta[Settings.song_start_tag] = start_time song_meta.save()
def embed_metadata(music_file, cover_image, song): """Add metadata to extracted OGG files. For details on the METADATA_BLOCK_PICTURE struct format, see https://xiph.org/flac/format.html#metadata_block_picture """ music_file.seek(0) audio = OggVorbis(music_file) audio["title"] = song.title audio["artist"] = song.artist audio["album"] = song.album_name audio["tracknumber"] = str(song.track_number) audio["tracktotal"] = str(song.track_total) if song.genre is not None: audio["genre"] = song.genre picture = Picture() # PIL does not allow for direct saving to bytes cover_image_file = io.BytesIO() cover_image.save(cover_image_file, format="png") picture.data = cover_image_file.getvalue() picture.type = 3 # Cover (front) picture.mime = "image/png" picture.width = cover_image.width picture.height = cover_image.height # PIL does not give depth, so we assert then hardcode assert cover_image.mode == "RGBA" picture.depth = 32 audio["metadata_block_picture"] = [ base64.b64encode(picture.write()).decode("ascii") ] audio.save(music_file)
def download_and_fix_ogg(ogg, audio_metadata, cover_art_file): global DRY_RUN if DRY_RUN: print "This is a dry run. So pretending to download the ogg..." return "/tmp/ogg" print "Now downloading the ogg in order to set the metadata in it..." if not LIVE and len(sys.argv) >= 6 and os.path.exists(sys.argv[5]): ogg_local_fn = sys.argv[5] print "(using presupplied file %s)" % ogg_local_fn else: f, metadata = client.get_file_and_metadata(ogg) ogg_local_fn = fetch_file(f, metadata) print "Successfully downloaded (to %s): now editing metadata..." % ogg_local_fn audio = OggVorbis(ogg_local_fn) for k in audio_metadata.keys(): audio[k] = audio_metadata[k] # add cover art im = Image.open(cover_art_file) w, h = im.size p = Picture() imdata = open(cover_art_file, 'rb').read() p.data = imdata p.type = 3 p.desc = '' p.mime = 'image/jpeg' p.width = w p.height = h p.depth = 24 dt = p.write() enc = base64.b64encode(dt).decode('ascii') audio['metadata_block_picture'] = [enc] audio.save() print "Successfully updated metadata." return ogg_local_fn
def rm_ogg_cover(self, episode): filename = episode.local_filename(create=False) if filename is None: return basename, extension = os.path.splitext(filename) if episode.file_type() != 'audio': return if extension.lower() != '.ogg': return try: ogg = OggVorbis(filename) found = False for key in ogg.keys(): if key.startswith('cover'): found = True ogg.pop(key) if found: logger.info('Removed cover art from OGG file: %s', filename) ogg.save() except Exception, e: logger.warn('Failed to remove OGG cover: %s', e, exc_info=True)
class _OggVorbisWrapper(_AbstractWrapper): TAG_MAP = { 'artwork': 'metadata_block_picture', 'artist': 'artist', 'album': 'album', 'title': 'title', 'genre': 'genre', } VALID_TAG_KEYS = ( 'artwork', 'artist', 'album', 'title', 'genre', ) def __init__(self, filename): _AbstractWrapper.__init__(self) self.audio = OggVorbis(filename) def __getattr__(self, attr): if attr in self.VALID_TAG_KEYS: if attr == 'artwork': try: raw_artwork_data = b64decode( self.audio['metadata_block_picture'][0]) picture = Picture(raw_artwork_data) return Artwork(picture.mime, picture.data) except KeyError: return None else: try: return self.audio[attr][0] except KeyError: return None raise TagError(self, attr) def __setattr__(self, attr, value): if attr in self.VALID_TAG_KEYS: if isinstance(value, Artwork): picture = Picture() picture.type = 3 picture.mime = value.mime picture.data = value.data self.audio['metadata_block_picture'] = [ b64encode(picture.write()).decode('utf-8') ] elif isinstance(value, str): self.audio[attr] = [value] else: raise TagValueError(value) else: object.__setattr__(self, attr, value) def __repr__(self): return repr(self.audio) def save(self): self.audio.save()
def remove_all(self): if self.backup is True: shutil.copy2(self.filename, self.output) self.filename = self.output mfile = OggVorbis(self.filename) mfile.delete() mfile.save()
def remove_all(self): if self.backup is True: shutil.copy2(self.filename, self.output) self.filename = self.output mfile = OggVorbis(self.filename) mfile.delete() mfile.save()
def ogg_tag(config): print("Tagging " + config.ogg_file) audio = OggVorbis(config.ogg_file) # Add the tags. for k in config.tags.keys(): audio[k] = config.tags[k] audio.save()
def add_tag(f, tag, value): if f.endswith('ogg'): audio = OggVorbis(f) elif f.endswith('flac'): audio = FLAC(f) audio[tag] = value # audio.pprint() audio.save()
def _set_id3_ogg(converted_file_path: str, song_object: SongObject): audio_file = OggVorbis(converted_file_path) audio_file = _embed_basic_metadata(audio_file, song_object, "ogg") audio_file = _embed_ogg_metadata(audio_file, song_object) audio_file = _embed_cover(audio_file, song_object, "ogg") audio_file.save()
def _set_id3_ogg(converted_file_path, song_obj): audio_file = OggVorbis(converted_file_path) audio_file = _embed_basic_metadata(audio_file, song_obj, "ogg") audio_file = _embed_ogg_metadata(audio_file, song_obj) audio_file = _embed_cover(audio_file, song_obj, "ogg") audio_file.save()
class Vorbis(object): tags = ['title', 'artist', 'album', 'genre', 'tracknumber'] def __init__(self, filename): self._comment = OggVorbis(filename) def write_random_tag(self, data): tag = random.choice(Vorbis.tags) self._comment[tag] = data self._comment.save()
def ogg_tag(config): print("Tagging " + config.ogg_file) audio = OggVorbis(config.ogg_file) # Add the tags. for k in config.tags.keys(): audio[k] = config.tags[k] audio.save()
def convert(self): ''' Convert wav -> ogg.''' if self.songwav == self.song: success = True dec = None else: success, dec = self.decode() if not success: warn('Decoding of "%s" failed.' % self.song) return if dec and self.decoder == 'mpg123': import mutagen try: info("additional option:" ) opts=['-R', str(mutagen.File(self.song).info.sample_rate)] info(str(opts)) except: opts=[] else: opts=[] if dec: enc = Popen(['oggenc', '-Q', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), '-'] + opts, stdin=dec.stdout) enc.communicate() dec.wait() if dec.returncode < 0: warn('Decoding of "%s" failed.' % self.song) return False elif enc.returncode < 0: warn('Encoding of "%s" failed.' % self.song) return False else: enc = call(['oggenc', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), self.songwav]) if enc != 0: warn('Encoding of "%s" failed.' % self.songwav) return False elif not self.conf.preserve_wav and self.song != self.songwav: os.remove(self.songwav) if self.tags != {}: try: # Add tags to the ogg file from mutagen.oggvorbis import OggVorbis myogg = OggVorbis(self.songogg) myogg.update(self.tags) myogg.save() except: warn('Could not save the tags') import traceback traceback.print_exc() return False elif self.songwav != self.song or 'cd-' in self.decoder: warn('No tags found...') if self.conf.delete_input: os.remove(self.song) return True
def saveLabel(self, file, label): '''read file and save label tag''' af = OggVorbis(file) logger.info("Tags BEFORE labelizer: " + str(af)) af['label'] = label af.save() logger.info("Tags AFTER labelizer: " + str(af))
def setValue(path, tag, value): format = os.path.splitext(path)[1] if(format == ".mp3"): audio = EasyID3(path) elif(format == ".ogg"): audio = OggVorbis(path) audio[tag] = value audio.save()
def test_save_split_setup_packet(self): fn = os.path.join("tests", "data", "multipage-setup.ogg") shutil.copy(fn, self.filename) audio = OggVorbis(self.filename) tags = audio.tags self.failUnless(tags) audio.save() self.audio = OggVorbis(self.filename) self.failUnlessEqual(self.audio.tags, tags)
def ogg_write_tags(self, path, tag_type, input_string): try: ogg_audio = OggVorbis(path) #Reading tags except: print ("No Ogg tag found or %r is not a valid OGG file") \ % (path.encode(sys.stdout.encoding or "utf-8", "replace"), ) return ogg_audio[tag_type] = input_string ogg_audio.save()
def saveLabel(self, file, label): '''read file and save label tag''' af = OggVorbis(file) logger.info( "Tags BEFORE labelizer: " + str(af) ) af['label'] = label af.save() logger.info( "Tags AFTER labelizer: " + str(af) )
def test_save_split_setup_packet(self): fn = os.path.join(DATA_DIR, "multipage-setup.ogg") shutil.copy(fn, self.filename) audio = OggVorbis(self.filename) tags = audio.tags self.failUnless(tags) audio.save() self.audio = OggVorbis(self.filename) self.failUnlessEqual(self.audio.tags, tags)
def ogg(): song = OggVorbis(file) write_keys(song) if exists(cover_img): pic = Picture() pic.data = open(cover_img, 'rb').read() pic.mime = 'image/jpeg' song["metadata_block_picture"] = [base64.b64encode(pic.write()).decode('ascii')] song.save()
def convert(self): ''' Convert wav -> ogg.''' info('Converting "%s" (using %s as decoder)...' % (self.song, self.decoder)) if self.songwav == self.song: success = True dec = None else: success, dec = self.decode() if not success: warn('Decoding of "%s" with %s failed.' % (self.song, self.decoder)) return if dec and self.decoder == 'mpg123': import mutagen opts=['-r', '-R', str(mutagen.File(self.song).info.sample_rate)] else: opts=[] if self.conf.quiet: opts.append("--quiet") if dec: enc = Popen(['oggenc', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), '-'] + opts, stdin=dec.stdout) enc.communicate() dec.wait() if dec.returncode < 0: warn('Decoding of "%s" with %s failed.' % (self.song, self.decoder)) return False elif enc.returncode < 0: warn('Encoding of "%s" failed.' % self.song) return False else: enc = call(['oggenc', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), self.songwav] + opts) if enc != 0: warn('Encoding of "%s" failed.' % self.songwav) return False elif not self.conf.preserve_wav and self.song != self.songwav: os.remove(self.songwav) if self.tags != {}: try: # Add tags to the ogg file from mutagen.oggvorbis import OggVorbis myogg = OggVorbis(self.songogg) myogg.update(self.tags) myogg.save() except: warn('Could not save the tags') import traceback traceback.print_exc() return False elif self.songwav != self.song or 'cd-' in self.decoder: warn('No tags found...') if self.conf.delete_input: os.remove(self.song) return True
def as_ogg(self, path, metadata, cached_albumart=None): logger.debug( 'Writing OGG Vorbis metadata to "{path}".'.format(path=path)) audiofile = OggVorbis(path) self._embed_basic_metadata(audiofile, metadata, "ogg") self._embed_ogg_metadata(audiofile, metadata) self._embed_mbp_picture(audiofile, metadata, cached_albumart, "ogg") audiofile.save()
def write_tags_to_ogg(path, tags): audio = OggVorbis(path) for dest, source in [['TITLE', 'TIT2'], ['ARTIST', 'TPE1'], ['ALBUM', 'TALB'], ['DATE', 'TDRC'], ['COPYRIGHT', 'TCOP'], ['LICENSE', 'WXXX:']]: audio[dest] = tags[source] audio['coverartmime'] = 'image/jpeg' audio['coverartdescription'] = 'Radiotux_ID3Tag.jpg' audio['coverart'] = get_ogg_coverart() audio.save()
def convert_to_ogg(song_path): """ Converts file at the provided path to ogg. WARNING: Care shall be taken by the caller of this function as it will explictly overwrite files that match the non-.ogg filename. """ try: # Setup new file name and path. filename, _ = os.path.splitext(os.path.basename(song_path)) ogg_filename = "{}.ogg".format(filename) ogg_path = os.path.join(os.path.dirname(song_path), ogg_filename) # Command will generate a new file with the same name, except .ogg # -vn disables video input conversion, -y overwrites if output already exists # -codec:a audio codec, -quality:a audio quality specifier result = subprocess.run( "ffmpeg -y -i {} -vn -codec:a libvorbis -quality:a 10 {}".format(song_path, ogg_path), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, ) # ffmpeg writes most of its normal output to stderr logging.info(result.stdout) logging.info(result.stderr) # ffmpeg doesn't know how to do covert art in ogg yet # See: https://trac.ffmpeg.org/ticket/4448 # Instead, we'll carry over the original covert art ourselves # using Vorbis Comment (https://wiki.xiph.org/VorbisComment) cover_art_picture = get_cover_art_from_song(song_path) ogg_file = OggVorbis(ogg_path) cover_art_data = cover_art_picture.write() encoded_data = base64.b64encode(cover_art_data) vcomment_value = encoded_data.decode("utf-8") ogg_file.tags["METADATA_BLOCK_PICTURE"] = [vcomment_value] # Delete extraneous cover art keys if "artwork" in ogg_file.tags.keys(): del ogg_file.tags["artwork"] ogg_file.save(ogg_path) return ogg_path except subprocess.CalledProcessError as err: logging.critical(err.stderr) logging.warning(err.stdout) raise
def write_tags_ogg(self): file = self.file_dir + os.sep + self.filename if os.path.exists(file): audio = OggVorbis(file) audio['TITLE'] = self.new_title.decode('utf8') audio['ARTIST'] = self.professor.decode('utf8') audio['ALBUM'] = self.title.decode('utf8') audio['DATE'] = self.date.decode('utf8') audio['GENRE'] = self.genre.decode('utf8') audio['SOURCE'] = self.title.decode('utf8') audio['ENCODER'] = self.encoder.decode('utf8') audio['COMMENT'] = self.comment.decode('utf8') audio.save()
def write_tags_ogg(self): file = self.file_dir + os.sep + self.filename if os.path.exists(file): audio = OggVorbis(file) audio['TITLE'] = self.new_title.decode('utf8') audio['ARTIST'] = self.professor.decode('utf8') audio['ALBUM'] = self.organization.decode('utf8') audio['DATE'] = self.date.decode('utf8') audio['GENRE'] = self.genre.decode('utf8') audio['SOURCE'] = self.organization.decode('utf8') audio['ENCODER'] = self.encoder.decode('utf8') audio['COMMENT'] = self.comment.decode('utf8') audio.save()
class _OggVorbisWrapper(_AbstractWrapper): TAG_MAP = { 'artwork': 'metadata_block_picture', 'artist': 'artist', 'album': 'album', 'title': 'title', 'genre': 'genre', } VALID_TAG_KEYS = ('artwork', 'artist', 'album', 'title', 'genre', ) def __init__(self, filename): _AbstractWrapper.__init__(self) self.audio = OggVorbis(filename) def __getattr__(self, attr): if attr in self.VALID_TAG_KEYS: if attr == 'artwork': try: raw_artwork_data = b64decode( self.audio['metadata_block_picture'][0]) picture = Picture(raw_artwork_data) return Artwork(picture.mime, picture.data) except KeyError: return None else: try: return self.audio[attr][0] except KeyError: return None raise TagError(self, attr) def __setattr__(self, attr, value): if attr in self.VALID_TAG_KEYS: if isinstance(value, Artwork): picture = Picture() picture.type = 3 picture.mime = value.mime picture.data = value.data self.audio['metadata_block_picture'] = [ b64encode(picture.write()).decode('utf-8') ] elif isinstance(value, str): self.audio[attr] = [value] else: raise TagValueError(value) else: object.__setattr__(self, attr, value) def __repr__(self): return repr(self.audio) def save(self): self.audio.save()
def SetVirtualData(self, item, col, data): print "Set Virtual Data" index=self.itemIndexMap[item] self.itemDataMap[index][col] = data if self._tabclose: print "Same row" return if self._origdata == str(self.itemDataMap[index]): print "Data did not change." return print "Data changed!" self._dirty = True #SortVirtList.SetVirtualData(self, item, col, data) #self.SetStringItem(self, item, col, data) artist = self.itemDataMap[index][0] title = self.itemDataMap[index][1] genre = self.itemDataMap[index][2] mtype = self.itemDataMap[index][3] path = self.itemDataMap[index][4] validexts = ['.mp3', '.ogg'] name, ext = os.path.splitext(path) if ext == ".cdg": candidates = glob.glob("%s.*" % name) for candidate in candidates: name, ext = os.path.splitext(candidate) if ext in validexts: path = candidate break if mtype in ('mp3', '.mp3'): m = MP3(path, ID3=EasyID3) try: m.add_tags(ID3=EasyID3) except mutagen.id3.error: print "Already has tag" elif mtype in ('ogg', 'ogg'): m = OggVorbis(path) else: print "Unrecognized type." return m['title'] = title m['artist'] = artist m['genre'] = genre m.save() print "Updated data."
def SetVirtualData(self, item, col, data): print "Set Virtual Data" index = self.itemIndexMap[item] self.itemDataMap[index][col] = data if self._tabclose: print "Same row" return if self._origdata == str(self.itemDataMap[index]): print "Data did not change." return print "Data changed!" self._dirty = True #SortVirtList.SetVirtualData(self, item, col, data) #self.SetStringItem(self, item, col, data) artist = self.itemDataMap[index][0] title = self.itemDataMap[index][1] genre = self.itemDataMap[index][2] mtype = self.itemDataMap[index][3] path = self.itemDataMap[index][4] validexts = ['.mp3', '.ogg'] name, ext = os.path.splitext(path) if ext == ".cdg": candidates = glob.glob("%s.*" % name) for candidate in candidates: name, ext = os.path.splitext(candidate) if ext in validexts: path = candidate break if mtype in ('mp3', '.mp3'): m = MP3(path, ID3=EasyID3) try: m.add_tags(ID3=EasyID3) except mutagen.id3.error: print "Already has tag" elif mtype in ('ogg', 'ogg'): m = OggVorbis(path) else: print "Unrecognized type." return m['title'] = title m['artist'] = artist m['genre'] = genre m.save() print "Updated data."
def __load_tags(self, tags, expected): m = OggVorbis(self.filename) for key, value in tags.iteritems(): m.tags[key] = value m.save() song = OggFile(self.filename) for key, value in expected.iteritems(): self.failUnlessEqual(song(key), value) if self.MAIN not in expected: self.failIf(self.MAIN in song) if self.SINGLE not in expected: self.failIf(self.SINGLE in song) if self.FALLBACK not in expected: self.failIf(self.FALLBACK in song)
def __load_tags(self, tags, expected): m = OggVorbis(self.filename) for key, value in iteritems(tags): m.tags[key] = value m.save() song = OggFile(self.filename) for key, value in iteritems(expected): self.failUnlessEqual(song(key), value) if self.MAIN not in expected: self.failIf(self.MAIN in song) if self.SINGLE not in expected: self.failIf(self.SINGLE in song) if self.FALLBACK not in expected: self.failIf(self.FALLBACK in song)
def test_save_grown_split_setup_packet_reference(self): if ogg is None: return fn = os.path.join("tests", "data", "multipage-setup.ogg") shutil.copy(fn, self.filename) audio = OggVorbis(self.filename) audio["foobar"] = ["quux" * 50000] tags = audio.tags self.failUnless(tags) audio.save() self.audio = OggVorbis(self.filename) self.failUnlessEqual(self.audio.tags, tags) vfc = ogg.vorbis.VorbisFile(self.filename).comment() for key in self.audio: self.failUnlessEqual(vfc[key], self.audio[key]) self.ogg_reference(self.filename)
def test_save_grown_split_setup_packet_reference(self): if ogg is None: return fn = os.path.join("tests", "data", "multipage-setup.ogg") shutil.copy(fn, self.filename) audio = OggVorbis(self.filename) audio["foobar"] = ["quux" * 50000] tags = audio.tags self.failUnless(tags) audio.save() self.audio = OggVorbis(self.filename) self.failUnlessEqual(self.audio.tags, tags) vfc = ogg.vorbis.VorbisFile(self.filename).comment() for key in self.audio: self.failUnlessEqual(vfc[key], self.audio[key]) self.ogg_reference(self.filename)
def write_tags_to_ogg(path, tags): audio = OggVorbis(path) for dest, source in [['TITLE', 'title'], ['COMPOSER', 'composer'], ['ALBUM', 'album'], ['DATE', 'date'], ['ARTIST', 'artist'], ['GENRE', 'genre'], ['ALBUMARTIST', 'album-artist'], ['TRACKNUMBER', 'track'], ['TRACKTOTAL', 'number-of-tracks'], ['DISCNUMBER', 'disc'], ['COMMENT', 'comment']]: if source in tags: audio[dest] = tags[source] if 'cover' in tags: audio['coverartmime'] = 'image/jpeg' audio['coverartdescription'] = 'Cover' audio['coverarttype'] = '3' audio['coverart'] = get_ogg_coverart(tags['cover']) audio.save()
def write_tags_to_ogg(path, tags): audio = OggVorbis(path) for dest, source in [['TITLE', 'title'], ['COMPOSER', 'composer'], ['ALBUM', 'album'], ['DATE', 'date'], ['ARTIST', 'artist'], ['GENRE', 'genre'], ['ALBUMARTIST', 'album-artist'], ['TRACKNUMBER', 'track'], ['TRACKTOTAL', 'number-of-tracks'], ['DISCNUMBER', 'disc'], ['COMMENT', 'comment']]: if source in tags: audio[dest] = tags[source] if 'cover' in tags: audio['coverartmime'] = 'image/jpeg' audio['coverartdescription'] = 'Cover' audio['coverarttype'] = '3' audio['coverart'] = get_ogg_coverart(tags['cover']) audio.save()
def add_ogg(self, path='', filename='file.ogg', artist='', album='', title='', tracknum=None, year=None, group='', conductor='', composer='', basefile='silence.ogg', apply_tags=True): """ Adds a new ogg with the given parameters to our library. Pass in ``False`` for ``apply_tags`` to only use whatever tags happen to be present in the source basefile. """ full_filename = self.add_file(basefile, filename, path=path) # Finish here if we've been told to. if not apply_tags: return # Apply the tags as specified tags = OggVorbis(full_filename) tags['ARTIST'] = artist tags['ALBUM'] = album tags['TITLE'] = title if group != '': tags['ENSEMBLE'] = group if conductor != '': tags['CONDUCTOR'] = conductor if composer != '': tags['COMPOSER'] = composer if tracknum is not None: tags['TRACKNUMBER'] = str(tracknum) if year is not None: tags['DATE'] = str(year) # Save to our filename tags.save()
def write_tags(filename, tags): try: if '.mp3' in filename: f = APEv2(filename) elif '.ogg' in filename: f = OggVorbis(filename) elif '.flac' in filename: f = FLAC(filename) for t in TAGS: f[t] = unicode(tags[t]) f.save() except: pass # again for mp3 with tags that are worse if '.mp3' in filename: f = EasyID3(filename) for t in TAGS: f[t] = [unicode(tags[t])] f.save()
def updateCoverOgg(lossyFileName, artworkFileName): # # Embed album art into transcoded file: OGG # import base64 from mutagen.oggvorbis import OggVorbis from mutagen.flac import Picture import PIL.Image import tempfile from shutil import copyfile # Use copyfile b/c this will *not* copy rights (which is error prone on gvfs/samba) log('- embedding album art ' + artworkFileName + ' to ' + lossyFileName) # Copy lossy file to a local location; to prevent (save) errors in a samba environment tempLossyFile = tempfile.gettempdir() + '/' + 'temp.ogg' copyfile(lossyFileName, tempLossyFile) # Embed the image o = OggVorbis(tempLossyFile) im = PIL.Image.open(artworkFileName) w, h = im.size p = Picture() imdata = open(artworkFileName, 'rb').read() p.data = imdata p.type = 3 p.desc = '' p.mime = 'image/jpeg' p.width = w p.height = h p.depth = 24 dt = p.write() enc = base64.b64encode(dt).decode('ascii') o['metadata_block_picture'] = [enc] o.save() # Now we are ready; copy the file to the desired output directory copyfile(tempLossyFile, lossyFileName) os.remove(tempLossyFile) # Remove the temporary file(s) return
def write_metadata(self): if MUTAGEN: if "MP3" in self.__audio_codec: # Prima scrive i tag v1 e v2, poi rimuove i v2 self.write_ID3v2() self.remove_ID3v2() elif "ogg" in self.__gst_type: tags = OggVorbis(self.__filepath) tags["tracknumber"] = unicode(int( self.get_tag("track_number"))) tags["title"] = unicode(self.get_tag("title")) tags["artist"] = unicode(self.get_tag("artist")) tags["album"] = unicode(self.get_tag("album")) tags["date"] = unicode(self.get_tag("year")) tags["genre"] = unicode(self.get_tag("genre")) tags["comment"] = unicode(self.get_tag("comment")) tags["albumartist"] = unicode(self.get_tag("album_artist")) tags["composer"] = unicode(self.get_tag("composer")) tags["discnumber"] = unicode(self.get_tag("disc_number")) # TODO: Come salvare la copertina in un file Vorbis??? # Questo non funziona: #tags["coverart"] = [self.get_tag("cover")] tags.save(self.__filepath) elif "flac" in self.__gst_type: tags = FLAC(self.__filepath) tags["tracknumber"] = unicode(int( self.get_tag("track_number"))) tags["title"] = unicode(self.get_tag("title")) tags["artist"] = unicode(self.get_tag("artist")) tags["album"] = unicode(self.get_tag("album")) tags["date"] = unicode(self.get_tag("year")) tags["genre"] = unicode(self.get_tag("genre")) tags["comment"] = unicode(self.get_tag("comment")) tags["albumartist"] = unicode(self.get_tag("album_artist")) tags["composer"] = unicode(self.get_tag("composer")) tags["discnumber"] = unicode(self.get_tag("disc_number")) # TODO: Come salvare la copertina in un file FLAC??? # Questo non funziona: #tags.add_picture(self.get_tag("cover")) tags.save(self.__filepath)
def write_metadata(self): if MUTAGEN: if "mpeg" in self.__mime_type and "MP3" in self.__audio_codec: # Prima scrive i tag v1 e v2, poi rimuove i v2 self.write_ID3v2() self.remove_ID3v2() elif "ogg" in self.__mime_type: tags = OggVorbis(self.__filepath) tags["tracknumber"] = unicode(int(self.get_tag("track_number"))) tags["title"] = unicode(self.get_tag("title")) tags["artist"] = unicode(self.get_tag("artist")) tags["album"] = unicode(self.get_tag("album")) tags["date"] = unicode(self.get_tag("year")) tags["genre"] = unicode(self.get_tag("genre")) tags["comment"] = unicode(self.get_tag("comment")) tags["albumartist"] = unicode(self.get_tag("album_artist")) tags["composer"] = unicode(self.get_tag("composer")) tags["discnumber"] = unicode(self.get_tag("disc_number")) # TODO: Come salvare la copertina in un file Vorbis??? # Questo non funziona: # tags["coverart"] = [self.get_tag("cover")] tags.save(self.__filepath) elif "flac" in self.__mime_type: tags = FLAC(self.__filepath) tags["tracknumber"] = unicode(int(self.get_tag("track_number"))) tags["title"] = unicode(self.get_tag("title")) tags["artist"] = unicode(self.get_tag("artist")) tags["album"] = unicode(self.get_tag("album")) tags["date"] = unicode(self.get_tag("year")) tags["genre"] = unicode(self.get_tag("genre")) tags["comment"] = unicode(self.get_tag("comment")) tags["albumartist"] = unicode(self.get_tag("album_artist")) tags["composer"] = unicode(self.get_tag("composer")) tags["discnumber"] = unicode(self.get_tag("disc_number")) # TODO: Come salvare la copertina in un file FLAC??? # Questo non funziona: # tags.add_picture(self.get_tag("cover")) tags.save(self.__filepath)
def set_genre(self, genre_list): dialog = gtk.Dialog("Setting genres...", self.window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) dialog.connect("response", self.dialog_response) progress_bar = gtk.ProgressBar() progress_bar.set_size_request(300, -1) label = gtk.Label(", ".join(genre_list)) label.set_line_wrap(True) label.set_padding(-1, 5) dialog.get_content_area().pack_start(label) dialog.get_content_area().pack_start(progress_bar) dialog.get_content_area().set_spacing(5) dialog.show_all() self.status_bar.push(self.context_id, "Setting genres...") file_list = [] for f in os.listdir(self.search_list[self.count][0]): if f.lower().endswith(".ogg") or f.lower().endswith(".flac"): file_list.append(f) file_list.sort() count = 0 for f in file_list: if f.lower().endswith(".ogg") or f.lower().endswith(".flac"): if self.close_dialog: self.close_dialog = False break count += 1 progress_bar.set_text(f) progress_bar.set_fraction(float(count) / len(file_list)) if f.lower().endswith(".ogg"): audio = OggVorbis(os.path.join(self.search_list[self.count][0], f)) if f.lower().endswith(".flac"): audio = FLAC(os.path.join(self.search_list[self.count][0], f)) audio['genre'] = genre_list audio.save() yield True self.status_bar.pop(self.context_id) dialog.destroy() if not self.search_on_list(): gtk.main_quit() yield False
def write_ogg_meta(ogg_file_path, cover_bytes, dimensions, year, artist, album, title): ogg_file = OggVorbis(ogg_file_path) picture = Picture() picture.data = cover_bytes picture.type = 3 picture.mime = u"image/jpeg" picture.width = dimensions[0] picture.height = dimensions[1] picture.depth = 24 picture_data = picture.write() encoded_data = b64encode(picture_data) comment = encoded_data.decode("ascii") ogg_file["metadata_block_picture"] = [comment] ogg_file["date"] = [year] ogg_file["artist"] = [artist] ogg_file["album"] = [album] ogg_file["title"] = [title] ogg_file.save()
def write(): if request.method == 'POST': loopstart_val = request.form['loopstart'] looplength_val = request.form['looplength'] print('LOOPSTART:', loopstart_val) print('LOOPLENGTH:', looplength_val) myfile = request.files['myfile'] tmp = tempfile.NamedTemporaryFile() print(tmp.name) with open(tmp.name, "wb") as f: f.write(myfile.read()) f.close() ogg = OggVorbis(tmp.name) ogg['LOOPSTART'] = loopstart_val ogg['LOOPLENGTH'] = looplength_val ogg.save() print(ogg) filename = 'loop.ogg' return send_file(tmp.name, mimetype='audio/ogg', as_attachment=True, attachment_filename=filename)
def clear_tags(filename): try: if '.mp3' in filename: f = APEv2(filename) elif '.ogg' in filename: f = OggVorbis(filename) elif '.flac' in filename: f = FLAC(filename) for k in f.keys(): f[k] = u'' f.save() except: pass # again for mp3 with tags that are worse if '.mp3' in filename: try: f = EasyID3(filename) for k in f.keys(): f[k] = [u''] f.save() except mutagen.id3.ID3NoHeaderError: pass
def ogg_coverart(config): print("Adding " + config.coverart_mime + " cover art to " + config.ogg_file) coverart = config.coverart imgdata = open(coverart,'rb').read() im = Image.open(coverart) w,h = im.size p = Picture() p.data = imgdata p.type = 3 p.desc = 'Cover' p.mime = config.coverart_mime p.width = w p.height = h p.depth = 24 dt=p.write() enc=base64.b64encode(dt).decode('ascii') audio = OggVorbis(config.ogg_file) audio['metadata_block_picture']=[enc] audio.save()
def ogg_coverart(config): print("Adding " + config.coverart_mime + " cover art to " + config.ogg_file) coverart = config.coverart imgdata = open(coverart,'rb').read() im = Image.open(coverart) w,h = im.size p = Picture() p.data = imgdata p.type = 3 p.desc = 'Cover' p.mime = config.coverart_mime p.width = w p.height = h p.depth = 24 dt=p.write() enc=base64.b64encode(dt).decode('ascii') audio = OggVorbis(config.ogg_file) audio['metadata_block_picture']=[enc] audio.save()
def put(self, addr, flag_id, flag): sock = self.create_socket(addr, SERVICE_PORT) song = self.pick_song() temp_file = '%s%s' % (TMP_DIR, flag_id) shutil.copyfile(song, temp_file) ogg_file = OggVorbis(temp_file) ogg_file[FLAG_TAG_NAME] = flag ogg_file.save() try: with open(temp_file, 'rb') as f: song_data = f.read() uuid = self.put_song(sock, song_data) if not uuid: return False print(uuid) return str(uuid) finally: os.remove(temp_file)
def tagOGG(conf, mediafile): # https://mutagen.readthedocs.io/en/latest/user/vcomment.html # https://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE # https://xiph.org/flac/format.html#metadata_block_picture # https://github.com/quodlibet/mutagen/issues/200 img_stream, img_meta = imgConv(conf['tags']['img']) picture = Picture() picture.data = img_stream picture.type = 3 picture.description = '{0} ({1})'.format(conf['tags']['artist'], conf['tags']['comment']) picture.mime = img_meta['mime'] picture.width = img_meta['width'] picture.height = img_meta['height'] picture.depth = img_meta['depth'] picture.desc = '{0} ({1})'.format(conf['tags']['artist'], conf['tags']['comment']) containered_data = picture.write() encoded_data = base64.b64encode(containered_data) img_tag = encoded_data.decode('ascii') print('{0}: Now adding tags to {1}...'.format(datetime.datetime.now(), mediafile)) tag = OggVorbis(mediafile) tag['TITLE'] = conf['episode']['pretty_title'] tag['ARTIST'] = conf['tags']['artist'] tag['ALBUM'] = conf['tags']['album'] tag['DATE'] = '{0}.{1}.{2}'.format(conf['tags']['year'], conf['episode']['month'], conf['episode']['day']) tag['TRACKNUMBER'] = conf['tags']['track'] tag['GENRE'] = conf['tags']['genre'] tag['DESCRIPTION'] = conf['tags']['comment'] tag['COPYRIGHT'] = conf['tags']['copyright'] tag['CONTACT'] = conf['tags']['url'] tag['ENCODED-BY'] = conf['tags']['encoded'] tag['ENCODER'] = conf['tags']['encoded'] tag['METADATA_BLOCK_PICTURE'] = [img_tag] tag.save()
def rm_ogg_cover(episode): filename = episode.local_filename(create=False, check_only=True) if filename is None: return (basename, extension) = os.path.splitext(filename) if episode.file_type() == "audio" and extension.lower().endswith("ogg"): logger.info(u"trying to remove cover from %s" % filename) found = False try: ogg = OggVorbis(filename) for key in ogg.keys(): if key.startswith("cover"): found = True ogg.pop(key) if found: logger.info(u"removed cover from the ogg file successfully") ogg.save() else: logger.info(u"there was no cover to remove in the ogg file") except: None
def __copyandtag(cls, target): '''__copyandtag''' src = cls.__inpath("normalized", target['in']) out = cls.__assembleoggname(target['title'], target['artists']) dst = cls.__inpath("pool", out) if not os.path.exists(src): return if not os.path.exists(dst): try: copyfile(src, dst) except Exception: logging.info("Failed copying " + src + " to " + dst) return try: ogg = OggVorbis(dst) if ogg.get("title", None) is None or \ ogg.get("artist", None) is None or \ ogg["title"] != target["title"] or \ ogg["artist"] != target["artists"]: ogg["title"] = target["title"] ogg["artist"] = target["artists"] ogg.save(dst) except Exception: logging.info("Failed tagging " + dst)
def main(self): if len(sys.argv) < 2: print "Usage:\n\t%s <archive|folder>" % sys.argv[0] sys.exit() s = os.path.abspath(sys.argv[1]) try: shutil.rmtree(".brainwash-work") except: pass try: os.mkdir(".brainwash-work") except: pass os.chdir(".brainwash-work") if os.path.isdir(s): print "Creating working copy..." shutil.copytree(s, "work") else: subprocess.call(["unp", s]) folders = find_music_folders(".") for folder in folders: music_files = myglob(folder[0], "*" + folder[1]) if len(music_files) < 2: cue_files = myglob(folder[0], "*.cue") if len(cue_files) < 1: # ask for mbid # need to write cuesheet generation code!!! # print "There is no cue file. To generate one I need the Release MBID." # mbid = raw_input('Enter MBID: ').strip() print "There is no cuesheet. please generate one yourself :P" continue else: cue_file = cue_files[0] wav_file = self.decode_to_wav(music_files[0]) subprocess.call(["bchunk", "-w", wav_file, cue_file, folder[0] + "/tmp-brainwash-"]) wav_files = myglob(folder[0], "tmp-brainwash-*.wav") music_files = [] for wav_file in wav_files: music_files += [self.encode_to_flac(wav_file)] folder[1] = "flac" # encode into a nice format if folder[1] not in formats_final: wav_files = [] if folder[1] == ".wav": wav_files = music_files[:] else: for music_file in music_files: wav_files += [self.decode_to_wav(music_file)] music_files = [] for wav_file in wav_files: music_files += [self.encode_to_flac(wav_file)] folder[1] = "flac" # take over the tags? print "Found: " + folder[0] try: mbid = file(folder[0] + "/.mbid").read().strip() print "Using existing mbid" except: release = self.guess_release(folder[0], music_files) if release is None: # ask for mbid print "Could not guess!" mbid = raw_input("Enter MBID: ").strip() else: # ask if guess is correct tmp_mbid = release.id.split("/")[-1:][0] print "Selected %s" % tmp_mbid answer = raw_input("Correct? [Y|n]").strip() if answer == "" or answer.lower() == "y": mbid = tmp_mbid else: print str(answer.lower()) mbid = raw_input("Enter MBID: ").strip() file(join(folder[0], ".mbid"), "w").write(str(mbid)) service = get_service() q = Query(service) i = ReleaseIncludes(artist=True, tracks=True, urlRelations=True, releaseEvents=True, discs=True) try: release = q.getReleaseById(mbid, i) except WebServiceError, e: print "Error: ", e continue dst = self.config["destination_dir"] year = 9999 for event in release.releaseEvents: year = min(year, int(event.date[:4])) if year == 9999: year = int(raw_input("Enter Release Year: ").strip()) release_title = self.clean_filename(release.title) if release.TYPE_SOUNDTRACK in release.getTypes(): dst += "/_soundtracks/(%s) %s/" % (year, release_title) elif not release.artist: dst += "/_va/(%s) %s/" % (year, release_title) else: sort_char = release.artist.sortName[:1].lower() sort_char = unicodedata.normalize("NFKD", sort_char).encode("ASCII", "ignore") dst += "/%s/%s/(%s) %s/" % ( sort_char, self.clean_filename(release.artist.sortName), year, release_title, ) try: os.makedirs(dst) except: raw_input("Failed creating %s! Press Anykey" % dst) file(join(dst, ".mbid"), "w").write(str(mbid)) for music_file in music_files: # fix permissions for broken archives os.chmod(music_file, (stat.S_IRUSR + stat.S_IWUSR + stat.S_IRGRP + stat.S_IROTH)) track_number = filename_track_number(music_file) track = release.tracks[track_number - 1] if folder[1] == ".mp3": # meta_file = MP3(music_file, ID3=EasyID3) meta_file = EasyID3() elif folder[1] == ".ogg": meta_file = OggVorbis(music_file) elif folder[1] == "flac": meta_file = FLAC(music_file) else: print "Uh oh, no meta-file for " + music_file # if not meta_file.tags: # meta_file.add_tags() artist = track.artist.name if track.artist else release.artist.name meta_file["title"] = track.title meta_file["artist"] = artist meta_file["album"] = release.title meta_file["tracknumber"] = str(track_number) + "/" + str(len(music_files)) meta_file["genre"] = self.get_lastfm_tags(meta_file["artist"][0]) meta_file.save(music_file) file_dst = dst + self.clean_filename( "%02d-%s - %s%s%s" % (track_number, artist, track.title, "." if folder[1] == "flac" else "", folder[1]) ) os.rename(music_file, file_dst) # cover art image_files = myglob(folder[0], "*.[jpg|png]") if len(image_files) > 1: for image_file in image_files: os.rename(image_file, dst + basename(image_file)) elif len(image_files) == 1: os.rename(image_files[0], dst + "cover." + image_files[0][-3:]) else: # try downlaod from amazon if release.asin: urllib.urlretrieve( "http://images.amazon.com/images/P/" + release.asin + ".01.LZZZZZZZ.jpg", dst + "cover.jpg" ) if os.path.getsize(dst + "cover.jpg") < 1000L: os.remove(dst + "cover.jpg") print "Done: " + dst
class VorbisFile: def __init__(self, fn): self.config = config if fn is not None: self.SetFile(fn) def SetFile(self, fn): self.fn = fn self.filename = os.path.basename(self.fn) self.af = OggVorbis(self.fn) def read_comments(self): dic = {'title' : '', 'artist' : '', 'album' : '', 'license' : '', 'label' : '', 'comment' : '' } for tag in self.af.keys(): tag = tag.lower() val = self.af.get(tag).pop(0) if val <> '': dic[tag] = val return dic def write_comments(self, metadata, userInfo, cache=1, removeSpool=0): ''' Cache the file (copy it to a tmp dir) and write the tags there. ''' logger.debug99("called VorbisFile.write_comments()") # now write the comments to file (self.af) dic = {} for tag in metadata: tag = tag.lower() val = metadata[tag] # build up metadata object together with audio file object if val != '': self.af[tag] = val else: logger.debug3("Not writing tag: %s (was left empty)" % tag) self.af.save() logger.debug3( "in VorbisFile.write_comments() Done! Wrote tags successfully to %s!" % self.fn ) # FIXME : el ImportOGG en modo 'edit' es para que re-lea tags y actualice la DB # pero no deberia ir dentro de la clase VorbisFile ''' if not cache: logger.debug2("Should re-import/update: %s" % self.fn) ImportOGG(self, self.fn, userInfo, 'edit') ''' return self.fn def getFilepath(self): return self.fn def getFilename(self): return self.filename def getTag(self, tag): if self.af.has_key(tag) and self.af[tag] is not '': return self.af.get(tag).pop(0) else: return '' def getLength(self): return self.af.info.length def getBitrate(self): return self.af.info.bitrate def getSamplerate(self): return self.af.info.sample_rate def getInfo(self): '''Available info (for OGG/Vorbis) is: channels, bitrate, serial, sample_rate, length''' return self.af.info def listTags(self): return self.af.keys() def getSize(self): return os.stat(self.fn).st_size