Exemplo n.º 1
0
        def set_id3_tags(audio):
            # add ID3 tag if it doesn't exist
            audio.add_tags()

            def embed_image(data):
                audio.tags.add(
                    id3.APIC(
                        encoding=3,
                        mime='image/jpeg',
                        type=3,
                        desc='Front Cover',
                        data=data
                    )
                )

            save_cover_image(embed_image)

            if album is not None:
                audio.tags.add(
                    id3.TALB(text=[tag_to_ascii(track.album.name, album)],
                             encoding=3))
            audio.tags.add(
                id3.TIT2(text=[tag_to_ascii(track.name, title)],
                         encoding=3))
            audio.tags.add(
                id3.TPE1(text=[tag_to_ascii(artists, artists_ascii)],
                         encoding=3))
            if album_artist is not None:
                audio.tags.add(
                    id3.TPE2(text=[tag_to_ascii(
                                       track.album.artist.name, album_artist)],
                             encoding=3))
            audio.tags.add(id3.TDRC(text=[str(track.album.year)],
                                    encoding=3))
            audio.tags.add(
                id3.TPOS(text=[idx_of_total_str(track.disc, num_discs)],
                         encoding=3))
            audio.tags.add(
                id3.TRCK(text=[idx_of_total_str(track.index, num_tracks)],
                         encoding=3))
            if args.comment is not None:
                audio.tags.add(
                    id3.COMM(text=[tag_to_ascii(comment, comment_ascii)],
                             encoding=3))
            if args.grouping is not None:
                audio.tags.add(
                    id3.TIT1(text=[tag_to_ascii(grouping, grouping_ascii)],
                             encoding=3))
            if genres is not None and genres:
                tcon_tag = id3.TCON(encoding=3)
                tcon_tag.genres = genres if args.ascii_path_only \
                    else genres_ascii
                audio.tags.add(tcon_tag)

            if args.id3_v23:
                audio.tags.update_to_v23()
                audio.save(v2_version=3, v23_sep='/')
                audio.tags.version = (2, 3, 0)
            else:
                audio.save()
Exemplo n.º 2
0
def fix_tags(abs, ext, f_meta):
    """
	:param abs: Path of the file we're tagging
	:param ext: Extension of the file we're tagging
	:param f_meta: Dict containing the metadata of the track we're tagging.
	"""
    if ext == "mp3":
        try:
            audio = id3.ID3(abs)
        except ID3NoHeaderError:
            audio = id3.ID3()
        audio['TRCK'] = id3.TRCK(text=str(audio['TRCK']) + "/" +
                                 str(f_meta['track_total']))
        audio['TPOS'] = id3.TPOS(text=str(audio['TPOS']) + "/" +
                                 str(f_meta['disc_total']))
        audio['TDRC'] = id3.TPOS(text=f_meta['release_date'])
        audio['TPUB'] = id3.TPOS(text=f_meta['planning'])
        audio['TPE1'] = id3.TPE1(text=f_meta['track_artist'])
        audio['TPE2'] = id3.TPE2(text=f_meta['album_artist'])
        audio.save(abs, "v2_version=3")
    else:
        audio = FLAC(abs)
        audio['TRACKTOTAL'] = str(f_meta['track_total'])
        audio['DISCTOTAL'] = str(f_meta['disc_total'])
        audio['DATE'] = f_meta['release_date']
        audio['LABEL'] = f_meta['planning']
        audio['ARTIST'] = f_meta['track_artist']
        audio['ALBUMARTIST'] = f_meta['album_artist']
        audio.save()
