Ejemplo n.º 1
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        with translate_errors():
            audio = self.MutagenType(self["~filename"])

        try:
            data = image.read()
        except EnvironmentError as e:
            raise AudioFileError(e)

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        audio.pop("coverart", None)
        audio.pop("coverartmime", None)
        audio["metadata_block_picture"] = base64.b64encode(
            pic.write()).decode("ascii")

        with translate_errors():
            audio.save()

        self.has_images = True
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        with translate_errors():
            tag = FLAC(self["~filename"])

        try:
            data = image.read()
        except EnvironmentError as e:
            raise AudioFileError(e)

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        tag.add_picture(pic)

        with translate_errors():
            tag.save()

        # clear vcomment tags
        super(FLACFile, self).clear_images()

        self.has_images = True
Ejemplo n.º 4
0
def get_cover_art_from_song(song_path):
    """
    Takes in path pointing to an audio file of arbitrary format and finds the cover
    art, if any, and returns it as a File.
    """
    file_type = mutagen.File(song_path)

    pic = None

    # TODO: Look to add support for more tag formats.
    if isinstance(file_type.tags, mutagen.id3.ID3):
        apic_frames = [file_type.tags[t] for t in file_type.tags.keys() if t.startswith("APIC")]

        cover_frame = apic_frames[0]
        if len(apic_frames) > 1:
            cover_frame = [f for f in apic_frames if f.type == mutagen.id3.PictureType.COVER_FRONT][0]

        downscaled_data = __downscale_cover_art(cover_frame.data)

        pic = Picture()
        pic.data = downscaled_data
        pic.type = cover_frame.type
        pic.mime = cover_frame.mime
        pic.width = THUMBNAIL_DIMENSION
        pic.height = THUMBNAIL_DIMENSION
        pic.depth = 16  # color depth

    return pic
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        with translate_errors():
            tag = FLAC(self["~filename"])

        try:
            data = image.read()
        except EnvironmentError as e:
            raise AudioFileError(e)

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        tag.add_picture(pic)

        with translate_errors():
            tag.save()

        # clear vcomment tags
        super().clear_images()

        self.has_images = True
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
 def _addCoverToFile(self, album):
     if self.fileType == 'FLAC':
         if not self.hasCover or (
                 self.audioTag.pictures[0].height != 1000 and self.audioTag.pictures[0].width != 1000):
             if self.hasCover:
                 self.audioTag.clear_pictures()
             # Build the file path by concatenating folder in the file path
             path = ''
             for folder in self.pathList:
                 path += '{}/'.format(folder)
             path += album.coverName
             with open(path, "rb") as img:
                 data = img.read()
             # Open physical image
             im = PIL.Image.open(path)
             width, height = im.size
             # Create picture and set its internals
             picture = Picture()
             picture.data = data
             picture.type = 3  # COVER_FRONT
             picture.desc = path.rsplit('/', 1)[-1]  # Add picture name as a description
             picture.mime = mimetypes.guess_type(path)[0]
             picture.width = width
             picture.height = height
             picture.depth = mode_to_bpp[im.mode]
             # Save into file's audio tag
             self.audioTag.add_picture(picture)
             self.audioTag.save()
     else:
         # TODO for APIC frame
         pass
Ejemplo n.º 9
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        with translate_errors():
            audio = self.MutagenType(self["~filename"])

        try:
            data = image.read()
        except EnvironmentError as e:
            raise AudioFileError(e)

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        audio.pop("coverart", None)
        audio.pop("coverartmime", None)
        audio["metadata_block_picture"] = base64.b64encode(
            pic.write()).decode("ascii")

        with translate_errors():
            audio.save()

        self.has_images = True
