예제 #1
0
 def clearInternalTags(self, album):
     # We could use audioTag.delete() but we just want to clear the tags supported by convention
     if self.fileType == 'MP3':
         self.audioTag.add(TIT2(text=''))
         self.audioTag.add(TDRC(text=''))
         self.audioTag.add(TPE1(text=''))
         self.audioTag.add(TPE2(text=''))
         self.audioTag.add(TOPE(text=''))
         self.audioTag.add(TRCK(text=''))
         self.audioTag.add(TALB(text=''))
         self.audioTag.add(TPOS(text=''))
         self.audioTag.add(TCMP(text=''))
     elif self.fileType == 'FLAC':
         self.audioTag['TITLE'] = ''
         self.audioTag['DATE'] = ''
         self.audioTag['ALBUM'] = ''
         self.audioTag['ARTIST'] = ''
         self.audioTag['ALBUMARTIST'] = ''
         self.audioTag['PERFORMER'] = ''
         self.audioTag['TRACKNUMBER'] = ''
         self.audioTag['DISCNUMBER'] = ''
         self.audioTag['TRACKTOTAL'] = ''
         self.audioTag['TOTALTRACK'] = ''
         self.audioTag['TOTALTRACKS'] = ''
         self.audioTag['DISCTOTAL'] = ''
         self.audioTag['TOTALDISC'] = ''
         self.audioTag['TOTALDISCS'] = ''
         self.audioTag['COMPILATION'] = ''
         self.audioTag['RELEASEDATE'] = ''
         self.audioTag.clear_pictures()
     self.audioTag.save(self.audioTagPath)
예제 #2
0
 def setInternalTags(self, album):
     # Compilation tag is '0' for regular release, '1' for various artist and '2' for mixes
     compilation = '0'
     default = '<fill me>'
     # Since record company must contain this string, we then admit its a compilation
     if ' Records' in album.albumArtist:
         compilation = '1'
     if self.fileType == 'FLAC':
         if len(self.fileNameList) == 6:  # Avoid range exception
             self._buildArtistsList()
             self._buildPerformersList()
             self._addCoverToFile(album)
             # Append tag by tag o the track
             if self.fileNameList[5] is not None:
                 self._setInternalTag('TITLE', self.fileNameList[5][:-5],
                                      default)
         if album.year is not None:
             self._setInternalTag('DATE', str(album.year), '1900')
         else:
             self._setInternalTag('DATE', '1900')
         if self.artists is not None:
             self._setInternalTag('ARTIST', '; '.join(self.artists),
                                  default)
         else:
             self._setInternalTag('ARTIST', default)
         if album.albumArtist is not None:
             self._setInternalTag('ALBUMARTIST', album.albumArtist, default)
         else:
             self._setInternalTag('ALBUMARTIST', default)
         if self.performers is not None:
             self._setInternalTag('PERFORMER', '; '.join(self.performers),
                                  default)
         else:
             self._setInternalTag('PERFORMER', default)
         if len(self.fileNameList
                ) == 6 and self.fileNameList[3] is not None:
             self._setInternalTag('TRACKNUMBER',
                                  str(self.fileNameList[3][1:]).lstrip('0'),
                                  '0')
         else:
             self._setInternalTag('TRACKNUMBER', '0')
         if album.totalTrack is not None:
             self._setInternalTag('TRACKTOTAL', str(album.totalTrack), '0')
         else:
             self._setInternalTag('TRACKTOTAL', '0')
         if len(self.folderNameList
                ) == 2 and self.folderNameList[1] is not None:
             self._setInternalTag('ALBUM', self.folderNameList[1], default)
         else:
             self._setInternalTag('ALBUM', default)
         if album.totalDisc is not None:
             self._setInternalTag('DISCTOTAL', str(album.totalDisc), '0')
         else:
             self._setInternalTag('DISCTOTAL', '0')
         if len(self.fileNameList
                ) == 6 and self.fileNameList[3] is not None:
             self._setInternalTag('DISCNUMBER',
                                  str(self.fileNameList[3][0]), '0')
         else:
             self._setInternalTag('DISCNUMBER', '0')
         # No need for test value as compilation is built locally (only for regular(0)/compilation(1), not live(2)/mix(3))
         self._setInternalTag('COMPILATION', compilation, '-1')
         # Create fields with default value to fasten manual tagging
         self._setInternalTag('COMPOSER', default)
         self._setInternalTag('LANGUAGE', default)
         self._setInternalTag('PRODUCER', default)
         self._setInternalTag(
             'LABEL', default
         )  # May be overwritten in _fillTagsFromPreviouslyExistingTag()
         # Release date
         if len(album.folderNameList[0]) > 4:
             self._setInternalTag('RELEASEDATE', album.folderNameList[0],
                                  '1900-01-01')
         else:
             self._setInternalTag('RELEASEDATE',
                                  '{}-01-01'.format(album.year),
                                  '1900-01-01')
         # If other tags were previously filled, try to integrate them according to the tagging convention
         self._fillTagsFromPreviouslyExistingTag()
     elif self.fileType == 'MP3':
         if len(self.fileNameList) == 6:  # Avoid range exception
             self._buildArtistsList()
             self._buildPerformersList()
             self._addCoverToFile(album)
             # Append tag by tag on the track
             if self.fileNameList[5] is not None:  # Track title
                 self.audioTag.add(TIT2(text=self.fileNameList[5]
                                        [:-4]))  # -4 for '.mp3' string
         if self.artists is not None:  # Artist
             self.audioTag.add(TPE1(text='; '.join(self.artists)))
         if album.albumArtist is not None:  # Album artist
             self.audioTag.add(TPE2(text=album.albumArtist))
         if len(
                 self.folderNameList
         ) == 2 and self.folderNameList[1] is not None:  # Album title
             self.audioTag.add(TALB(text=self.folderNameList[1]))
         if album.year is not None:  # Year
             self.audioTag.add(TDRC(text=str(album.year)))
         if self.performers is not None:  # Performer (original artist)
             self.audioTag.add(TOPE(text='; '.join(self.performers)))
         if len(self.fileNameList) == 6 and self.fileNameList[
                 3] is not None and album.totalTrack is not None:  # track N°/track total
             self.audioTag.add(
                 TRCK(text=str(self.fileNameList[3][1:]).lstrip('0') + '/' +
                      str(album.totalTrack)))
         if len(self.fileNameList) == 6 and self.fileNameList[
                 3] is not None and album.totalDisc is not None:  # disc N°/disc total
             self.audioTag.add(
                 TPOS(text=str(self.fileNameList[3][0]) + '/' +
                      str(album.totalDisc)))
         self.audioTag.add(TCMP(text=compilation))  # Compilation
         self.audioTag.add(TPUB(text=default))  # Producer
         self.audioTag.add(TCOP(text=default))  # Label
         self.audioTag.add(TCOM(text=default))  # Composer
         self.audioTag.add(TLAN(text=default))  # Language
         # Release date
         if len(album.folderNameList[0]) > 4:
             self.audioTag.add(TDOR(text=album.folderNameList[0]))
         else:
             self.audioTag.add(TDOR(text='{}-01-01'.format(album.year)))
     # Now save all the new tags into the audio file
     self.audioTag.save(self.audioTagPath)