Exemplo n.º 3
0
        def set_id3_tags_raw(audio, audio_file):
            try:
                id3_dict = id3.ID3(audio_file)
            except id3.ID3NoHeaderError:
                id3_dict = id3.ID3()

            def embed_image(data):
                id3_dict.add(
                    id3.APIC(encoding=3,
                             mime='image/jpeg',
                             type=3,
                             desc='Front Cover',
                             data=data))

            save_cover_image(embed_image)

            if album is not None:
                id3_dict.add(
                    id3.TALB(text=[tag_to_ascii(track.album.name, album)],
                             encoding=3))
            id3_dict.add(
                id3.TIT2(text=[tag_to_ascii(track.name, title)], encoding=3))
            id3_dict.add(
                id3.TPE1(text=[tag_to_ascii(artists, artists_ascii)],
                         encoding=3))
            if album_artist is not None:
                id3_dict.add(
                    id3.TPE2(text=[
                        tag_to_ascii(track.album.artist.name, album_artist)
                    ],
                             encoding=3))
            id3_dict.add(id3.TDRC(text=[str(track.album.year)], encoding=3))
            id3_dict.add(
                id3.TPOS(text=[idx_of_total_str(track.disc, num_discs)],
                         encoding=3))
            id3_dict.add(
                id3.TRCK(text=[idx_of_total_str(track.index, num_tracks)],
                         encoding=3))
            if args.comment is not None:
                id3_dict.add(
                    id3.COMM(text=[tag_to_ascii(comment, comment_ascii)],
                             encoding=3))
            if args.grouping is not None:
                audio.tags.add(
                    id3.TIT1(text=[tag_to_ascii(grouping, grouping_ascii)],
                             encoding=3))
            if genres is not None and genres:
                tcon_tag = id3.TCON(encoding=3)
                tcon_tag.genres = genres if args.ascii_path_only \
                    else genres_ascii
                id3_dict.add(tcon_tag)

            if args.id3_v23:
                id3_dict.update_to_v23()
                id3_dict.save(audio_file, v2_version=3, v23_sep='/')
                id3_dict.version = (2, 3, 0)
            else:
                id3_dict.save(audio_file)
            audio.tags = id3_dict
Exemplo n.º 4
0
    def set_tags(self, audio):
        try:
            id3_dict = id3.ID3(self.audio_file)
        except id3.ID3NoHeaderError:
            id3_dict = id3.ID3()

        def embed_image(data):
            id3_dict.add(
                id3.APIC(encoding=3,
                         mime='image/jpeg',
                         type=3,
                         desc='Front Cover',
                         data=data))

        self.save_cover_image(embed_image)

        if self.album() is not None:
            id3_dict.add(id3.TALB(text=[self.album()], encoding=3))

        id3_dict.add(id3.TIT2(text=[self.title()], encoding=3))
        id3_dict.add(id3.TPE1(text=[self.artists()], encoding=3))

        if self.album_artist() is not None:
            id3_dict.add(id3.TPE2(text=[self.album_artist()], encoding=3))

        id3_dict.add(id3.TDRC(text=[self.year()], encoding=3))
        id3_dict.add(id3.TPOS(text=[self.disc_idx_and_total()], encoding=3))
        id3_dict.add(id3.TRCK(text=[self.track_idx_and_total()], encoding=3))

        if self.comment() is not None:
            id3_dict.add(id3.COMM(text=[self.comment()], encoding=3))

        if self.grouping() is not None:
            id3_dict.add(id3.TIT1(text=[self.grouping()], encoding=3))

        if self.genres() is not None:
            tcon_tag = id3.TCON(encoding=3)
            tcon_tag.genres = self.genres()
            id3_dict.add(tcon_tag)

        if self.args.id3_v23:
            id3_dict.update_to_v23()
            id3_dict.save(self.audio_file, v2_version=3, v23_sep='/')
            id3_dict.version = (2, 3, 0)
        else:
            id3_dict.save(self.audio_file)
        audio.tags = id3_dict
