def _set_tag(self, f, name, value): if type(value) is not list: value = [value] if name in ['trkn', 'disk']: try: f[name] = [] for val in value: tmp = map(int, val.split('/')) f[name].append(tuple(tmp)) except (TypeError, ValueError): pass elif name == 'covr': f[name] = [] for val in value: if val.mime == 'image/jpeg': f[name].append( mp4.MP4Cover(val.data, mp4.MP4Cover.FORMAT_JPEG)) elif val.mime == 'image/png': f[name].append( mp4.MP4Cover(val.data, mp4.MP4Cover.FORMAT_JPEG)) else: raise ValueError( 'MP4 does not support cover image type %s' % val.type) elif name == 'tmpo': f[name] = [int(v) for v in value] elif name == '----:com.apple.iTunes:ORIGYEAR': f[name] = [str(v) for v in value] else: f[name] = value
def _downloadAudio(self, video): filepath = os.environ.get( 'HOME') + '/Downloads/YouTubePlayer/' + video.title + '[audio].m4a' audio = video.m4astreams[-1] try: audio.download( filepath, quiet=False, callback=self._setdownloadETA) except FileNotFoundError: os.makedirs(os.environ.get('HOME') + '/Downloads/YouTubePlayer') audio.getbestaudio(preftype="m4a").download( filepath, quiet=False, callback=self._setdownloadETA) metadata = self._getMetadata(video) if metadata is None: return self.infoLabel.set_text('Fixing metadata') audiofile = mp4.MP4(filepath) audiofile['\xa9nam'] = metadata['track_title'] audiofile['\xa9ART'] = metadata['artist'] audiofile['\xa9alb'] = metadata['album'] audiofile['aART'] = metadata['artist'] cover = metadata['album_art_url'] fd = urllib.request.urlopen(cover) covr = mp4.MP4Cover(fd.read(), getattr(mp4.MP4Cover, 'FORMAT_PNG' if cover.endswith('png') else 'FORMAT_JPEG')) fd.close() audiofile['covr'] = [covr] audiofile.save() self.infoLabel.set_text('Metadata fixed')
def do_one(self, number, fn): bn = os.path.basename(fn) dn = os.path.dirname(fn) result = re.match('(\d*);(.*?);(.*).(m4a)', bn) if not result: print u'bad file name format: {0}'.format(bn) return _, youtube_id, title, ext = result.groups() disk_number = number / self.tracks_per_disk + 1 track_number = number % self.tracks_per_disk + 1 # try to split title to artist - song name result = re.match('(.*) - (.*)', title) if result: artist, song_name = result.groups() else: artist, song_name = '', title f = mp4.MP4(fn) f.tags['trkn'] = [(track_number, self.tracks_per_disk)] f.tags['disk'] = [(disk_number, self.num_disks)] f.tags['cpil'] = True f.tags['\xa9alb'] = [ self.album, ] f.tags['\xa9nam'] = [ song_name, ] f.tags['\xa9ART'] = [ artist, ] f.tags['\xa9gen'] = [ self.genre, ] f.tags['\xa9cmt'] = [ youtube_id, ] jpg_file = os.path.splitext(fn)[0] + '.jpg' with open(jpg_file, 'rb') as h: cover_data = h.read() cover = mp4.MP4Cover(cover_data, mp4.AtomDataType.JPEG) f.tags['covr'] = [ cover, ] f.save() os.unlink(jpg_file) new_fn = os.path.join(dn, title + '.' + ext) try: os.rename(fn, new_fn) except WindowsError as e: print u'cannot rename {0}'.format(number) print u'error {0}: {1}'.format(e.args[0], e.args[1]) self.xl.add_song(number, youtube_id, title, song_name, artist)
def _savePic(self, coverPath): data = _getFileData(coverPath) if data is None: return if 'flac' in self._ext: pic = flac.Picture() pic.data = data if pathHelper.getFileExtension(coverPath) == '.jpg': pic.mime = u"image/jpeg" self._handle.clear_pictures() self._handle.add_picture(pic) if 'mp3' in self._ext: self._handle.tags.add(APIC(encoding=3, data=data)) if 'mp4' in self._ext or 'm4a' in self._ext: pic = mp4.MP4Cover(data) self._handle.tags['covr'] = [pic]
def __savePic__(self, coverPath): data = __content__(coverPath) if data is None: return if 'flac' in self._ext: pic = flac.Picture() pic.data = data if '.jpg' in coverPath: pic.mime = u"image/jpeg" self._handle.clear_pictures() self._handle.add_picture(pic) if 'mp3' in self._ext: self._handle.tags.add(APIC(encoding=3, data=data)) if 'mp4' in self._ext or 'm4a' in self._ext: pic = mp4.MP4Cover(data) self._handle.tags['covr'] = [pic]
def _downloadAudio(self, video): print("download audio") download_path = os.environ.get('HOME') + '/Downloads/YouTubePlayer/' if not os.path.exists(download_path): print(download_path, "does not exist") os.makedirs(download_path) filepath = download_path + video.title + '[audio].m4a' audio = video.m4astreams[-1] try: audio.download(filepath, quiet=False, callback=self._setdownloadETA) except DownloadError: GObject.idle_add(self.infoLabel.set_text, "Can't download this video.") return metadata = self._getMetadata(video) if metadata is None: return self.infoLabel.set_text('Fixing metadata') audiofile = mp4.MP4(filepath) audiofile['\xa9nam'] = metadata['track_title'] audiofile['\xa9ART'] = metadata['artist'] audiofile['\xa9alb'] = metadata['album'] audiofile['aART'] = metadata['artist'] cover = metadata['album_art_url'] fd = urllib.request.urlopen(cover) covr = mp4.MP4Cover( fd.read(), getattr(mp4.MP4Cover, 'FORMAT_PNG' if cover.endswith('png') else 'FORMAT_JPEG')) fd.close() audiofile['covr'] = [covr] audiofile.save() self.infoLabel.set_text('Metadata fixed')
def mp4edit(self): """ MP4(m4a)の曲情報を編集 """ # タグ書き換え self.tags['\xa9nam'] = self.title self.tags['\xa9alb'] = self.album self.tags['\xa9ART'] = self.artist self.tags['\xa9gen'] = self.genre self.tags['\xa9cmt'] = self.comment # アートワーク書き換え if not self.artwork_url == '': # 画像読み込み try: artwork_read = urlopen(self.artwork_url).read() except: raise URLOpenError("画像を取得できません") # 画像書き換え # list pic = [mp4.MP4Cover(artwork_read, mp4.MP4Cover.FORMAT_JPEG)] self.tags['covr'] = pic # 保存 self.tags.save(self.filepath) # 表示用アートワーク更新 artworks = self.tags.get('covr') # list or None artwork = None if artworks: for artwork in artworks: # 抽出(最後に登録されている画像のみ) pass # bytesへ変換 if artwork: self.artwork = bytes(artwork)
def setAlbumInfo(album): conn = sqlite3.connect('database/music.db') # print("Connection granted") cur = conn.cursor() conn_settings = sqlite3.connect('database/settings.db') # print("Connection granted") cur_settings = conn_settings.cursor() cur_settings.execute("SELECT music_directory_path FROM music_directory WHERE active='True'") result_directory = cur_settings.fetchone() cur.execute("SELECT album_artist FROM album WHERE album_spotify_id='%s'" % str(album)) result_art_id = cur.fetchone() cur.execute("SELECT artist_name FROM artist WHERE artist_id='%s'" % str(result_art_id[0])) result_art_name = cur.fetchone() cur.execute("SELECT album_name FROM album WHERE album_spotify_id='%s'" % str(album)) result_alb_name = cur.fetchone() cur.execute("SELECT album_id FROM album WHERE album_spotify_id='%s'" % str(album)) result_alb_id = cur.fetchone() cur.execute("SELECT album_number_songs FROM album WHERE album_spotify_id='%s'" % str(album)) result_alb_number_songs = cur.fetchone() print(result_alb_number_songs[0]) cur.execute("SELECT album_coverart FROM album WHERE album_spotify_id='%s'" % str(album)) result_alb_coverart = cur.fetchone() try: coverArtDirectory = "%s%s/cover_art" % (str(result_directory[0]), str(result_art_name[0])) coverArtName = "%s.jpg" % str(result_alb_name[0]) if not os.path.exists(coverArtDirectory): os.makedirs(coverArtDirectory) if coverArtName not in coverArtDirectory: urllib.request.urlretrieve("%s" % str(result_alb_coverart[0]), "%s/%s" % (str(coverArtDirectory), str(coverArtName))) print("Cover Art Downloaded Fine!") directory = "%s%s/%s" % (str(result_directory[0]), str(result_art_name[0]), str(result_alb_name[0])) directoryResults = os.listdir(directory) for re in directoryResults: print("PreCleaned: " + re) cleanResult = re.replace('.m4a', '') print("Cleaned: " + cleanResult) cur.execute("SELECT song_name FROM song WHERE song_album='%s' AND song_name='%s'" % (str(result_alb_id[0]), str(cleanResult))) result_song_name = cur.fetchone() cur.execute("SELECT song_track_number FROM song WHERE song_album='%s' AND song_name='%s'" % (str(result_alb_id[0]), str(cleanResult))) result_song_track_number = cur.fetchone() cur.execute("SELECT song_spotify_id FROM song WHERE song_album='%s' AND song_name='%s'" % (str(result_alb_id[0]), str(cleanResult))) result_song_spotify_id = cur.fetchone() if (result_song_track_number != None): # print(str(result_song_track_number[0])) coverArtLocation = "%s/%s" % (str(coverArtDirectory), str(coverArtName)) song = mutagen.MP4("%s/%s" % (str(directory), str(re))) song['\xa9nam'] = result_song_name[0] song['\xa9alb'] = result_alb_name[0] song['\xa9ART'] = result_art_name[0] song['trkn'] = [(int(result_song_track_number[0]), int(result_alb_number_songs[0]))] with open(coverArtLocation, "rb") as f: song["covr"] = [mutagen.MP4Cover(f.read(), imageformat=mutagen.MP4Cover.FORMAT_JPEG)] song.save() except FileNotFoundError as err: print("Sorry File Not found: {0}".format(err)) # # savedir = "/home/que/Music/MusicLibrary/Artists/%s/%s/" % (str(art_id[0]), str(alb_name[0])) # savename = "%s%s" % (fileName, audioType) conn.close() conn_settings.close()
def embed_image(data): audio.tags["covr"] = mp4.MP4Cover(data)
def __get_tag_image(self, image_file, audio_mime_type): """ The function that returns cover image. :param str image_file: Path to image file :param list audio_mime_type: Mime-Types of image file :return binary image_data: Binary data of image file """ if not os.path.isfile(image_file): return # Create image with open(image_file, 'rb') as f: image_data = f.read() if image_data is None: raise InvalidDataException("Could not create image data.", image_file) image_mime_type = mimetypes.guess_type(image_file)[0] if contains_at_least(audio_mime_type, ['audio/x-mp4', 'audio/x-m4a', 'audio/mp4a-latm']): if image_mime_type == "image/jpeg": image_format = mp4.MP4Cover.FORMAT_JPEG elif image_mime_type == "image/png": image_format = mp4.MP4Cover.FORMAT_PNG else: raise InvalidMimeTypeException("Invalid image format.", image_mime_type) return mp4.MP4Cover(image_data, image_format) elif contains_at_least(audio_mime_type, ['audio/x-mp3', 'audio/mpeg']): if not image_mime_type == "image/jpeg" and not image_mime_type == "image/png": raise InvalidMimeTypeException("Invalid image format.", image_mime_type) return id3.APIC(encoding=3, mime=image_mime_type, type=3, desc='Cover', data=image_data) elif contains_at_least(audio_mime_type, ['audio/x-aac']): # TODO: Add aac support pass # if not image_mime_type == "image/jpeg" and not image_mime_type == "image/png": # raise InvalidMimeTypeException("Invalid image format.", image_mime_type) # # picture = flac.Picture() # picture.type = 3 # picture.desc = 'front cover' # picture.data = image_data # # return picture elif contains_at_least(audio_mime_type, ['audio/x-flac']): if not image_mime_type == "image/jpeg" and not image_mime_type == "image/png": raise InvalidMimeTypeException("Invalid image format.", image_mime_type) picture = flac.Picture() picture.type = 3 picture.desc = 'front cover' picture.data = image_data return picture else: raise InvalidMimeTypeException("Invalid audio format.", audio_mime_type)
def mp4Tagger( file, metaData ): """ Parse information from the IMDbPY API and write Tag data to MP4 files. Arguments: file (str): Full path of file to write metadata to. metaData (dict): Dictionary of meta data where keys are internal metadata keys and values are metadata values Keyword arguments: None Returns: int: Returns following values based on completion. - 0 : Completed successfully. - 1 : Input was NOT and MP4 - 2 : IMDb ID was not valid - 3 : Failed to download information from IMDb AND themoviedb.org - 4 : Writing tags is NOT possible - 5 : Failed when trying to remove tags from file. - 6 : Failed when trying to write tags to file. - 10 : IMDbPY not installed AND getTMDb_Info failed to import - 11 : File is too large """ log = logging.getLogger(__name__) # Set up a logger log.debug( 'Testing file is MP4' ) # Debugging information if not file.endswith('.mp4'): # If the input file does NOT end in '.mp4' log.error('Input file is NOT an MP4!!!') return 1 # Print message and return code one (1) log.debug( 'Testing file too large' ) # Debugging information if os.stat(file).st_size > sys.maxsize: # If the file size is larger than the supported maximum size log.error('Input file is too large!') return 11 # Print message and return code eleven (11) version = metaData.pop('version', '') comment = _updateComment( metaData.get('comment', '') ) metaData.update( {'comment' : comment } ) metaData = toMP4(metaData) if len(metaData) == 0: log.warning('No metadata, cannot write tags') return 3 filedir, filebase = os.path.dirname( file ), os.path.basename( file ) # Get the directory and baseanem of the file log.debug('Loading file using mutagen.mp4.MP4') # Debugging information handle = mp4.MP4(file) # Initialize mutagen MP4 handler log.debug('Attempting to add tag block to file') # Debugging information try: # Try to... handle.add_tags() # Add new tags to the file except mp4.error as e: # On exception, catch the error if 'already exists' in e.__str__(): # If the error is that the tag block already exists log.debug('MP4 tags already exist in file.') # Debugging information pass # Pass else: # Else, adding is not possible log.error('Could NOT add tags to file!') # Log an error return 4 # Return code 4 try: # Try to... handle.delete(); # Remove all old tags. except mp4.error as e: # On exception, catch the error log.error( e.__str__() ); # Log the error return 5; # Return code 5 log.debug('Setting basic inforamtion') # Debugging information for key, val in metaData.items(): if key == 'covr' and val != '': fmt = mp4.AtomDataType.PNG if val.endswith('png') else mp4.AtomDataType.JPEG # Set format for the image if os.path.isfile( val ): # If value is local file with open(val, 'rb') as fid: data = fid.read() # Read in data from file else: log.debug('Attempting to get coverart') # Debugging information _, data = downloadCover( file, val, text = version ) # Download the data if data is not None: val = [ mp4.MP4Cover( data, fmt ) ] # Add image to file else: continue try: handle[key] = val except: log.warning( 'Failed to write metadata for: {}'.format(key) ) log.debug('Saving tags to file') # Debugging information try: # Try to... handle.save(); # Save the tags except: # On exception log.error('Failed to save tags to file!'); # Log an error return 6 return 0
def mp4Tagger(file, metaData): ''' Name: mp4Tags Purpose: A function to parse information from the IMDbPY API and write Tag data to MP4 files. Inputs: file : Full path of file to write metadata to. metaData : Dictionary of meta data where keys are internal metadata keys and values are metadata values Outputs: Returns following values based on completion. 0 : Completed successfully. 1 : Input was NOT and MP4 2 : IMDb ID was not valid 3 : Failed to download information from IMDb AND themoviedb.org 4 : Writing tags is NOT possible 5 : Failed when trying to remove tags from file. 6 : Failed when trying to write tags to file. 10 : IMDbPY not installed AND getTMDb_Info failed to import 11 : File is too large Keywords: None Dependencies: mutagen Author and History: Kyle R. Wodzicki Created 18 Feb. 2018 ''' log = logging.getLogger(__name__) # Set up a logger log.debug('Testing file is MP4') # Debugging information if not file.endswith('.mp4'): # If the input file does NOT end in '.mp4' log.error('Input file is NOT an MP4!!!') return 1 # Print message and return code one (1) log.debug('Testing file too large') # Debugging information if os.stat( file ).st_size > sys.maxsize: # If the file size is larger than the supported maximum size log.error('Input file is too large!') return 11 # Print message and return code eleven (11) metaData = toMP4(metaData) if len(metaData) == 0: log.warning('No metadata, cannot write tags') return 3 filedir, filebase = os.path.dirname(file), os.path.basename( file) # Get the directory and baseanem of the file log.debug('Loading file using mutagen.mp4.MP4') # Debugging information handle = mp4.MP4(file) # Initialize mutagen MP4 handler log.debug('Attempting to add tag block to file') # Debugging information try: # Try to... handle.add_tags() # Add new tags to the file except mp4.error as e: # On exception, catch the error if 'already exists' in e.__str__( ): # If the error is that the tag block already exists log.debug( 'MP4 tags already exist in file.') # Debugging information pass # Pass else: # Else, adding is not possible log.error('Could NOT add tags to file!') # Log an error return 4 # Return code 4 try: # Try to... handle.delete() # Remove all old tags. except mp4.error as e: # On exception, catch the error log.error(e.__str__()) # Log the error return 5 # Return code 5 log.debug('Setting basic inforamtion') # Debugging information for key, val in metaData.items(): if key == 'covr' and val != '': log.debug('Attempting to get coverart') # Debugging information fmt = mp4.AtomDataType.PNG if val.endswith( 'png') else mp4.AtomDataType.JPEG # Set format for the image data = download(val) if data is not None: val = [mp4.MP4Cover(data, fmt)] # Add image to file else: continue try: handle[key] = val except: log.warning('Failed to write metadata for: {}'.format(key)) log.debug('Saving tags to file') # Debugging information try: # Try to... handle.save() # Save the tags except: # On exception log.error('Failed to save tags to file!') # Log an error return 6 return 0