예제 #3
0
def save_song_attrs_to_id3tags(tags, song):
    # - APIC: Artwork
    if song.artwork:
        tags["APIC"] = APIC(
            encoding=3,  # 3 is for utf-8
            mime='image/jpeg',  # image/jpeg or image/png
            type=3,  # 3 is for the cover image
            desc=u'Cover',
            data=song.artwork.read())

    # - TIT2: Song Title
    if song.title:
        tags["TIT2"] = TIT2(encoding=3,
                            text=song.title.decode('unicode-escape'))

    # - TPE1: Artist
    if song.artist:
        tags["TPE1"] = TPE1(encoding=3,
                            text=song.artist.decode('unicode-escape'))

    # - TDRC: Year
    if song.year:
        tags["TDRC"] = TDRC(encoding=3,
                            text=str(song.year).decode('unicode-escape'))

    # - TALB: Album
    if song.album:
        tags["TALB"] = TALB(encoding=3,
                            text=song.album.decode('unicode-escape'))

    #: Release date?
    # release_date =

    # - TPE2: Album artist
    if song.album_artist:
        tags["TPE2"] = TPE2(encoding=3,
                            text=song.album_artist.decode('unicode-escape'))

    # - TRCK: Track number
    if song.track_number:
        tags["TRCK"] = TRCK(encoding=3,
                            text=str(
                                song.track_number).decode('unicode-escape'))

    # - TBPM: BPM
    if song.bpm:
        tags["TBPM"] = TBPM(encoding=3,
                            text=str(song.bpm).decode('unicode-escape'))

    # - TOPE: Original artist
    if song.original_artist:
        tags["TOPE"] = TOPE(encoding=3,
                            text=song.original_artist.decode('unicode-escape'))

    # - TKEY: Key
    if song.key:
        tags["TKEY"] = TKEY(encoding=3, text=song.key.decode('unicode-escape'))

    # - TCOM: Composer
    if song.composer:
        tags["TCOM"] = TCOM(encoding=3,
                            text=song.composer.decode('unicode-escape'))

    # - TEXT: Lyricist
    if song.lyricist:
        tags["TEXT"] = TEXT(encoding=3,
                            text=song.lyricist.decode('unicode-escape'))

    # - COMM: Comments
    if song.comments:
        tags["COMM"] = COMM(encoding=3,
                            text=song.comments.decode('unicode-escape'))

    # - TPE4: Remixer
    if song.remixer:
        tags["TPE4"] = TPE4(encoding=3,
                            text=song.remixer.decode('unicode-escape'))

    # - TPUB: Label/Publisher
    if song.label:
        tags["TPUB"] = TPUB(encoding=3,
                            text=song.label.decode('unicode-escape'))

    # - TCON: Genre/content type
    if song.genre:
        tags["TCON"] = TCON(encoding=3,
                            text=song.genre.decode('unicode-escape'))

    if song.lyrics:
        tags["USLT"] = USLT(encoding=3,
                            text=song.lyrics.decode('unicode-escape'))
