def select_track(self, *event):

        if len(self.listbox.curselection()) != 0:

            self.idx_track = self.listbox.curselection()[0]
            pista = self.listbox.get(self.idx_track)

            self.set_titulo(pista)
            self.reproductor.load_music(self.listado_pista[self.idx_track])
            song = ""
            songLength = ""
            try:
                song = wave.WAVE(self.listado_pista[self.idx_track])
                songLength = song.info.length
            except MutagenError:
                print("error")

            try:
                song = oggvorbis.OggVorbis(self.listado_pista[self.idx_track])
                songLength = song.info.length
            except MutagenError:
                print("error")

            m, s = divmod(songLength, 60)
            m, s = int(m), int(s)
            print(songLength)
            print(f"{m:02}:{s:02}")
            self.progress_timeline["to"] = songLength
            print("Tiempo de duración", self.progress_timeline["to"])
            self.set_duration(f"{m:02}:{s:02}")
            self.var_timeline.set(0)
            self.play()
Пример #2
0
    def vorbis_art(self, vorbis_file):

        song = mogg.OggVorbis(vorbis_file)

        pic = mflac.Picture()
        pic.data = self.art_data
        pic.type = 3
        pic.mime = 'image/jpeg'

        song['METADATA_BLOCK_PICTURE'] = str(base64.b64encode(pic.write()),
                                             'utf-8')
        song.save()
Пример #3
0
    async def detecter(self, songdir):
        #リストアップ
        files = os.listdir(songdir)
        files_file = [
            f for f in files if os.path.isfile(os.path.join(songdir, f))
        ]
        #osuファイル検出
        osu_detect = [l for l in files_file if l.endswith('.osu')]
        osu_osup = os.path.join(songdir, osu_detect[0])
        osu_osuo = open(osu_osup, encoding='utf_8')
        osu_raw = osu_osuo.readlines()
        osu_osuo.close()
        AFn = None
        Tit = None
        UTit = None
        dosz_id = None

        for line in osu_raw:
            line = line.replace('\n', '')
            if line.startswith("AudioFilename:"):
                AFn = line[15:]
                continue
            elif line.startswith("Title:"):
                Tit = line[6:]
                continue
            elif line.startswith("TitleUnicode:"):
                UTit = line[13:]
                break
            elif line.startswith("[Difficulty]"):
                break

        if UTit:
            Tit = UTit
        AudioFname = os.path.join(songdir, AFn)
        if AudioFname.endswith(".mp3") or AudioFname.endswith(".MP3"):
            af = MP3(AudioFname)
        elif AudioFname.endswith(".ogg") or AudioFname.endswith(".OGG"):
            af = oggvorbis.OggVorbis(AudioFname)
        elif AudioFname.endswith(".m4a") or AudioFname.endswith(".M4A"):
            af = MP4(AudioFname)
        elif AudioFname.endswith(".flac") or AudioFname.endswith(".FLAC"):
            af = flac.FLAC(AudioFname)
        duration = int(af.info.length) + 1
        dosz_idd = os.path.dirname(songdir)
        dosz_ids = songdir.replace(dosz_idd, '').split(' ')[0]
        dosz_id = dosz_ids.replace('\\', '')
        print("検出ID:{}".format(dosz_id))
        return Tit, AudioFname, duration, dosz_id
Пример #4
0
    def vorbis_tag(self, a_file):
        """ This function takes a metadata dictionary and uses Mutagen to
        apply it to a FLAC or OGG Vorbis file.
        """

        title, extension = os.path.splitext(a_file)

        if extension == '.flac':
            song = mflac.FLAC(a_file)
        elif extension == '.ogg':
            song = mogg.OggVorbis(a_file)
        else:
            print("%s format not permitted by flac_paste" % extension)

        # Remove any pre-existing tags
        song.delete()

        info_dict = self.info_dict
        transfer_dictionary = {
            'ALBUM': info_dict['album'],
            'ALBUMARTIST': info_dict['album_artist'],
            'ARTIST': info_dict['artist'],
            'DATE': info_dict['date'][:4],
            'LABEL': info_dict['label'],
            'GENRE': info_dict['genre'],
            'TITLE': self.track_title,
            'TRACKNUMBER': self.track_number.zfill(2),
            'TOTALTRACKS': str(info_dict['total_tracks']).zfill(2),
            'DISCNUMBER': info_dict['disc'],
            'TOTALDISCS': info_dict['total_discs']
        }

        for tag in transfer_dictionary:
            song[tag] = transfer_dictionary[tag]

        song.save()