Exemplo n.º 5
0
    def set_tags(self, audio):
        # add ID3 tag if it doesn't exist
        audio.add_tags()

        def embed_image(data):
            audio.tags.add(
                id3.APIC(encoding=3,
                         mime='image/jpeg',
                         type=3,
                         desc='Front Cover',
                         data=data))

        self.save_cover_image(embed_image)

        if self.album() is not None:
            audio.tags.add(id3.TALB(text=[self.album()], encoding=3))

        audio.tags.add(id3.TIT2(text=[self.title()], encoding=3))
        audio.tags.add(id3.TPE1(text=[self.artists()], encoding=3))

        if self.album_artist() is not None:
            audio.tags.add(id3.TPE2(text=[self.album_artist()], encoding=3))

        audio.tags.add(id3.TDRC(text=[self.year()], encoding=3))
        audio.tags.add(id3.TPOS(text=[self.disc_idx_and_total()], encoding=3))
        audio.tags.add(id3.TRCK(text=[self.track_idx_and_total()], encoding=3))

        if self.comment() is not None:
            audio.tags.add(id3.COMM(text=[self.comment()], encoding=3))

        if self.grouping() is not None:
            audio.tags.add(id3.TIT1(text=[self.grouping()], encoding=3))

        if self.genres() is not None:
            tcon_tag = id3.TCON(encoding=3)
            tcon_tag.genres = self.genres()
            audio.tags.add(tcon_tag)

        if self.args.id3_v23:
            audio.tags.update_to_v23()
            audio.save(v2_version=3, v23_sep='/')
            audio.tags.version = (2, 3, 0)
        else:
            audio.save()
Exemplo n.º 6
0
    def save(self):
        if self.clr:
            for file in self.audiofiles:
                tmp = mid3.ID3(file)
                tmp.clear()
                tmp.add(mid3.TIT2(text=""))  # title frame
                tmp.add(mid3.TPE1(text=""))  # artist frame
                tmp.add(mid3.TALB(text=""))  # album frame
                tmp.add(mid3.TPE2(text=""))  # album artist frame
                tmp.add(mid3.TCOM(text=""))  # composer frame
                tmp.add(mid3.TCON(text=""))  # genre frame
                tmp.add(mid3.TDRC(text=""))  # date frame
                tmp.add(mid3.TRCK(text=""))  # tracknumber frame
                tmp.add(mid3.TPOS(text=""))  # discnumber frame
                tmp.add(mid3.TBPM(text=""))  # bpm frame
                tmp.save()

        if self.artwork:
            with open(self.artwork, 'rb') as albumart:
                for file in self.audiofiles:
                    tmp = mid3.ID3(file)
                    tmp['APIC'] = mid3.APIC(
                        encoding=3,
                        mime='image/jpeg',
                        type=3, desc=u'Cover',
                        data=albumart.read()
                    )
                    tmp.save()
                    albumart.seek(0)

        for file in self.audiofiles:
            tmp = EasyID3(file)
            for tag in self.__sets:
                if self.__sets[tag]:
                    tmp[tag] = self.__sets[tag]
                    tmp.save()