예제 #4
0
def updateFileMetadata(track, tags):
    if track.location.endswith(".mp3"):
        # Check if the file has a tag header
        audioTag = ID3()
        if tags.trackTitle is not None:
            audioTag.add(TIT2(text=tags.trackTitle))
        if tags.trackYear is not None:
            audioTag.add(TDRC(text=str(tags.trackYear)))
        if tags.trackArtist is not None:
            audioTag.add(TPE1(text=tags.trackArtist))
        if tags.trackPerformer is not None:
            audioTag.add(TOPE(text=tags.trackPerformer))
        if tags.trackComposer is not None:
            audioTag.add(TCOM(text=tags.trackComposer))
        if tags.trackNumber is not None:
            if tags.albumTotalTrack is not None:
                audioTag.add(
                    TRCK(text=str(tags.trackNumber) + "/" +
                         str(tags.albumTotalTrack)))
            else:
                audioTag.add(TRCK(text=str(tags.trackNumber)))
        if tags.trackBPM is not None:
            audioTag.add(TBPM(text=str(tags.trackBPM)))
        if tags.lyrics is not None:
            audioTag.add(USLT(text=tags.lyrics))
        if tags.trackGenre is not None:
            audioTag.add(TCON(text=tags.trackGenre))
        if tags.albumTitle is not None:
            audioTag.add(TALB(text=tags.albumTitle))
        if tags.albumArtist is not None:
            audioTag.add(TPE1(text=tags.albumArtist))
        if tags.albumTotalDisc is not None:
            audioTag.add(TXXX(desc="TOTALDISCS", text=[tags.albumTotalDisc]))
        if tags.comment is not None:
            audioTag.add(COMM(text=tags.comment))
        if tags.albumDiscNumber is not None:
            audioTag.add(TPOS(text=str(tags.albumDiscNumber)))
        if tags.cover is not None:
            audioTag.add(APIC(data=tags.cover, type=3))
        audioTag.save(track.location)
        data = errorCheckMessage(True, None, updateFileMetadata)
    elif track.location.endswith(".flac"):
        audioTag = FLAC(track.location)
        if tags.trackTitle is not None:
            audioTag["TITLE"] = tags.trackTitle
        if tags.trackYear is not None:
            audioTag['DATE'] = str(tags.trackYear)
        if tags.trackArtist is not None:
            audioTag['ARTIST'] = tags.trackArtist
        if tags.trackPerformer is not None:
            audioTag['PERFORMER'] = tags.trackPerformer
        if tags.trackComposer is not None:
            audioTag['COMPOSER'] = tags.trackComposer
        if tags.trackNumber is not None:
            audioTag['TRACKNUMBER'] = str(tags.trackNumber)
        if tags.albumTotalTrack is not None:
            audioTag['TOTALTRACK'] = str(tags.albumTotalTrack)
        if tags.trackBPM is not None:
            audioTag['BPM'] = tags.trackBPM
        if tags.lyrics is not None:
            audioTag['LYRICS'] = tags.lyrics
        if tags.trackGenre is not None:
            audioTag['GENRE'] = tags.trackGenre
        if tags.albumTitle is not None:
            audioTag['ALBUM'] = tags.albumTitle
        if tags.albumArtist is not None:
            audioTag['ARTIST'] = tags.albumArtist
        if tags.albumTotalDisc is not None:
            audioTag['TOTALDISC'] = str(tags.albumTotalDisc)
        if tags.albumDiscNumber is not None:
            audioTag['DISCNUMBER'] = str(tags.albumDiscNumber)
        if tags.comment is not None:
            audioTag['COMMENT'] = str(tags.comment)
        if tags.cover is not None:
            picture = audioTag.pictures
            picture[0].data = tags.cover
        audioTag.save(track.location)
        data = errorCheckMessage(True, None, updateFileMetadata)
    else:
        data = errorCheckMessage(False, ErrorEnum.FORMAT_ERROR,
                                 updateFileMetadata)
    return data