Ejemplo n.º 10
0
def download_flac(track: tidalapi.models.Track, file_path, album=None):
    if album is None:
        album = track.album
    url = session.get_media_url(track_id=track.id)

    r = requests.get(url, stream=True)
    r.raw.decode_content = True
    data = BytesIO()
    shutil.copyfileobj(r.raw, data)
    data.seek(0)
    audio = FLAC(data)

    # general metatags
    audio['artist'] = track.artist.name
    audio[
        'title'] = f'{track.name}{f" ({track.version})" if track.version else ""}'

    # album related metatags
    audio['albumartist'] = album.artist.name
    audio[
        'album'] = f'{album.name}{f" ({album.version})" if album.version else ""}'
    audio['date'] = str(album.year)

    # track/disc position metatags
    audio['discnumber'] = str(track.volumeNumber)
    audio['disctotal'] = str(album.numberOfVolumes)
    audio['tracknumber'] = str(track.trackNumber)
    audio['tracktotal'] = str(album.numberOfTracks)

    # Tidal sometimes returns null for track copyright
    if hasattr(track, 'copyright') and track.copyright:
        audio['copyright'] = track.copyright
    elif hasattr(album, 'copyright') and album.copyright:
        audio['copyright'] = album.copyright

    # identifiers for later use in own music libraries
    if hasattr(track, 'isrc') and track.isrc:
        audio['isrc'] = track.isrc
    if hasattr(album, 'upc') and album.upc:
        audio['upc'] = album.upc

    pic = Picture()
    pic.type = id3.PictureType.COVER_FRONT
    pic.width = 640
    pic.height = 640
    pic.mime = 'image/jpeg'
    r = requests.get(track.album.image, stream=True)
    r.raw.decode_content = True
    pic.data = r.raw.read()

    audio.add_picture(pic)

    data.seek(0)
    audio.save(data)
    with open(file_path, "wb") as f:
        data.seek(0)
        shutil.copyfileobj(data, f)