Exemplo n.º 7
0
    def __update_tag(self, download_dir, audio_file, image_file,
                     song_title=None, album_title=None, album_artist=None, album_composer=None,
                     track_number=-1, process_index=-1, process_total=-1):
        """
        The function that update audio metadata for each song.

        :param str download_dir: Download directory
        :param str audio_file: Path to audio file
        :param str image_file: Path to image file
        :param str song_title: Song title
        :param str album_title: Album title to be saved in metadata
        :param str album_artist: Album artist to be saved in metadata
        :param str album_composer: Album composer to be saved in metadata
        :param int track_number: track number to be saved in metadata
        :param int process_index: Current process index displayed in log message
        :param int process_total: Total number of process displayed in log message
        """

        if audio_file is None:
            logger.warning('[Process:{}/{}][Track:{}] Could not update metadata because there is no data found on the playlist. The video may be private or deleted.'.format(process_index, process_total, track_number))
            return

        if process_index > 0 and process_total > 0:

            if track_number > 0:
                log_prefix = '[Process:{}/{}][Track:{}]'.format(process_index, process_total, track_number)

            else:
                log_prefix = '[Process:{}/{}]'.format(process_index, process_total)

        else:
            log_prefix = ''

        audio_filename = os.path.basename(audio_file)

        try:
            # Validate audio data
            if not os.path.isfile(audio_file):
                raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), audio_file)

            audio_mime_type = mimetypes.guess_type(audio_file)

            if contains_at_least(audio_mime_type, ['audio/x-mp4', 'audio/x-m4a', 'audio/mp4a-latm']):

                # For more info about mp4 tag is available at
                # https://github.com/quodlibet/mutagen/blob/cf399dc58940fb1356f672809d763be9e2af0033/mutagen/mp4/__init__.py
                # http://atomicparsley.sourceforge.net/mpeg-4files.html
                mp4_data = mp4.MP4(audio_file)
                # Track Number
                if not self.no_track_number and track_number > 0:
                    mp4_data['trkn'] = [(track_number, 0)]
                # Cover image
                if not self.no_artwork:
                    image_data = self.__get_tag_image(image_file, audio_mime_type)
                    if image_data:
                        mp4_data['covr'] = [image_data]
                # Album title
                if not self.no_album_title and album_title is not None:
                    mp4_data['\xa9alb'] = album_title
                # Album artist
                if not self.no_album_artist and album_artist is not None:
                    mp4_data['aART'] = album_artist
                # Composer
                if not self.no_composer and album_composer is not None:
                    mp4_data['\xa9wrt'] = album_composer
                # Part of compilation
                if not self.no_compilation:
                    mp4_data['cpil'] = True
                # Save
                mp4_data.save()

            elif contains_at_least(audio_mime_type, ['audio/x-mp3', 'audio/mpeg']):

                # For more info about ID3v2 tag is available at
                # https://github.com/quodlibet/mutagen/blob/4a5d7d17f1a611280cc52d229aa70b77ca3c55dd/mutagen/id3/_frames.py
                # https://help.mp3tag.de/main_tags.html
                mp3_data = id3.ID3(audio_file)
                # Cover image
                if not self.no_artwork:
                    image_data = self.__get_tag_image(image_file, audio_mime_type)
                    if image_data:
                        mp3_data['APIC'] = image_data
                # Track number
                if not self.no_track_number and track_number > 0:
                    mp3_data.add(id3.TRCK(encoding=3, text=['{}/{}'.format(track_number, 0)]))
                # Album title
                if not self.no_album_title and album_title is not None:
                    mp3_data["TALB"] = id3.TALB(encoding=0, text=album_title)
                # Album artist
                if not self.no_album_artist and album_artist is not None:
                    mp3_data["TPE2"] = id3.TPE2(encoding=0, text=album_artist)
                # Composer
                if not self.no_composer and album_composer is not None:
                    mp3_data["TCOM"] = id3.TCOM(encoding=0, text=album_composer)
                # Part of compilation
                if not self.no_compilation:
                    mp3_data['TCMP'] = id3.TCMP(encoding=0, text=['1'])
                # Save
                mp3_data.save()

            elif contains_at_least(audio_mime_type, ['audio/x-aac']):

                # TODO: Add AAC support
                pass
                # image_data = __get_tag_image(image_file, audio_mime_type)
                # aac_data = aac.AAC(audio_file)
                # if not self.no_track_number:
                #     if track_number > 0 and track_total > 0:
                #         aac_data.add_tags(id3.TRCK(encoding=3, text=['{}/{}'.format(track_number, track_total)]))
                #         # mp3_data['TRCK'] = id3.TRCK(encoding=3, text=[str(track_number)])
                # if image_data:
                #     mp3_data['APIC'] = image_data
                #     aac_data.save()

            elif contains_at_least(audio_mime_type, ['audio/x-flac']):

                # https://github.com/quodlibet/mutagen/blob/a1db79ece62c4e86259f15825e360d1ce0986a22/mutagen/flac.py
                # https://github.com/quodlibet/mutagen/blob/4a5d7d17f1a611280cc52d229aa70b77ca3c55dd/tests/test_flac.py

                flac_data = flac.FLAC(audio_file)
                # Artwork
                if not self.no_artwork:
                    image_data = self.__get_tag_image(image_file, audio_mime_type)
                    if image_data:
                        flac_data.add_picture(image_data)
                # Save
                flac_data.save()

                flac_data = File(audio_file)
                # Track number
                if not self.no_track_number and track_number > 0:
                    flac_data.tags['tracknumber'] = str(track_number)
                # Album title
                if not self.no_album_title and album_title is not None:
                    flac_data.tags['album'] = album_title
                # Album artist
                if not self.no_album_artist and album_artist is not None:
                    flac_data.tags['albumartist'] = album_artist
                # Composer
                if not self.no_composer and album_composer is not None:
                    flac_data.tags['composer'] = album_composer
                # Part of compilation
                if not self.no_compilation:
                    pass
                # Save
                flac_data.save()
                # audio = File(audio_file, easy=True)

            else:
                raise InvalidMimeTypeException("Invalid audio format.", audio_mime_type)

            # Remove artwork if succeeded
            if os.path.exists(image_file):
                os.remove(image_file)

            # Rename filename from id to title
            dest_audio_file = os.path.join(download_dir, '{}.{}'.format(song_title, self.audio_codec))
            os.rename(audio_file, dest_audio_file)

            dest_audio_filename = os.path.basename(dest_audio_file)
            logger.info('{}[File:{}] Updated.'.format(log_prefix, dest_audio_filename))

        except FileNotFoundError:
            message = 'File not found. Skipped.'
            logger.warning('{}[File:{}] {}'.format(log_prefix, audio_filename, message))

        except InvalidDataException as e:
            message = e.message + ' Skipped.'
            logger.warning('{}[File:{}] {}'.format(log_prefix, audio_filename, message))

        except InvalidMimeTypeException as e:
            message = e.message + ' Skipped.'
            logger.warning('{}[File:{}] {}'.format(log_prefix, audio_filename, message))

        except Exception as e:
            message = 'Error {}: {} Skipped.'.format(type(e), str(e))
            logger.error('{}[File:{}] {}'.format(log_prefix, audio_filename, message))