Пример #5
0
def set_metadata_tags(args, audio_file, idx, track, ripper):
    # log completed file
    print(Fore.GREEN + Style.BRIGHT + os.path.basename(audio_file) +
          Style.NORMAL + "\t[ " + format_size(os.stat(audio_file)[ST_SIZE]) +
          " ]" + Fore.RESET)

    if args.output_type == "wav" or args.output_type == "pcm":
        print(Fore.YELLOW + "Skipping metadata tagging for " +
              args.output_type + " encoding...")
        return

    # ensure everything is loaded still
    if not track.is_loaded:
        track.load()
    if not track.album.is_loaded:
        track.album.load()
    album_browser = track.album.browse()
    album_browser.load()

    # calculate num of tracks on disc and num of dics
    num_discs = 0
    num_tracks = 0
    for track_browse in album_browser.tracks:
        if (track_browse.disc == track.disc and
                track_browse.index > track.index):
            num_tracks = track_browse.index
        if track_browse.disc > num_discs:
            num_discs = track_browse.disc

    # try to get genres from Spotify's Web API
    genres = None
    if args.genres is not None:
        genres = ripper.web.get_genres(args.genres[0], track)

    # use mutagen to update id3v2 tags and vorbis comments
    try:
        audio = None
        on_error = 'replace' if args.ascii_path_only else 'ignore'
        album = to_ascii(track.album.name, on_error)
        artist = to_ascii(track.artists[0].name, on_error)
        title = to_ascii(track.name, on_error)

        # the comment tag can be formatted
        if args.comment is not None:
            comment = \
                format_track_string(ripper, args.comment[0], idx, track)
            comment_ascii = to_ascii(comment, on_error)

        if args.grouping is not None:
            grouping = \
                format_track_string(ripper, args.grouping[0], idx, track)
            grouping_ascii = to_ascii(grouping, on_error)

        if genres is not None and genres:
            genres_ascii = [to_ascii(genre) for genre in genres]

        # cover art image
        def get_cover_image(image_link):
            image_link = 'http://i.scdn.co%s' % (
                image_link[len('spotify'):].replace(':', '/'))
            cover_file = urllib.request.urlretrieve(image_link)[0]

            with open(cover_file, "rb") as f:
                if f.mode == "rb":
                    return f.read()
                else:
                    return None

        image_link = str(track.album.cover(0).link)
        image = get_cover_image(image_link)
        
        def tag_to_ascii(_str, _str_ascii):
            return _str if args.ascii_path_only else _str_ascii

        def idx_of_total_str(_idx, _total):
            if _total > 0:
                return "%d/%d" % (_idx, _total)
            else:
                return "%d" % (_idx)

        def save_cover_image(embed_image_func):
            if image is not None:
                def write_image(file_name):
                    cover_path = os.path.dirname(audio_file)
                    cover_file = os.path.join(cover_path, file_name)
                    if not path_exists(cover_file):
                        with open(cover_file, "wb") as f:
                            f.write(image)

                if args.cover_file is not None:
                    write_image(args.cover_file[0])
                elif args.cover_file_and_embed is not None:
                    write_image(args.cover_file_and_embed[0])
                    embed_image_func()
                else:
                    embed_image_func()

        def set_id3_tags(audio):
            # add ID3 tag if it doesn't exist
            audio.add_tags()

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

            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(track.artists[0].name, 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()

        # aac is not well supported
        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():
                id3_dict.add(
                    id3.APIC(
                        encoding=3,
                        mime='image/jpeg',
                        type=3,
                        desc='Front Cover',
                        data=image
                    )
                )

            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(track.artists[0].name, 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

        def set_vorbis_comments(audio):
            # add Vorbis comment block if it doesn't exist
            if audio.tags is None:
                audio.add_tags()

            def embed_image():
                pic = flac.Picture()
                pic.type = 3
                pic.mime = "image/jpeg"
                pic.desc = "Front Cover"
                pic.data = image
                if args.output_type == "flac":
                    audio.add_picture(pic)
                else:
                    data = base64.b64encode(pic.write())
                    audio["METADATA_BLOCK_PICTURE"] = [data.decode("ascii")]

            save_cover_image(embed_image)

            if album is not None:
                audio.tags["ALBUM"] = tag_to_ascii(track.album.name, album)
            audio.tags["TITLE"] = tag_to_ascii(track.name, title)
            audio.tags["ARTIST"] = tag_to_ascii(track.artists[0].name, artist)
            audio.tags["DATE"] = str(track.album.year)
            audio.tags["YEAR"] = str(track.album.year)
            audio.tags["DISCNUMBER"] = str(track.disc)
            audio.tags["DISCTOTAL"] = str(num_discs)
            audio.tags["TRACKNUMBER"] = str(track.index)
            audio.tags["TRACKTOTAL"] = str(num_tracks)
            if args.comment is not None:
                audio.tags["COMMENT"] = tag_to_ascii(comment, comment_ascii)
            if args.grouping is not None:
                audio.tags["GROUPING"] = \
                    tag_to_ascii(grouping, grouping_ascii)

            if genres is not None and genres:
                _genres = genres if args.ascii_path_only else genres_ascii
                audio.tags["GENRE"] = ", ".join(_genres)

            audio.save()

        # only called by Python 3
        def set_mp4_tags(audio):
            # add MP4 tags if it doesn't exist
            if audio.tags is None:
                audio.add_tags()

            def embed_image():
                audio.tags["covr"] = mp4.MP4Cover(image)

            save_cover_image(embed_image)

            if album is not None:
                audio.tags["\xa9alb"] = tag_to_ascii(track.album.name, album)
            audio["\xa9nam"] = tag_to_ascii(track.name, title)
            audio.tags["\xa9ART"] = tag_to_ascii(track.artists[0].name, artist)
            audio.tags["\xa9day"] = str(track.album.year)
            audio.tags["disk"] = [(track.disc, num_discs)]
            audio.tags["trkn"] = [(track.index, num_tracks)]
            if args.comment is not None:
                audio.tags["\xa9cmt"] = tag_to_ascii(comment, comment_ascii)
            if args.grouping is not None:
                audio.tags["\xa9grp"] = tag_to_ascii(grouping, grouping_ascii)

            if genres is not None and genres:
                _genres = genres if args.ascii_path_only else genres_ascii
                audio.tags["\xa9gen"] = ", ".join(_genres)

            audio.save()

        def set_m4a_tags(audio):
            # add M4A tags if it doesn't exist
            audio.add_tags()

            def embed_image():
                audio.tags[str("covr")] = m4a.M4ACover(image)

            save_cover_image(embed_image)

            if album is not None:
                audio.tags[b"\xa9alb"] = tag_to_ascii(track.album.name, album)
            audio[b"\xa9nam"] = tag_to_ascii(track.name, title)
            audio.tags[b"\xa9ART"] = tag_to_ascii(
                track.artists[0].name, artist)
            audio.tags[b"\xa9day"] = str(track.album.year)
            audio.tags[str("disk")] = (track.disc, num_discs)
            audio.tags[str("trkn")] = (track.index, num_tracks)
            if args.comment is not None:
                audio.tags[b"\xa9cmt"] = tag_to_ascii(comment, comment_ascii)
            if args.grouping is not None:
                audio.tags[b"\xa9grp"] = tag_to_ascii(grouping, grouping_ascii)

            if genres is not None and genres:
                _genres = genres if args.ascii_path_only else genres_ascii
                audio.tags[b"\xa9gen"] = ", ".join(_genres)

            audio.save()

        if args.output_type == "flac":
            audio = flac.FLAC(audio_file)
            set_vorbis_comments(audio)
        elif args.output_type == "ogg":
            audio = oggvorbis.OggVorbis(audio_file)
            set_vorbis_comments(audio)
        elif args.output_type == "opus":
            audio = oggopus.OggOpus(audio_file)
            set_vorbis_comments(audio)
        elif args.output_type == "aac":
            audio = aac.AAC(audio_file)
            set_id3_tags_raw(audio, audio_file)
        elif args.output_type == "m4a":
            if sys.version_info >= (3, 0):
                from mutagen import mp4

                audio = mp4.MP4(audio_file)
                set_mp4_tags(audio)
            else:
                from mutagen import m4a, mp4

                audio = m4a.M4A(audio_file)
                set_m4a_tags(audio)
                audio = mp4.MP4(audio_file)
        elif args.output_type == "alac.m4a":
            if sys.version_info >= (3, 0):
                from mutagen import mp4

                audio = mp4.MP4(audio_file)
                set_mp4_tags(audio)
            else:
                from mutagen import m4a, mp4

                audio = m4a.M4A(audio_file)
                set_m4a_tags(audio)
                audio = mp4.MP4(audio_file)
        elif args.output_type == "mp3":
            audio = mp3.MP3(audio_file, ID3=id3.ID3)
            set_id3_tags(audio)

        def bit_rate_str(bit_rate):
            brs = "%d kb/s" % bit_rate
            if not args.cbr:
                brs = "~" + brs
            return brs

        def mode_str(mode):
            modes = ["Stereo", "Joint Stereo", "Dual Channel", "Mono"]
            if mode < len(modes):
                return modes[mode]
            else:
                return ""

        def channel_str(num):
            channels = ["", "Mono", "Stereo"]
            if num < len(channels):
                return channels[num]
            else:
                return ""

        # log id3 tags
        print("-" * 79)
        print(Fore.YELLOW + "Setting artist: " + artist + Fore.RESET)
        if album is not None:
            print(Fore.YELLOW + "Setting album: " + album + Fore.RESET)
        print(Fore.YELLOW + "Setting title: " + title + Fore.RESET)
        print(Fore.YELLOW + "Setting track info: (" +
              str(track.index) + ", " + str(num_tracks) + ")" + Fore.RESET)
        print(Fore.YELLOW + "Setting disc info: (" + str(track.disc) +
              ", " + str(num_discs) + ")" + Fore.RESET)
        print(Fore.YELLOW + "Setting release year: " +
              str(track.album.year) + Fore.RESET)
        if genres is not None and genres:
            print(Fore.YELLOW + "Setting genres: " +
                  " / ".join(genres_ascii) + Fore.RESET)
        if image is not None:
            print(Fore.YELLOW + "Adding cover image" + Fore.RESET)
        if args.comment is not None:
            print(Fore.YELLOW + "Adding comment: " + comment_ascii +
                  Fore.RESET)
        if args.grouping is not None:
            print(Fore.YELLOW + "Adding grouping: " + grouping_ascii +
                  Fore.RESET)
        if args.output_type == "flac":
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print("Time: " + format_time(audio.info.length) +
                  "\tFree Lossless Audio Codec" +
                  "\t[ " + bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) +
                  " Hz - " + channel_str(audio.info.channels) + " ]")
            print("-" * 79)
            print(Fore.YELLOW + "Writing Vorbis comments - " +
                  audio.tags.vendor + Fore.RESET)
            print("-" * 79)
        if args.output_type == "alac.m4a":
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print("Time: " + format_time(audio.info.length) +
                  "\tApple Lossless" +
                  "\t[ " + bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) +
                  " Hz - " + channel_str(audio.info.channels) + " ]")
            print("-" * 79)
            print(Fore.YELLOW + "Writing Apple iTunes metadata - " +
                  Fore.RESET)
            print("-" * 79)
        elif args.output_type == "ogg":
            print("Time: " + format_time(audio.info.length) +
                  "\tOgg Vorbis Codec" +
                  "\t[ " + bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) +
                  " Hz - " + channel_str(audio.info.channels) + " ]")
            print("-" * 79)
            print(Fore.YELLOW + "Writing Vorbis comments - " +
                  audio.tags.vendor + Fore.RESET)
            print("-" * 79)
        elif args.output_type == "opus":
            print("Time: " + format_time(audio.info.length) + "\tOpus Codec" +
                  "\t[ " + channel_str(audio.info.channels) + " ]")
            print("-" * 79)
            print(Fore.YELLOW + "Writing Vorbis comments - " +
                  audio.tags.vendor + Fore.RESET)
            print("-" * 79)
        elif args.output_type == "mp3":
            print("Time: " + format_time(audio.info.length) + "\tMPEG" +
                  str(audio.info.version) +
                  ", Layer " + ("I" * audio.info.layer) + "\t[ " +
                  bit_rate_str(audio.info.bitrate / 1000) +
                  " @ " + str(audio.info.sample_rate) + " Hz - " +
                  mode_str(audio.info.mode) + " ]")
            print("-" * 79)
            id3_version = "v%d.%d" % (
                audio.tags.version[0], audio.tags.version[1])
            print("ID3 " + id3_version + ": " +
                  str(len(audio.tags.values())) + " frames")
            print(
                Fore.YELLOW + "Writing ID3 version " +
                id3_version + Fore.RESET)
            print("-" * 79)
        elif args.output_type == "aac":
            print("Time: " + format_time(audio.info.length) +
                  "\tAdvanced Audio Coding" +
                  "\t[ " + bit_rate_str(audio.info.bitrate / 1000) +
                  " @ " + str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print("-" * 79)
            id3_version = "v%d.%d" % (
                audio.tags.version[0], audio.tags.version[1])
            print("ID3 " + id3_version + ": " +
                  str(len(audio.tags.values())) + " frames")
            print(
                Fore.YELLOW + "Writing ID3 version " +
                id3_version + Fore.RESET)
            print("-" * 79)
        elif args.output_type == "m4a":
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print("Time: " + format_time(audio.info.length) +
                  "\tMPEG-4 Part 14 Audio" +
                  "\t[ " + bit_rate_str(bit_rate / 1000) +
                  " @ " + str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print("-" * 79)
            print(Fore.YELLOW + "Writing Apple iTunes metadata - " +
                  str(audio.info.codec) + Fore.RESET)
            print("-" * 79)

    except id3.error:
        print(Fore.YELLOW + "Warning: exception while saving id3 tag: " +
              str(id3.error) + Fore.RESET)
Пример #6
0
def set_metadata_tags(args, audio_file, idx, track, ripper):
    if args.output_type == "wav" or args.output_type == "pcm":
        print(Fore.YELLOW + "Skipping metadata tagging for " +
              args.output_type + " encoding..." + Fore.RESET)
        return

    # ensure everything is loaded still
    if not track.is_loaded:
        track.load(args.timeout)
    if not track.album.is_loaded:
        track.album.load(args.timeout)
    album_browser = track.album.browse()
    album_browser.load(args.timeout)

    # calculate num of tracks on disc and num of dics
    num_discs = 0
    num_tracks = 0
    for track_browse in album_browser.tracks:
        if (track_browse.disc == track.disc
                and track_browse.index > track.index):
            num_tracks = track_browse.index
        if track_browse.disc > num_discs:
            num_discs = track_browse.disc

    # try to get genres from Spotify's Web API
    genres = None
    if args.genres is not None:
        genres = ripper.web.get_genres(args.genres, track)

    # use mutagen to update id3v2 tags and vorbis comments
    try:
        audio = None
        on_error = 'replace' if args.ascii_path_only else 'ignore'
        album = to_ascii(track.album.name, on_error)
        artists = ", ".join([artist.name for artist in track.artists]) \
            if args.all_artists else track.artists[0].name
        artists_ascii = to_ascii(artists, on_error)
        album_artist = to_ascii(track.album.artist.name, on_error)
        title = to_ascii(track.name, on_error)

        # the comment tag can be formatted
        if args.comment is not None:
            comment = \
                format_track_string(ripper, args.comment, idx, track)
            comment_ascii = to_ascii(comment, on_error)

        if args.grouping is not None:
            grouping = \
                format_track_string(ripper, args.grouping, idx, track)
            grouping_ascii = to_ascii(grouping, on_error)

        if genres is not None and genres:
            genres_ascii = [to_ascii(genre) for genre in genres]

        # cover art image
        image = None
        if args.large_cover_art:
            image = ripper.web.get_large_coverart(track.link.uri)

        # if we fail, use regular cover size
        if image is None:
            image = track.album.cover()
            if image is not None:
                image.load(args.timeout)
                image = image.data

        def tag_to_ascii(_str, _str_ascii):
            return _str if args.ascii_path_only else _str_ascii

        def idx_of_total_str(_idx, _total):
            if _total > 0:
                return "%d/%d" % (_idx, _total)
            else:
                return "%d" % (_idx)

        def save_cover_image(embed_image_func):
            if image is not None:

                def write_image(file_name):
                    cover_path = os.path.dirname(audio_file)
                    cover_file = os.path.join(cover_path, file_name)
                    if not path_exists(cover_file):
                        with open(enc_str(cover_file), "wb") as f:
                            f.write(image)

                if args.cover_file is not None:
                    write_image(args.cover_file)
                elif args.cover_file_and_embed is not None:
                    write_image(args.cover_file_and_embed)
                    embed_image_func(image)
                else:
                    embed_image_func(image)

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

        # aac is not well supported
        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

        def set_vorbis_comments(audio):
            # add Vorbis comment block if it doesn't exist
            if audio.tags is None:
                audio.add_tags()

            def embed_image(data):
                pic = flac.Picture()
                pic.type = 3
                pic.mime = "image/jpeg"
                pic.desc = "Front Cover"
                pic.data = data
                if args.output_type == "flac":
                    audio.add_picture(pic)
                else:
                    data = base64.b64encode(pic.write())
                    audio["METADATA_BLOCK_PICTURE"] = [data.decode("ascii")]

            save_cover_image(embed_image)

            if album is not None:
                audio.tags["ALBUM"] = tag_to_ascii(track.album.name, album)
            audio.tags["TITLE"] = tag_to_ascii(track.name, title)
            audio.tags["ARTIST"] = tag_to_ascii(artists, artists_ascii)
            if album_artist is not None:
                audio.tags["ALBUMARTIST"] = \
                    tag_to_ascii(track.album.artist.name, album_artist)
            audio.tags["DATE"] = str(track.album.year)
            audio.tags["YEAR"] = str(track.album.year)
            audio.tags["DISCNUMBER"] = str(track.disc)
            audio.tags["DISCTOTAL"] = str(num_discs)
            audio.tags["TRACKNUMBER"] = str(track.index)
            audio.tags["TRACKTOTAL"] = str(num_tracks)
            if args.comment is not None:
                audio.tags["COMMENT"] = tag_to_ascii(comment, comment_ascii)
            if args.grouping is not None:
                audio.tags["GROUPING"] = \
                    tag_to_ascii(grouping, grouping_ascii)

            if genres is not None and genres:
                _genres = genres if args.ascii_path_only else genres_ascii
                audio.tags["GENRE"] = ", ".join(_genres)

            audio.save()

        # only called by Python 3
        def set_mp4_tags(audio):
            # add MP4 tags if it doesn't exist
            if audio.tags is None:
                audio.add_tags()

            def embed_image(data):
                audio.tags["covr"] = mp4.MP4Cover(data)

            save_cover_image(embed_image)

            if album is not None:
                audio.tags["\xa9alb"] = tag_to_ascii(track.album.name, album)
            audio["\xa9nam"] = tag_to_ascii(track.name, title)
            audio.tags["\xa9ART"] = tag_to_ascii(artists, artists_ascii)
            if album_artist is not None:
                audio.tags["aART"] = \
                    tag_to_ascii(track.album.artist.name, album_artist)
            audio.tags["\xa9day"] = str(track.album.year)
            audio.tags["disk"] = [(track.disc, num_discs)]
            audio.tags["trkn"] = [(track.index, num_tracks)]
            if args.comment is not None:
                audio.tags["\xa9cmt"] = tag_to_ascii(comment, comment_ascii)
            if args.grouping is not None:
                audio.tags["\xa9grp"] = tag_to_ascii(grouping, grouping_ascii)

            if genres is not None and genres:
                _genres = genres if args.ascii_path_only else genres_ascii
                audio.tags["\xa9gen"] = ", ".join(_genres)

            audio.save()

        def set_m4a_tags(audio):
            # add M4A tags if it doesn't exist
            audio.add_tags()

            def embed_image(data):
                audio.tags[str("covr")] = m4a.M4ACover(data)

            save_cover_image(embed_image)

            if album is not None:
                audio.tags[b"\xa9alb"] = tag_to_ascii(track.album.name, album)
            audio[b"\xa9nam"] = tag_to_ascii(track.name, title)
            audio.tags[b"\xa9ART"] = tag_to_ascii(artists, artists_ascii)
            if album_artist is not None:
                audio.tags[str("aART")] = tag_to_ascii(track.album.artist.name,
                                                       album_artist)
            audio.tags[b"\xa9day"] = str(track.album.year)
            audio.tags[str("disk")] = (track.disc, num_discs)
            audio.tags[str("trkn")] = (track.index, num_tracks)
            if args.comment is not None:
                audio.tags[b"\xa9cmt"] = tag_to_ascii(comment, comment_ascii)
            if args.grouping is not None:
                audio.tags[b"\xa9grp"] = tag_to_ascii(grouping, grouping_ascii)

            if genres is not None and genres:
                _genres = genres if args.ascii_path_only else genres_ascii
                audio.tags[b"\xa9gen"] = ", ".join(_genres)

            audio.save()

        if args.output_type == "flac":
            audio = flac.FLAC(audio_file)
            set_vorbis_comments(audio)
        if args.output_type == "aiff":
            audio = aiff.AIFF(audio_file)
            set_id3_tags(audio)
        elif args.output_type == "ogg":
            audio = oggvorbis.OggVorbis(audio_file)
            set_vorbis_comments(audio)
        elif args.output_type == "opus":
            audio = oggopus.OggOpus(audio_file)
            set_vorbis_comments(audio)
        elif args.output_type == "aac":
            audio = aac.AAC(audio_file)
            set_id3_tags_raw(audio, audio_file)
        elif args.output_type == "m4a":
            audio = mp4.MP4(audio_file)
            set_mp4_tags(audio)
        elif args.output_type == "alac.m4a":
            audio = mp4.MP4(audio_file)
            set_mp4_tags(audio)
        elif args.output_type == "mp3":
            audio = mp3.MP3(audio_file, ID3=id3.ID3)
            set_id3_tags(audio)

        def bit_rate_str(bit_rate):
            brs = "%d kb/s" % bit_rate
            if not args.cbr:
                brs = "~" + brs
            return brs

        def mode_str(mode):
            modes = ["Stereo", "Joint Stereo", "Dual Channel", "Mono"]
            if mode < len(modes):
                return modes[mode]
            else:
                return ""

        def channel_str(num):
            channels = ["", "Mono", "Stereo"]
            if num < len(channels):
                return channels[num]
            else:
                return ""

        # log id3 tags
        print(Fore.YELLOW + "  Artist:\t" + Fore.RESET + artists_ascii)
        if album is not None:
            print(Fore.YELLOW + "  Album:\t" + Fore.RESET + album)
        if album_artist is not None:
            print(Fore.YELLOW + "  Album artist:\t" + Fore.RESET +
                  album_artist)
        print(Fore.YELLOW + "  Title:\t" + Fore.RESET + title)
        print(Fore.YELLOW + "  Track number:\t" + Fore.RESET +
              str(track.index) + "/" + str(num_tracks))
        print(Fore.YELLOW + "  Disc number:\t" + Fore.RESET + str(track.disc) +
              "/" + str(num_discs))
        print(Fore.YELLOW + "  Year:\t\t" + Fore.RESET + str(track.album.year))
        if genres is not None and genres:
            print(Fore.YELLOW + "  Genres:\t" + Fore.RESET +
                  " / ".join(genres_ascii))
        if image is not None:
            print(Fore.YELLOW + "  Cover image:\t" + Fore.RESET + "Yes")
        if args.comment is not None:
            print(Fore.YELLOW + "  Comment:\t" + Fore.RESET + comment_ascii)
        if args.grouping is not None:
            print(Fore.YELLOW + "  Grouping:\t" + Fore.RESET + grouping_ascii)
        print(Fore.YELLOW + "  Time:\t\t" + Fore.RESET +
              format_time(audio.info.length))
        print(Fore.YELLOW + "  Size:\t\t" + Fore.RESET +
              format_size(os.stat(enc_str(audio_file))[ST_SIZE]))

        if args.output_type == "flac":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET +
                  "Free Lossless Audio Codec")
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels))
            print(Fore.YELLOW + "  Comment:\t" + Fore.RESET +
                  audio.tags.vendor)

        if args.output_type == "aiff":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET +
                  "Audio Interchange File Format")
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels))
            id3_version = "v%d.%d" % (audio.tags.version[0],
                                      audio.tags.version[1])
            print(Fore.YELLOW + "  ID3:\t\t" + Fore.RESET + id3_version +
                  " - " + str(len(audio.tags.values())) + " frames")

        elif args.output_type == "alac.m4a":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET + "Apple Lossless")
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels))
            print(Fore.YELLOW + "  iTunes:\t" + Fore.RESET +
                  str(audio.info.codec))

        elif args.output_type == "ogg":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET +
                  "Ogg Vorbis Codec")
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels))
            print(Fore.YELLOW + "  Comment:\t" + Fore.RESET +
                  audio.tags.vendor)

        elif args.output_type == "opus":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET + "Opus Codec")
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  channel_str(audio.info.channels))
            print(Fore.YELLOW + "  Comment:\t" + Fore.RESET +
                  audio.tags.vendor)

        elif args.output_type == "mp3":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET + "MPEG" +
                  str(audio.info.version) + ", Layer " +
                  ("I" * audio.info.layer))
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  mode_str(audio.info.mode))
            id3_version = "v%d.%d" % (audio.tags.version[0],
                                      audio.tags.version[1])
            print(Fore.YELLOW + "  ID3:\t\t" + Fore.RESET + id3_version +
                  " - " + str(len(audio.tags.values())) + " frames")

        elif args.output_type == "aac":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET +
                  "Advanced Audio Coding")
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels))
            id3_version = "v%d.%d" % (audio.tags.version[0],
                                      audio.tags.version[1])
            print(Fore.YELLOW + "  ID3:\t\t" + Fore.RESET + id3_version +
                  " - " + str(len(audio.tags.values())) + " frames")

        elif args.output_type == "m4a":
            print(Fore.YELLOW + "  Format:\t" + Fore.RESET +
                  "MPEG-4 Part 14 Audio")
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print(Fore.YELLOW + "  Quality:\t" + Fore.RESET +
                  bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels))
            print(Fore.YELLOW + "  iTunes:\t" + Fore.RESET +
                  str(audio.info.codec))

    except id3.error:
        print(Fore.YELLOW + "Warning: exception while saving id3 tag: " +
              str(id3.error) + Fore.RESET)
