diff --git a/headphones/encode.py b/headphones/encode.py index 632e9a45..10fd63b5 100644 --- a/headphones/encode.py +++ b/headphones/encode.py @@ -2,8 +2,12 @@ import os import headphones import shutil import time +import sys from subprocess import call +from headphones import logger +from lib.mutagen.mp3 import MP3 +from lib.mutagen.easyid3 import EasyID3 try: import argparse @@ -14,6 +18,7 @@ def encode(albumPath): tempDirEncode=os.path.join(albumPath,"temp") musicFiles=[] + musicFinalFiles=[] musicTempFiles=[] encoder ="" if not os.path.exists(tempDirEncode): @@ -25,10 +30,11 @@ def encode(albumPath): for r,d,f in os.walk(albumPath): for music in f: - if any(music.endswith('.' + x) for x in ["flac", "m4a", "wav"]): + if any(music.endswith('.' + x) for x in ["mp3", "flac", "m4a", "wav"]): musicFiles.append(os.path.join(r, music)) - musicTempFiles.append(os.path.join(tempDirEncode, music)) - + musicTemp = os.path.join(os.path.splitext(music)[0])+'.mp3' + musicTempFiles.append(os.path.join(tempDirEncode, musicTemp)) + if headphones.ENCODER=='lame': encoder=os.path.join(headphones.ENCODERFOLDER,'lame') else: @@ -36,25 +42,56 @@ def encode(albumPath): i=0 for music in musicFiles: return_code=1 - if headphones.ENCODER == 'lame': - cmd=encoder+' -h --resample ' + headphones.SAMPLINGFREQUENCY + ' -b ' + headphones.BITRATE - cmd=cmd+' "'+os.path.join(music)+'"' - cmd=cmd+' "'+os.path.join(musicTempFiles[i])+'"' - return_code = call(cmd, shell=True) - if return_code==0: - os.remove(music) - os.rename(musicTempFiles[i],music) - i=i+1 - else: - cmd=encoder+' -i' - cmd=cmd+' "'+os.path.join(music)+'"' - cmd=cmd+' -ac 2 -vn -ar ' + headphones.SAMPLINGFREQUENCY + ' -ab ' + headphones.BITRATE +'k' - cmd=cmd+' "'+os.path.join(musicTempFiles[i])+'"' - return_code = call(cmd, shell=True) - print return_code - if return_code==0: - os.remove(music) - os.rename(musicTempFiles[i],music) - i=i+1 - - shutil.rmtree(tempDirEncode) \ No newline at end of file + if headphones.ENCODER == 'lame': + if not any(music.endswith('.' + x) for x in ["mp3", "wav"]): + logger.warn('Lame cant encode "%s" format for "%s", use ffmpeg' % (os.path.splitext(music)[1],music)) + else: + if (music.endswith('.mp3') and (MP3(music).info.bitrate/1000<=headphones.BITRATE)): + logger.warn('Music "%s" has bitrate<="%skbit" will not be reencoded' % (music,headphones.BITRATE)) + else: + cmd=encoder+' -h --resample ' + str(headphones.SAMPLINGFREQUENCY) + ' -b ' + str(headphones.BITRATE) + cmd=cmd+' "'+os.path.join(music)+'"' + cmd=cmd+' "'+os.path.join(musicTempFiles[i])+'"' + return_code = call(cmd, shell=True) + if return_code==0: + #copyID3(music,musicTempFiles[i]) + os.remove(music) + shutil.move(musicTempFiles[i],os.path.join(albumPath)) + else: + if (music.endswith('.mp3') and (MP3(music).info.bitrate/1000<=headphones.BITRATE)): + logger.warn('Music "%s" has bitrate<="%skbit" will not be reencoded' % (music,headphones.BITRATE)) + else: + cmd=encoder+' -i' + cmd=cmd+' "'+os.path.join(music)+'"' + cmd=cmd+' -ac 2 -vn -ar ' + str(headphones.SAMPLINGFREQUENCY) + ' -ab ' + str(headphones.BITRATE) +'k' + cmd=cmd+' "'+os.path.join(musicTempFiles[i])+'"' + return_code = call(cmd, shell=True) + if return_code==0: + #copyID3(music,musicTempFiles[i]) + os.remove(music) + shutil.move(musicTempFiles[i],os.path.join(albumPath)) + + i=i+1 + + shutil.rmtree(tempDirEncode) + time.sleep(1) + logger.info('Encoding for folder "%s" is completed' % (albumPath)) + for r,d,f in os.walk(albumPath): + for music in f: + if any(music.endswith('.' + x) for x in headphones.MEDIA_FORMATS): + musicFinalFiles.append(os.path.join(r, music)) + return musicFinalFiles + +def copyID3 (src,dst): + try: + source = EasyID3(src) + try: + dest = EasyID3(dst) + except: + dest = ID3() + dest.save(dst) + for key in source: + dest[key] = source[key] + dest.save() + except: + return() diff --git a/headphones/librarysync.py b/headphones/librarysync.py index 73d53e99..990c2d3c 100644 --- a/headphones/librarysync.py +++ b/headphones/librarysync.py @@ -15,7 +15,7 @@ def libraryScan(dir=None): dir = str(dir) except UnicodeEncodeError: dir = unicode(dir).encode('unicode_escape') - + logger.info('Scanning music directory: %s' % dir) new_artists = [] @@ -28,12 +28,14 @@ def libraryScan(dir=None): for files in f: # MEDIA_FORMATS = music file extensions, e.g. mp3, flac, etc if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS): + song = os.path.join(r, files) file = unicode(os.path.join(r, files), headphones.SYS_ENCODING, errors='replace') # Try to read the metadata try: f = MediaFile(song) + except: logger.error('Cannot read file: ' + file) continue @@ -77,10 +79,10 @@ def libraryScan(dir=None): # The have table will become the new database for unmatched tracks (i.e. tracks with no associated links in the database myDB.action('INSERT INTO have VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [f_artist, f.album, f.track, f.title, f.length, f.bitrate, f.genre, f.date, f.mb_trackid, file, helpers.cleanName(f_artist+' '+f.album+' '+f.title)]) - + logger.info('Completed scanning of directory: %s' % dir) logger.info('Checking filepaths to see if we can find any matches') - + # Now check empty file paths to see if we can find a match based on their folder format tracks = myDB.select('SELECT * from tracks WHERE Location IS NULL') for track in tracks: @@ -142,6 +144,7 @@ def libraryScan(dir=None): if match: logger.info('Found a match: %s. Writing MBID to metadata' % match[0]) + myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [match[0], track['TrackID']]) myDB.action('DELETE from have WHERE Location=?', [match[0]]) @@ -151,11 +154,15 @@ def libraryScan(dir=None): f.mb_trackid = track['TrackID'] f.save() myDB.action('UPDATE tracks SET BitRate=? WHERE TrackID=?', [f.bitrate, track['TrackID']]) + + logger.debug('Wrote mbid to track: %s' % match[0]) + except: logger.error('Error embedding track id into: %s' % match[0]) continue - + logger.info('Done checking empty filepaths') + # Clean up bad filepaths tracks = myDB.select('SELECT Location, TrackID from tracks WHERE Location IS NOT NULL') @@ -173,12 +180,13 @@ def libraryScan(dir=None): # Update track counts logger.info('Updating track counts') + for artist in current_artists: havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL', [artist['ArtistID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']])) myDB.action('UPDATE artists SET HaveTracks=? WHERE ArtistID=?', [havetracks, artist['ArtistID']]) logger.info('Found %i new artists' % len(artist_list)) - + if len(artist_list): if headphones.ADD_ARTISTS: logger.info('Importing %i new artists' % len(artist_list)) diff --git a/headphones/postprocessor.py b/headphones/postprocessor.py index ec4d7e6f..7a779e6e 100644 --- a/headphones/postprocessor.py +++ b/headphones/postprocessor.py @@ -198,11 +198,10 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) logger.info('Starting post-processing for: %s - %s' % (release['ArtistName'], release['AlbumTitle'])) #start enconding - if headphones.ENCODE=='1': - encode.encode(albumpath) + if headphones.ENCODE: + downloaded_track_list=encode.encode(albumpath) if headphones.EMBED_ALBUM_ART or headphones.ADD_ALBUM_ART: - album_art_path = albumart.getAlbumArt(albumid) artwork = urllib.urlopen(album_art_path).read()