Exemplo n.º 8
0
def visit(arg, dirname, names):
    print dirname
    # Do some math/checking for disk number info
    parent = os.path.dirname(dirname)
    thisdir = os.path.basename(dirname)
    m = re.search(r'(?:cd|dis[ck])\s+([AB]|\d+)\b', thisdir, flags=re.IGNORECASE)
    disknum  = 0
    numdisks = 0
    if m:
        disknum = m.group(1)
        if disknum == 'A':
            disknum = 1
        elif disknum == 'B':
            disknum = 2
        else:
            disknum = int(disknum)
        for dir in os.listdir(parent):
            if not os.path.isdir(os.path.join(parent, dir)):
                continue
            m = re.search(r'(?:cd|dis[ck])\s+([AB]|\d+)\b', dir, flags=re.IGNORECASE)
            if m:
                d = m.group(1)
                if d == 'A':
                    d = 1
                elif d == 'B':
                    d = 2
                else:
                    d = int(d)
                numdisks = max(numdisks, d)
    # Parse the files
    mp3 = []
    m4a = []
    for file in names:
        if file.startswith('.'):
            continue
        elif file.endswith('.m4a'):
            m4a.append(file)
        elif file.endswith('.mp3'):
            mp3.append(file)
        else:
            try:
                # Clean up the name
                if os.path.isdir(os.path.join(dirname, file)):
                    new = fix_name(file.decode("utf-8"))
                else:
                    new = fix_name_full(file.decode("utf-8"))
                #print os.path.join(dirname, file)
                if file.decode("utf-8") != new.decode("utf-8"):
                    print '  {0}\n    {1}'.format(file, new)
                    if not dryrun:
                        os.rename(os.path.join(dirname, file), os.path.join(dirname, new))
            except:
                print "  FILE:  "+os.path.join(dirname, file)
                raise
    # Now, parse the music files
    music   = []
    artists = {}
    is_comp = False
    artist  = None
    for file in m4a:
        # Load some info about this mp4 for later comparison
        (mp4, name, changed) = load_mp4(dirname, file, len(m4a), int(disknum), int(numdisks))
        # Setup for compilation detection
        if not is_comp:
            if artist:
                if artist != mp4[t4['artist']][0]:
                    is_comp = True
            else:
                artist = mp4[t4['artist']][0]
                if artist.lower() == 'various':
                    is_comp = True
            a_artist = mp4.get(t4['albumartist'], [None])[0]
            if a_artist and artist and a_artist != artist:
                is_comp = True
        # Save music files for later
        music.append({
            'file':    file,
            'name':    name,
            'mp4':     mp4,
            'changed': changed,
            })
    for file in mp3:
        # Load some info about this mp4 for later comparison
        (mp3, name, changed) = load_mp3(dirname, file, len(mp3), disknum, numdisks)
        # Setup for compilation detection
        if not is_comp:
            if artist:
                if t3['artist'] in mp3 and artist != mp3[t3['artist']].text[0]:
                    is_comp = True
            elif t3['artist'] in mp3:
                artist = mp3[t3['artist']].text[0]
                if artist.lower() == 'various':
                    is_comp = True
            if t3['albumartist'] in mp3:
                a_artist = mp3[t3['albumartist']].text[0]
                if a_artist and artist and a_artist != artist:
                    is_comp = True
        # Save music files for later
        music.append({
            'file':    file,
            'name':    name,
            'mp3':     mp3,
            'changed': changed,
            })
    if len(artists) > 1:
        is_comp = True
    # Now parse the music files that we found
    for group in music:
        # Load the data from the group, for easier manipulation
        file    = group['file']
        name    = group['name']
        changed = group['changed']
        #print file
        if 'mp4' in group:
            m = group['mp4']
            # Compilation?
            compilation = m.get(t4['partofcompilation'])
            if is_comp and not compilation:
                compilation = True
                m[t4['partofcompilation']] = True
                changed.append('partofcompilation')
            a_artist = m.get(t4['albumartist'], [None])[0]
            if compilation and not a_artist:
                m[t4['albumartist']] = ['Various']
                changed.append('albumartist')
        elif 'mp3' in group:
            m = group['mp3']
            # Compilation?
            compilation = None
            if t3['partofcompilation'] in m:
                compilation = m[t3['partofcompilation']].text[0]
            if is_comp and not compilation:
                m[t3['partofcompilation']] = id3.TCMP(0, '1')
                changed.append('partofcompilation')
            if compilation and not (t3['albumartist'] in m and m[t3['albumartist']].text[0]):
                m[t3['albumartist']] = id3.TPE2(0, 'Various')
                changed.append('albumartist')
        # Save
        if changed and len(changed) > 0:
            print "  Save {0}\n    {1}".format(file, ','.join(changed))
            if not dryrun:
                m.save()
        if name:
            print '  {0}\n    {1}'.format(file, name)
            if not dryrun:
                os.rename(os.path.join(dirname, file), os.path.join(dirname, name))