Пример #7
0
def set_metadata_tags(args, audio_file, idx, track, ripper):
    # log completed file
    print(Fore.GREEN + Style.BRIGHT + os.path.basename(audio_file) +
          Style.NORMAL + "\t[ " +
          format_size(os.stat(enc_str(audio_file))[ST_SIZE]) + " ]" +
          Fore.RESET)

    if args.output_type == "wav" or args.output_type == "pcm":
        print_yellow("Skipping metadata tagging for " + args.output_type +
                     " encoding...")
        return

    # ensure everything is loaded still
    if not track.is_loaded:
        track.load(args.timeout)
    if not track.album.is_loaded:
        track.album.load(args.timeout)

    # use mutagen to update audio file tags
    try:
        audio = None
        tags = None

        if args.output_type == "flac":
            audio = flac.FLAC(audio_file)
            tags = VorbisTags(args, audio_file, idx, track, ripper)
            tags.set_tags(audio)

        elif args.output_type == "aiff":
            audio = aiff.AIFF(audio_file)
            tags = Id3Tags(args, audio_file, idx, track, ripper)
            tags.set_tags(audio)

        elif args.output_type == "ogg":
            audio = oggvorbis.OggVorbis(audio_file)
            tags = VorbisTags(args, audio_file, idx, track, ripper)
            tags.set_tags(audio)

        elif args.output_type == "opus":
            audio = oggopus.OggOpus(audio_file)
            tags = VorbisTags(args, audio_file, idx, track, ripper)
            tags.set_tags(audio)

        elif args.output_type == "aac":
            audio = aac.AAC(audio_file)
            tags = RawId3Tags(args, audio_file, idx, track, ripper)
            tags.set_tags(audio)

        elif args.output_type == "m4a" or args.output_type == "alac.m4a":
            if sys.version_info >= (3, 0):
                audio = mp4.MP4(audio_file)
                tags = MP4Tags(args, audio_file, idx, track, ripper)
                tags.set_tags(audio)
            else:
                audio = m4a.M4A(audio_file)
                tags = M4ATags(args, audio_file, idx, track, ripper)
                tags.set_tags(audio)
                audio = mp4.MP4(audio_file)

        elif args.output_type == "mp3":
            audio = mp3.MP3(audio_file, ID3=id3.ID3)
            tags = Id3Tags(args, audio_file, idx, track, ripper)
            tags.set_tags(audio)

        # utility functions
        def bit_rate_str(bit_rate):
            brs = "%d kb/s" % bit_rate
            if not args.cbr:
                brs = "~" + brs
            return brs

        def mode_str(mode):
            modes = ["Stereo", "Joint Stereo", "Dual Channel", "Mono"]
            return modes[mode] if mode < len(modes) else ""

        def channel_str(num):
            channels = ["", "Mono", "Stereo"]
            return channels[num] if num < len(channels) else ""

        def print_line():
            print("-" * 79)

        # log tags
        print_line()
        print_yellow("Setting artist: " + tags.artists())

        if tags.album() is not None:
            print_yellow("Setting album: " + tags.album())

        if tags.album_artist() is not None:
            print_yellow("Setting album artist: " + tags.album_artist())

        print_yellow("Setting title: " + tags.title())
        print_yellow("Setting track info: (" + tags.track_idx() + ", " +
                     tags.num_tracks() + ")")
        print_yellow("Setting disc info: (" + tags.disc_idx() + ", " +
                     tags.num_discs() + ")")
        print_yellow("Setting release year: " + tags.year())

        if tags.genres() is not None:
            print_yellow("Setting genres: " + " / ".join(tags.genres()))

        if tags.image is not None:
            print_yellow("Adding cover image")

        if tags.comment() is not None:
            print_yellow("Adding comment: " + tags.comment())

        if tags.grouping() is not None:
            print_yellow("Adding grouping: " + tags.grouping())

        # log bitrate info
        if args.output_type == "flac":
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print("Time: " + format_time(audio.info.length) +
                  "\tFree Lossless Audio Codec" + "\t[ " +
                  bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print_line()
            print_yellow("Writing Vorbis comments - " + audio.tags.vendor)
            print_line()

        elif args.output_type == "aiff":
            print("Time: " + format_time(audio.info.length) +
                  "\tAudio Interchange File Format" + "\t[ " +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print_line()
            id3_version = "v%d.%d" % (audio.tags.version[0],
                                      audio.tags.version[1])
            print("ID3 " + id3_version + ": " + str(len(audio.tags.values())) +
                  " frames")
            print(Fore.YELLOW + "Writing ID3 version " + id3_version)
            print_line()

        elif args.output_type == "alac.m4a":
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print("Time: " + format_time(audio.info.length) +
                  "\tApple Lossless" + "\t[ " + bit_rate_str(bit_rate / 1000) +
                  " @ " + str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print_line()
            print_yellow("Writing Apple iTunes metadata")
            print_line()

        elif args.output_type == "ogg":
            print("Time: " + format_time(audio.info.length) +
                  "\tOgg Vorbis Codec" + "\t[ " +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print_line()
            print_yellow("Writing Vorbis comments - " + audio.tags.vendor)
            print_line()

        elif args.output_type == "opus":
            print("Time: " + format_time(audio.info.length) + "\tOpus Codec" +
                  "\t[ " + channel_str(audio.info.channels) + " ]")
            print_line()
            print_yellow("Writing Vorbis comments - " + audio.tags.vendor)
            print_line()

        elif args.output_type == "mp3":
            print("Time: " + format_time(audio.info.length) + "\tMPEG" +
                  str(audio.info.version) + ", Layer " +
                  ("I" * audio.info.layer) + "\t[ " +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  mode_str(audio.info.mode) + " ]")
            print_line()
            id3_version = "v%d.%d" % (audio.tags.version[0],
                                      audio.tags.version[1])
            print("ID3 " + id3_version + ": " + str(len(audio.tags.values())) +
                  " frames")
            print_yellow("Writing ID3 version " + id3_version)
            print_line()

        elif args.output_type == "aac":
            print("Time: " + format_time(audio.info.length) +
                  "\tAdvanced Audio Coding" + "\t[ " +
                  bit_rate_str(audio.info.bitrate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print_line()
            id3_version = "v%d.%d" % (audio.tags.version[0],
                                      audio.tags.version[1])
            print("ID3 " + id3_version + ": " + str(len(audio.tags.values())) +
                  " frames")
            print("Writing ID3 version " + id3_version)
            print_line()

        elif args.output_type == "m4a":
            bit_rate = ((audio.info.bits_per_sample * audio.info.sample_rate) *
                        audio.info.channels)
            print("Time: " + format_time(audio.info.length) +
                  "\tMPEG-4 Part 14 Audio" + "\t[ " +
                  bit_rate_str(bit_rate / 1000) + " @ " +
                  str(audio.info.sample_rate) + " Hz - " +
                  channel_str(audio.info.channels) + " ]")
            print_line()
            print_yellow("Writing Apple iTunes metadata - " +
                         str(audio.info.codec))
            print_line()

    except id3.error:
        print_yellow("Warning: exception while saving id3 tag: " +
                     str(id3.error))