예제 #5
0
    def download(self,
                 location: str = "downloads/",
                 file_name: str = None,
                 use_better_file_name: bool = True,
                 use_album_data: bool = True,
                 artwork_url: str = None,
                 artwork_crop_to_square: bool = True) -> None:
        """
        Download the stream

        .. note::
            When downloading a stream, it also attempts to download metadata and album artwork for it. The artists is
            the username user who uploaded the track, the title is the track title on SoundCloud and the artwork is
            whatever is provided with the track. It also does a quick check to see if the track appears in any albums.
            If it does, then it gets the first album and then gets album info and artwork from there instead.

        :param location: The location to download the stream to
        :param file_name: The name of the file
        :param use_better_file_name: If no file name specified, create one using the username and track title?
        :param use_album_data: Use the data of the first album that the track is in
        :param artwork_url: The url of the artwork to use
        :param artwork_crop_to_square: Should the artwork be cropped to a square? (Not currently used)
        :return: None
        """
        if (self.client_id is not None):
            response = requests.get(self.url, stream=True)
            if (response.status_code != 200):
                print(
                    f"Error: Could not download the file. (Status code {response.status_code})"
                )
                return
            download_url = response.json()["url"]
            if (file_name is None):
                file_name = re.search(r"[a-zA-Z0-9\-]*\.[0-9]+\.(mp3|opus)",
                                      download_url).group()
                if (use_better_file_name and self.track_data is not None
                        and self.track_data.track_artists is not None
                        and self.track_data.track_title is not None):
                    extension = file_name.split(".")[-1]
                    file_name = "{} - {}.{}".format(
                        self.track_data.track_artists[0],
                        self.track_data.track_title, extension)
            file_name = SoundCloudStream.sanitize_file_name(file_name)
            if (not os.path.exists(location)):
                os.mkdir(location)
            output_location = os.path.join(location, file_name)
            http = urllib3.PoolManager()
            with http.request('GET', download_url,
                              preload_content=False) as r, open(
                                  output_location, 'wb') as out_file:
                shutil.copyfileobj(r, out_file)
            try:
                tags = ID3(output_location)
            except Exception:
                tags = ID3()

            if (self.track_data is not None):
                # tags["TIT1"] = TIT1(encoding=3, text="Group description")
                if (self.track_data.track_title is not None):
                    tags["TIT2"] = TIT2(encoding=3,
                                        text=self.track_data.track_title)
                if (self.track_data.track_subtitle is not None):
                    tags["TIT3"] = TIT3(encoding=3, text=self.track_data)
                if (self.track_data.track_comments is not None):
                    tags["COMM"] = COMM(encoding=3,
                                        lang=u"eng",
                                        desc=self.track_data.track_comments)
                if (self.track_data.track_artists is not []):
                    tags["TPE1"] = TPE1(encoding=3,
                                        text=self.track_data.track_artists[0])
                if (self.track_data.album_artist is not None):
                    tags["TPE2"] = TPE2(encoding=3,
                                        text=self.track_data.album_artist)
                if (self.track_data.album_title is not None):
                    tags["TALB"] = TALB(encoding=3,
                                        text=self.track_data.album_title)
                if (self.track_data.album_year is not None):
                    tags["TDRC"] = TDRC(encoding=3,
                                        text=str(self.track_data.album_year))
                if (self.track_data.track_number is not None):
                    tags["TRCK"] = TRCK(encoding=3,
                                        text="{}/0".format(
                                            self.track_data.track_number))
                if (self.track_data.genre is not None):
                    tags["TCON"] = TCON(encoding=3, text=self.track_data.genre)
                if (self.track_data.album_artwork_url is not None):
                    url = self.track_data.album_artwork_url.replace(
                        "large", "t500x500")
                    with http.request("GET", url, preload_content=False) as r,\
                            open(output_location + ".jpg", "wb") as out_file:
                        shutil.copyfileobj(r, out_file)
                    with open(output_location + ".jpg", "rb") as album_art:
                        tags["APIC"] = APIC(encoding=3,
                                            mime="image/jpeg",
                                            type=3,
                                            desc=u"cover",
                                            data=album_art.read())
                    os.remove(output_location + ".jpg")

            tags.save(output_location)
        else:
            print("Error: No client ID provided")