Exemplo n.º 9
0
 def setAlbumArtist(self, _value):
     self.isSave = True
     self.tags["TPE2"] = id3.TPE2(
         encoding=3, text=self.correctValuesForMusicTagType(_value))
Exemplo n.º 10
0
       id3Title + " by " + id3Artist)
 try:
     url = api.get_stream_url(trackIDs[0])
     urlretrieve(url, filePath)
 except:
     print("Error occurred downloading trackID " + trackIDs[0] +
           ". Skipping...")
     del trackIDs[0]
     continue
 errorTrack = 0
 mp3File = File(filePath)
 mp3File.add_tags()
 mp3File.tags.add(id3.TIT2(encoding=3, text=id3Title))
 mp3File.tags.add(id3.TALB(encoding=3, text=id3Album))
 mp3File.tags.add(id3.TPE1(encoding=3, text=id3Artist))
 mp3File.tags.add(id3.TPE2(encoding=3, text=id3AlbumArtist))
 mp3File.tags.add(id3.TCOM(encoding=3, text=id3Composer))
 if id3Genre:
     mp3File.tags.add(id3.TCON(encoding=3, text=id3Genre))
 if id3Year:
     mp3File.tags.add(id3.TYER(encoding=3, text=id3Year))
 mp3File.tags.add(id3.TRCK(encoding=3, text=id3TrackNumber))
 mp3File.tags.add(id3.TPOS(encoding=3, text=id3DiscNumber))
 if id3AlbumCover:
     mp3File.tags.add(
         id3.APIC(mime='image/jpeg',
                  type=3,
                  desc=u'Cover',
                  data=id3AlbumCover))
 mp3File.save()
 del trackIDs[0]