Ejemplo n.º 11
0
    async def add(self):
        loop = asyncio.get_event_loop()
        await loop.run_in_executor(
            None, super().__init__, f"{self.trackInfo['trackId']}.ogg"
        )
        async with httpx.AsyncClient() as client:
            albumArtResponse = await client.get(self.trackInfo["albumArtHigh"])
        picture = Picture()
        picture.data = albumArtResponse.content
        """
        Initially Vorbis comments didn't contain album arts, now they can keep album arts according to FLAC's specifications, thus using Picture class from flac.
        mutagen example uses picture.type = 17 here: https://mutagen.readthedocs.io/en/latest/user/vcomment.html.
        Keeping it's value as 17 makes Android's MediaMetadataRetriever to not detect the album art.
        What on earth is "A bright coloured fish" ?
        Reference: https://xiph.org/flac/format.html#metadata_block_picture.
        """
        picture.type = 3
        picture.desc = "Cover (front)"
        picture.mime = "image/jpeg"
        picture.width = 544
        picture.height = 544
        encoded_data = base64.b64encode(picture.write())
        vcomment_value = encoded_data.decode("ascii")
        """
        Sets album art.
        """
        self["metadata_block_picture"] = [vcomment_value]
        """
        In Vorbis comments, a key e.g. "artists" can have more than one value.
        In mutagen implementation, that's why we give values in a list.
        Reference: https://gitlab.gnome.org/GNOME/rhythmbox/-/issues/16
        """
        self["title"] = [self.trackInfo["trackName"]]
        self["album"] = [self.trackInfo["albumName"]]
        """
        This is where we can simply provide simply a list of artists, as written above (for having mutiple value for the same key).     
        But, by that MediaMetadataRetriever is just shows first artist :-(. So, I'm just joining all artists with "/" separator. (Though, this is incorrect according to official reference).
        """
        self["artist"] = ["/".join(self.trackInfo["trackArtistNames"])]
        """
        No reference of this comment at http://age.hobba.nl/audio/mirroredpages/ogg-tagging.html, still using because a mutagen example uses it. Thus, unable to read.
        """
        self["albumartist"] = [self.trackInfo["albumArtistName"]]
        """
        This needs a fix. Vorbis comment keeps date instead of year & MediaMetadataRetriever is unable to read this.
        Fix if you get to know something...
        """
        self["date"] = [str(self.trackInfo["year"])]
        self["tracknumber"] = [f"{self.trackInfo['trackNumber']}/{self.trackInfo['albumLength']}"]
        """
        Again, no official reference of this one at http://age.hobba.nl/audio/mirroredpages/ogg-tagging.html. Thus, unable to read.
        """
        self["tracktotal"] = [str(self.trackInfo["albumLength"])]
        loop = asyncio.get_event_loop()
        await loop.run_in_executor(None, self.save)

        """
Ejemplo n.º 12
0
 def _picture_f2m(flackup_picture):
     """Create a Mutagen Picture from a Flackup Picture."""
     picture = MutagenPicture()
     picture.type = flackup_picture.type
     picture.mime = flackup_picture.mime
     picture.width = flackup_picture.width
     picture.height = flackup_picture.height
     picture.depth = flackup_picture.depth
     picture.data = flackup_picture.data
     return picture
Ejemplo n.º 13
0
    def tag_flac(self, file_path, track_info, album_info, album_art_path=None):
        tagger = FLAC(file_path)

        self._meta_tag(tagger, track_info, album_info, 'flac')
        if self.fmtopts['embed_album_art'] and album_art_path is not None:
            pic = Picture()
            with open(album_art_path, 'rb') as f:
                pic.data = f.read()

            pic.type = PictureType.COVER_FRONT
            pic.mime = u"image/jpeg"
            try:
                img = cv2.imread(album_art_path)
                pic.height, pic.width, channels = img.shape
            except Exception as e:
                pic.width = 1280
                pic.height = 1280
            pic.depth = 24
            tagger.add_picture(pic)
        tagger.save(file_path)
Ejemplo n.º 14
0
    def buttonAddPictureClicked(self):
        self.logger("buttonAddPictureClicked")
        filename = QtGui.QFileDialog.getOpenFileName(self, "Image File")
        reader = QtGui.QImageReader(filename)
        rformat = reader.format()
        image = reader.read()
        self.coverArtPixmap = QtGui.QPixmap.fromImage(image)
        self.logger(
            'width = %d, height = %d' %
            (self.coverArtPixmap.width(), self.coverArtPixmap.height()))
        self.labelPicture.setPixmap(
            self.coverArtPixmap.scaled(self.labelPicture.width(),
                                       self.labelPicture.height(),
                                       QtCore.Qt.KeepAspectRatio))

        pic = Picture()

        data = Qt.QByteArray()
        buf = Qt.QBuffer(data)

        pic.type = 3  # APICType.COVER_FRONT
        self.logger('format: %s' % rformat)
        if rformat == 'png':
            pic.mime = 'image/png'
            image.save(buf, 'PNG')
        elif rformat == 'jpg' or rformat == 'jpeg':
            pic.mime = 'image/jpeg'
            image.save(buf, 'JPG')
        else:
            pic.mime = 'image/unknown'
        self.logger("format: %s" % pic.mime)
        pic.data = data.data()
        pic.width = self.coverArtPixmap.width()
        pic.height = self.coverArtPixmap.height()
        pic.depth = self.coverArtPixmap.depth()
        pic.colors = image.colorCount()
        if len(self.audio.pictures) > 0:
            ret = QtGui.QMessageBox.warning(
                self, "FLAC Tagger",
                "This FLAC file already contains one or more pictures.\n"
                "Do you want to replace them?",
                QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel,
                QtGui.QMessageBox.Cancel)
            if ret == QtGui.QMessageBox.Yes:
                self.audio.clear_pictures()
                self.audio.addPicture(pic)
            else:
                # make sure the old picture is displayed again
                self.displayPictures()
        else:
            self.audio.addPicture(pic)
Ejemplo n.º 15
0
    def set_image(self, image):
        pic = Picture()
        pic.data = image.read()
        pic.type = COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        # pic.depth = image.color_depth

        self.audio.add_picture(pic)
        with translate_errors():
            self.audio.save()
        # clear vcomment tags
        super().clear_images()
Ejemplo n.º 16
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        with image:
            pic = Picture()
            pic.data = image.read()
            pic.type = COVER_FRONT
            pic.mime = image.mime_type
            pic.width = image.width
            pic.height = image.height

            self.audio.pop("coverart", None)
            self.audio.pop("coverartmime", None)
            self.audio["metadata_block_picture"] = base64.b64encode(
                pic.write()).decode("ascii")
Ejemplo n.º 17
0
def tag_put_picture(album_id):
    pic = Picture()
    album = get_album(album_id)
    with open(album['Path'] + "/folder.jpg", "rb") as f:
        pic.data = f.read()
    if not pic.data:
        return 'No folder.jpg found'
    pic.type = id3.PictureType.COVER_FRONT
    pic.mime = u"image/jpeg"
    pic.width = 500
    pic.height = 500
    pic.depth = 16
    for p in tag_get_piece_paths(album_id):
        set_pic(p, pic)
    return 'success'
Ejemplo n.º 18
0
def _add_ogg_image(audio: File, image: Image, image_data: bytes):
    picture = Picture()
    picture.data = image_data
    picture.type = 3  # Front cover
    picture.desc = u"Cover Art"
    picture.mime = _image_mimes[image.format]
    picture.width = image.width
    picture.height = image.height
    picture.depth = 24
    picture_data = picture.write()
    encoded_data = base64.b64encode(picture_data)

    vcomment_value = encoded_data.decode("ascii")
    audio["metadata_block_picture"] = [vcomment_value]

    audio.save()
Ejemplo n.º 19
0
    def tag_flac(self, file_path, track_info, album_info, album_art_path=None):
        tagger = FLAC(file_path)

        self._meta_tag(tagger, track_info, album_info)
        if self.fmtopts['embed_album_art'] and album_art_path is not None:
    	    pic = Picture()
    	    with open(album_art_path, 'rb') as f:
    	        pic.data = f.read()
    	    
    	    pic.type = PictureType.COVER_FRONT
    	    pic.mime = u"image/jpeg"
            # TODO: detect this automatically?
    	    pic.width = 1280
    	    pic.height = 1280
    	    pic.depth = 24
    	    tagger.add_picture(pic)
        tagger.save(file_path)
Ejemplo n.º 20
0
    def to_flac(self, flac_meta: FLAC, builtin_cuesheet=False) -> None:
        '''
        :param builtin_cuesheet: Whether to use the cuesheet field builtin FLAC specs
        '''
        def add_if_exist(obj, tag_key):
            if obj:
                flac_meta.tags[tag_key] = obj

        add_if_exist(self.title, 'ALBUM')
        add_if_exist(self.genre, 'GENRE')
        add_if_exist(self.date, 'DATE')
        if self.artists:
            flac_meta.tags['ALBUM ARTIST'] = list(self.artists)
        if self.discnumber is not None:
            flac_meta.tags['DISCNUMBER'] = str(self.discnumber)

        if self.cover:
            image = Image.open(BytesIO(self.cover))
            pic = Picture()
            pic.type = PictureType.COVER_FRONT
            pic.data = self.cover
            pic.mime = Image.MIME[image.format]
            pic.width = image.width
            pic.height = image.height
            flac_meta.add_picture(pic)

        if self.cuesheet:
            if builtin_cuesheet:
                flac_meta.cuesheet = self.cuesheet.to_flac(
                    flac_meta.info.sample_rate)
                flac_meta.cuesheet.tracks.append(
                    CueSheetTrack(170,
                                  flac_meta.info.total_samples))  # lead-out

                # save track-wise tags in foobar2000 style
                tracks = next(iter(self.cuesheet.files.values()))
                for i, track in tracks.items():
                    add_if_exist(track.title, f'CUE_TRACK{i:02}_TITLE')
                    add_if_exist(track.performer, f'CUE_TRACK{i:02}_PERFORMER')
            else:
                flac_meta.tags['CUESHEET'] = str(self.cuesheet)
            add_if_exist(self.cuesheet.catalog, 'Catalog')
            add_if_exist(self.cuesheet.rems.get('COMMENT', None), 'Comment')

        flac_meta.save()
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
 def addCover(self):
     if self.fileSuffix == "mp3" or self.fileSuffix == "MP3":
         self.songFile.tags.add(
             APIC(encoding=3,
                  mime='image/jpeg',
                  type=3,
                  desc="Cover",
                  data=self.albumart))
     elif self.fileSuffix == "flac" or self.fileSuffix == "FLAC":
         image = Picture()
         image.type = id3.PictureType.COVER_FRONT
         image.mime = 'image/jpeg'
         image.desc = "Cover"
         image.data = self.albumart
         image.width = 500
         image.height = 500
         image.depth = 16
         self.songFile.add_picture(image)
     self.songFile.save()
Ejemplo n.º 23
0
def get_image_size(fname):
	'''Determine the image type of fhandle and return its size.
	from draco'''
	with open(fname, 'rb') as fhandle:
		head = fhandle.read(24)
		if len(head) != 24:
			return
		if imghdr.what(fname) == 'png':
			check = struct.unpack('>i', head[4:8])[0]
			if check != 0x0d0a1a0a:
				return
			width, height = struct.unpack('>ii', head[16:24])
		elif imghdr.what(fname) == 'gif':
			width, height = struct.unpack('<HH', head[6:10])
		elif imghdr.what(fname) == 'jpeg':
			try:
				fhandle.seek(0) # Read 0xff next
				size = 2
				ftype = 0
				while not 0xc0 <= ftype <= 0xcf:
					fhandle.seek(size, 1)
					byte = fhandle.read(1)
					while ord(byte) == 0xff:
						byte = fhandle.read(1)
					ftype = ord(byte)
					size = struct.unpack('>H', fhandle.read(2))[0] - 2
				# We are at a SOFn block
				fhandle.seek(1, 1)  # Skip `precision' byte.
				height, width = struct.unpack('>HH', fhandle.read(4))
			except Exception: #IGNORE:W0703
				printError()
				return
		else:
			return
		fhandle.seek(0)
		imgdata = fhandle.read()
		img = Picture()
		img.data = imgdata
		img.width = width
		img.height = height

        return img
Ejemplo n.º 24
0
def write_cover_opus(afile, cover):
    file_ = OggOpus(afile)

    with open(cover, "rb") as h:
        data = h.read()

    picture = Picture()
    picture.data = data
    picture.type = 17
    picture.desc = u"cover art"
    picture.mime = u"image/" + os.path.splitext(cover)[1][1:]
    dim = [int(x) for x in COVER_DIMENSION_INTERN.split("x")]
    picture.width = dim[0]
    picture.height = dim[1]
    picture.depth = 24

    picture_data = picture.write()
    encoded_data = base64.b64encode(picture_data)
    vcomment_value = encoded_data.decode("ascii")

    file_["metadata_block_picture"] = [vcomment_value]
    file_.save()
Ejemplo n.º 25
0
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()
Ejemplo n.º 26
0
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()
Ejemplo n.º 27
0
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()
Ejemplo n.º 28
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        try:
            audio = self.MutagenType(self["~filename"])
            data = image.file.read()
        except EnvironmentError:
            return

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        audio.pop("coverart", None)
        audio.pop("coverartmime", None)
        audio["metadata_block_picture"] = base64.b64encode(pic.write())
        audio.save()

        self.has_images = True
Ejemplo n.º 29
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        try:
            audio = self.MutagenType(self["~filename"])
            data = image.file.read()
        except EnvironmentError:
            return

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        audio.pop("coverart", None)
        audio.pop("coverartmime", None)
        audio["metadata_block_picture"] = base64.b64encode(pic.write())
        audio.save()

        self.has_images = True
Ejemplo n.º 30
0
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()
Ejemplo n.º 31
0
def UpdateCoverOgg(lossyFileName, artworkFileName):   
    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 in ' + lossyFileName) 

    # Copy lossy file to a local location; to prevent (save) errors in a samba environment
    tempLossyFile = tempfile.gettempdir() + '/' + 'temp.ogg'
    copyfile(lossyFileName, tempLossyFile) 

    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()   

    copyfile(tempLossyFile, lossyFileName) 
    os.remove(tempLossyFile)  
    
    return
Ejemplo n.º 32
0
    def set_image(self, image):
        """Replaces all embedded images by the passed image"""

        try:
            tag = FLAC(self["~filename"])
            data = image.file.read()
        except EnvironmentError:
            return

        pic = Picture()
        pic.data = data
        pic.type = APICType.COVER_FRONT
        pic.mime = image.mime_type
        pic.width = image.width
        pic.height = image.height
        pic.depth = image.color_depth

        tag.add_picture(pic)
        tag.save()

        # clear vcomment tags
        super(FLACFile, self).clear_images()

        self.has_images = True
Ejemplo n.º 33
0
    def _write_tags(self, flacfile, cover=False):
        f = FLAC(flacfile)

        f['albumartist'] = self._author
        f['tracknumber'] = str(self._track_number)
        f['album'] = self._album_title
        f['title'] = self._title
        f['artist'] = self._author
        f['genre'] = 'Audiobook'
        f['comment'] = 'Generated by WaveReader - https://github.com/kerenon/wavereader'

        if self._coverfile:
            p = Picture()
            with open(self._coverfile, "rb") as pf:
                p.data = pf.read()
            i = Image.open(self._coverfile)
            p.width = i.width
            p.height = i.height
            p.mime = i.get_format_mimetype()
            i.close()
            p.type = id3.PictureType.COVER_FRONT
            f.add_picture(p)

        f.save()
Ejemplo n.º 34
0
def Utils_Meta_setMusicInfo(path, info):
    """
    TODO: Write lyrics to file
    :param path:文件目录
    :param info:字典,详情:
    {
        "TALB": "Name of Album",
        "TIT2": "Title",
        "TPE1": "Author,Separate with '/'",
        "APIC": "Path to cover photo",
        "STRICT": Boolean:strict cover mode,
        "TRANSCODE": Boolean:convert to mp3,
        "TRANSPATH": "Path to converted file"
    }
    :return: int {
        0: Nothing need done
        1: Need reExt
    }
    """
    status_code = 0
    try:
        id3 = ID3(path)
        id3.update_to_v23()
        id3.delall("TALB")
        id3.delall("TIT2")
        id3.delall("TPE1")
        id3.delall("APIC")

        id3.add(TALB(encoding=3, text=info["TALB"]))
        id3.add(TIT2(encoding=3, text=info["TIT2"]))
        id3.add(TPE1(encoding=3, text=info["TPE1"]))
        if info["STRICT"]:
            image = Image.open(info["APIC"])
            img_bytes = io.BytesIO()

            if image.size[0] > image.size[1]:
                image = image.crop(
                    (int((image.size[0] - image.size[1]) / 2), 0,
                     int((image.size[0] + image.size[1]) / 2), image.size[1]))
            elif image.size[0] < image.size[1]:
                image = image.crop((0, int(
                    (image.size[1] - image.size[0]) / 2), 0,
                                    int((image.size[0] + image.size[1]) / 2)))
            image.resize((300, 300)).save(img_bytes, format="JPEG")
            id3.add(
                APIC(encoding=0,
                     mime=mimetypes.guess_type(info["APIC"])[0],
                     type=6,
                     data=img_bytes.getvalue()))
        else:
            with open(info["APIC"], "rb") as f:
                id3.add(
                    APIC(encoding=0,
                         mime=mimetypes.guess_type(info["APIC"])[0],
                         type=6,
                         data=f.read()))
        id3.save()
    except ID3NoHeaderError:
        traceback.print_exc()
        ext = os.path.splitext(path)[1]
        if ".flac" in ext or ".FLAC" in ext:
            flac = FLAC(path)
            flac.tags['TITLE'] = info["TIT2"]
            flac.tags['ALBUM'] = info["TALB"]
            flac.tags['ARTIST'] = info["TPE1"]
            with open(info["APIC"], "rb") as f:
                image = Image.open(info["APIC"])
                p = Picture()
                p.data = f.read()
                p.type = 3
                p.mime = mimetypes.guess_type(info["APIC"])[0]
                p.width = image.size[0]
                p.height = image.size[1]
                p.depth = 24  # color depth
                flac.add_picture(p)
                image.close()
            flac.save()
        else:
            try:
                mp4 = MP4(path)
                mp4.tags["\xa9alb"] = info["TALB"]
                mp4.tags["\xa9nam"] = info["TIT2"]
                mp4.tags["\xa9ART"] = info["TPE1"]
                with open(info["APIC"], "rb") as f:
                    mp4["covr"] = [
                        MP4Cover(f.read(), imageformat=MP4Cover.FORMAT_PNG)
                    ]
                mp4.save()
                status_code = 1
            except Exception:
                traceback.print_exc()
        if info["TRANSCODE"]:
            if not os.path.exists(os.path.split(info["TRANSPATH"])[0]):
                os.makedirs(os.path.split(info["TRANSPATH"])[0])
            Utils_FormatTools.Utils_Format_autoTranscode(
                path, info["TRANSPATH"])
            info["TRANSCODE"] = False
            Utils_Meta_setMusicInfo(info["TRANSPATH"], info)
    except MutagenError:
        traceback.print_exc()
    return status_code
Ejemplo n.º 35
0
def tag(file_path: Path, track: Track) -> None:
    """
    Tag the music file at the given file path using the specified
    [Track][deethon.types.Track] instance.

    Args:
        file_path (Path): The music file to be tagged
        track: The [Track][deethon.types.Track] instance to be used for tagging.
    """
    ext = file_path.suffix

    if ext == ".mp3":
        tags = ID3()
        tags.clear()

        tags.add(Frames["TALB"](encoding=3, text=track.album.title))
        tags.add(Frames["TBPM"](encoding=3, text=str(track.bpm)))
        tags.add(Frames["TCON"](encoding=3, text=track.album.genres))
        tags.add(Frames["TCOP"](encoding=3, text=track.copyright))
        tags.add(Frames["TDAT"](encoding=3,
                                text=track.release_date.strftime("%d%m")))
        tags.add(Frames["TIT2"](encoding=3, text=track.title))
        tags.add(Frames["TPE1"](encoding=3, text=track.artist))
        tags.add(Frames["TPE2"](encoding=3, text=track.album.artist))
        tags.add(Frames["TPOS"](encoding=3, text=str(track.disk_number)))
        tags.add(Frames["TPUB"](encoding=3, text=track.album.label))
        tags.add(Frames["TRCK"](
            encoding=3, text=f"{track.number}/{track.album.total_tracks}"))
        tags.add(Frames["TSRC"](encoding=3, text=track.isrc))
        tags.add(Frames["TYER"](encoding=3, text=str(track.release_date.year)))

        tags.add(Frames["TXXX"](encoding=3,
                                desc="replaygain_track_gain",
                                text=str(track.replaygain_track_gain)))

        if track.lyrics:
            tags.add(Frames["USLT"](encoding=3, text=track.lyrics))

        tags.add(Frames["APIC"](encoding=3,
                                mime="image/jpeg",
                                type=3,
                                desc="Cover",
                                data=track.album.cover_xl))

        tags.save(file_path, v2_version=3)

    else:
        tags = FLAC(file_path)
        tags.clear()
        tags["album"] = track.album.title
        tags["albumartist"] = track.album.artist
        tags["artist"] = track.artist
        tags["bpm"] = str(track.bpm)
        tags["copyright"] = track.copyright
        tags["date"] = track.release_date.strftime("%Y-%m-%d")
        tags["genre"] = track.album.genres
        tags["isrc"] = track.isrc
        if track.lyrics:
            tags["lyrics"] = track.lyrics
        tags["replaygain_track_gain"] = str(track.replaygain_track_gain)
        tags["title"] = track.title
        tags["tracknumber"] = str(track.number)
        tags["year"] = str(track.release_date.year)

        cover = Picture()
        cover.type = 3
        cover.data = track.album.cover_xl
        cover.width = 1000
        cover.height = 1000
        tags.clear_pictures()
        tags.add_picture(cover)
        tags.save(deleteid3=True)