Beispiel #1
0
    def extract_metadata(self, file):
        enc = locale.getpreferredencoding()

        try:
            meta = EasyID3(file.path)
        except Exception, e:
            meta = MutagenFile(file.path)
Beispiel #2
0
    def tag(self):
        data = self.get_parent_instance().metadata()

        with tempfile.NamedTemporaryFile(suffix='-musicdb.mp3') as f:
            # Download
            with default_storage.open(self.file.location) as g:
                contents = g.read()

            f.write(contents)
            f.flush()
            f.seek(0)

            audio = MutagenFile(f.name)
            audio.delete()

            if isinstance(audio, mp3.MP3):
                audio.tags = easyid3.EasyID3()

            audio.update(data)
            audio.save()

            self.length = int(audio.info.length)

            # Copy it back
            default_storage.delete(self.file.location)
            dst = default_storage.save(self.file.location, DjangoFile(f))

            assert dst == self.file.location
Beispiel #3
0
    def quick_create(cls, abspath, cd, track_title, track_num):
        audio = MutagenFile(abspath)

        if isinstance(audio, mp3.MP3):
            extension = 'mp3'

        location = os.path.join(
            'albums',
            '%d' % cd.id,
            '%.2d.%s' % (track_num, extension),
        )

        file = File.create_from_path(abspath, location)

        music_file = MusicFile.objects.create(
            file=file,
            rev_model='track',
        )

        return cls.objects.create(
            cd=cd,
            num=track_num,
            title=track_title,
            music_file=music_file,
        )
Beispiel #4
0
def get_audio_length(path):        
    try:
        audio = MutagenFile(path, FORMATS)
        if audio is not None:
            return int(audio.info.length) * 1000
        return 0
    except:
        return 0
Beispiel #5
0
    def extract_metadata(self, file):
        

        log = logging.getLogger('importer.process.extract_metadata')
        log.info('Extracting metadata for: %s' % (file.path))
        
        enc = locale.getpreferredencoding()
        
        try:
            meta = EasyID3(file.path)
            log.debug('using EasyID3')
        except Exception, e:
            meta = MutagenFile(file.path)
            log.debug('using MutagenFile')
Beispiel #6
0
    def save(self, *args, **kwargs):
        if not self.length:
            filename = os.path.join(settings.MEDIA_LOCATION,
                                    self.file.location)
            audio = MutagenFile(filename)

            if isinstance(audio, mp3.MP3):
                self.type = 'mp3'
            elif isinstance(audio, flac.FLAC):
                self.type = 'flac'
            else:
                assert False, "Unsupported Mutagen class %s" % audio.__class__

            self.length = int(audio.info.length)

        super(MusicFile, self).save(*args, **kwargs)
Beispiel #7
0
 def tag(self):
     try:
         data = self.get_parent_instance().metadata()
         filename = os.path.join(settings.MEDIA_LOCATION,
                                 self.file.location)
         audio = MutagenFile(filename)
         audio.delete()
         if isinstance(audio, mp3.MP3):
             audio.tags = easyid3.EasyID3()
         audio.update(data)
         audio.save()
     except:
         self.tags_dirty = None
         self.save()
         raise
     finally:
         self.tags_dirty = False
         self.save()
Beispiel #8
0
def add_chapters(filepath, chapters):
    """Adds chapters to the given audio file"""
    audio = ID3(filepath)
    # Adding table of contents
    audio.add(
        CTOC(element_id=u"toc",
             flags=CTOCFlags.TOP_LEVEL | CTOCFlags.ORDERED,
             child_element_ids=[
                 u"chp" + str(i + 1) for i in range(len(chapters))
             ],
             sub_frames=[TIT2(text=[u"Table of Contents"])]))
    # Adding chapters
    for i in range(len(chapters) - 1):
        add_chapter(audio, chapters[i][0], chapters[i + 1][0], chapters[i][1],
                    i + 1)
    length = MutagenFile(filepath).info.length * 1000
    add_chapter(audio, chapters[-1][0], length, chapters[-1][1], len(chapters))
    audio.save()
Beispiel #9
0
            base_duration = None
            self.processed = 2
        """  
        self.base_format = iext
        self.base_bitrate = base_bitrate
        self.base_samplerate = base_samplerate
        self.base_filesize = base_filesize
        """
        self.duration = base_duration

        meta = None
        try:
            meta = EasyID3(self.master.path)
            log.debug('using EasyID3')
        except Exception, e:
            meta = MutagenFile(self.master.path)
            log.debug('using MutagenFile')

        print meta

        if 'title' in meta:
            self.name = meta['title'][0]
        if 'artist' in meta:
            self.artist, created = Artist.objects.get_or_create(
                name=meta['artist'][0])
            #self.name = meta['title'][0]

        self.save()

        try:
            self.create_waveform_image()
    def extract_metadata(self, file):

        if self.file_metadata:
            return self.file_metadata

        log.info('Extracting metadata for: %s' % (file.path))

        enc = locale.getpreferredencoding()

        meta = None
        ext = os.path.splitext(file.path)[1]
        log.debug('detected %s as extension' % ext)

        if ext:
            ext = ext.lower()

        if ext == '.mp3':
            try:
                meta = EasyID3(file.path)
            except Exception as e:
                log.debug('unable to process MP3')

        if ext in ['.mp4', '.m4a']:
            try:
                meta = EasyMP4(file.path)
            except Exception as e:
                log.debug('unable to process M4A')

        if not meta:
            try:
                meta = MutagenFile(file.path)
                log.debug('using MutagenFile')
            except Exception as e:
                log.warning(
                    'even unable to open file with straight mutagen: %s' % e)

        dataset = dict(METADATA_SET)

        # try to get obp identifyer
        try:
            from mutagen.id3 import ID3
            id3 = ID3(file.path)
            obp_media_uuid = id3["UFID:http://openbroadcast.org"].data.decode(
                'ascii')
            if obp_media_uuid:
                dataset['obp_media_uuid'] = obp_media_uuid
        except:
            pass

        # Media
        try:
            dataset['media_name'] = meta['title'][0]
        except Exception as e:
            log.info('metadata missing "media_name": %s' % (e))

        try:
            dataset['media_mb_id'] = meta['musicbrainz_trackid'][0]
        except Exception as e:
            log.debug('metadata missing "media_mb_id": %s' % (e))

        try:

            try:
                dataset['media_tracknumber'] = int(meta['tracknumber'][0])
            except Exception as e:
                try:
                    dataset['media_tracknumber'] = int(
                        meta['tracknumber'][0].split('/')[0])
                except Exception as e:
                    pass
                log.debug('metadata missing "media_tracknumber": %s' % (e))

            try:
                tn = meta['tracknumber'][0].split('/')
                dataset['media_tracknumber'] = int(tn[0])
                dataset['media_totaltracks'] = int(tn[1])

            except Exception as e:
                pass

        except Exception as e:
            log.debug('unable to extract tracknumber from metadata')

        # try to extract tracknumber from filename
        if 'media_tracknumber' in dataset and not dataset['media_tracknumber']:

            t_num = None

            path, filename = os.path.split(file.path)
            log.info('Looking for number in filename: %s' % filename)

            match = re.search("\A\d+", filename)

            try:
                if match:
                    t_num = int(match.group(0))
            except:
                pass

            dataset['media_tracknumber'] = t_num

        # Artist
        try:
            dataset['artist_name'] = meta['artist'][0]
        except Exception as e:
            pass

        try:
            # mutagen metadata contains '/' separated ids for mp3, while a list for flac
            # so we join by '/' to get an unified way.
            # the opposite would actually be better, but also would require a lot of refactoring...
            # so a TODO: fix this at some point of time...
            dataset['artist_mb_id'] = '/'.join(meta['musicbrainz_artistid'])

        except Exception as e:
            pass

        try:
            dataset['performer_name'] = meta['performer'][0]
        except Exception as e:
            pass

        # Release
        try:
            dataset['release_name'] = meta['album'][0]
        except Exception as e:
            #print e
            pass

        try:
            dataset['release_mb_id'] = meta['musicbrainz_albumid'][0]
        except Exception as e:
            #print e
            pass

        try:
            dataset['release_date'] = meta['date'][0]
        except Exception as e:
            #print e
            pass

        try:
            dataset['release_releasecountry'] = meta['releasecountry'][0]
        except Exception as e:
            #print e
            pass

        try:
            dataset['release_status'] = meta['musicbrainz_albumstatus'][0]
        except Exception as e:
            #print e
            pass

        # Label
        try:
            try:
                dataset['label_name'] = meta['organization'][0]
            except Exception as e:
                #print e
                pass

            try:
                dataset['label_name'] = meta['label'][0]
            except Exception as e:
                #print e
                pass

        except Exception as e:
            #print e
            pass

        try:
            dataset['label_code'] = meta['labelno'][0]
        except Exception as e:
            #print e
            pass

        # Misc
        try:
            dataset['media_copyright'] = meta['copyright'][0]
        except Exception as e:
            #print e
            pass

        try:
            dataset['media_comment'] = meta['comment'][0]
        except Exception as e:
            #print e
            pass

        try:
            dataset['media_bpm'] = meta['bpm'][0]
        except Exception as e:
            #print e
            pass
        """
        hacks to prevent some mutagen bugs:
         - https://bitbucket.org/lazka/mutagen/issues/215/mutageneasyid3easyid3keyerror
         - https://dev.sourcefabric.org/browse/CC-6035
        """
        if meta:

            for k in meta:

                if k == 'replaygain_SeratoGain_gain':
                    del (meta[k])

                if k == 'replaygain_SeratoGain_peak':
                    del (meta[k])

                if k[0:13] == 'PRIV:TRAKTOR4':
                    del (meta[k])

        self.file_metadata = dataset

        return dataset
Beispiel #11
0
    #  this is a problem.
    #
    #  The good thing about the changes is that there will be no longer a
    #  dependency on mutagen and more formats will be able to be read (WAV and
    #  FLAC).
    #
    # Note(3) from [email protected]:
    #
    #  I have made this optional: if Mutagen is installed, use it otherwise
    #  don't.

    # Use mutagen's duration count only if available and if it supports the file
    # type.
    buffer, samples, sample_rate, stereo, duration = result
    if MutagenFile is not None:
        mutagenfile = MutagenFile(filename)
        if bool(mutagenfile):
            duration = mutagenfile.info.length * 1000

    fingerprint = ofa.create_print(buffer, samples, sample_rate, stereo)
    return fingerprint, int(duration)


def encode_filename(filename):
    """Encode unicode strings to filesystem encoding."""
    if isinstance(filename, unicode):
        if os.path.supports_unicode_filenames:
            return filename
        else:
            return filename.encode(_io_encoding, 'replace')
    else:
    def process(self):
        iext = None
        try:
            iext = os.path.splitext(self.master.path)[1].lower()
            iext = iext[1:]
            audiofile = audiotools.open(self.master.path)
            
            base_format = iext
            base_bitrate = audiofile.bits_per_sample()
            base_samplerate = audiofile.sample_rate()
            base_filesize = os.path.getsize(self.master.path)
            base_duration = audiofile.seconds_length()
            
            try:
                base_duration = float(audiofile.total_frames()) / float(audiofile.sample_rate()) * 1000
                print 'frames: %s' % audiofile.total_frames()
                print 'rate: %s' % audiofile.sample_rate()
                print base_duration
                print
            except:
                pass
            
            self.processed = 1
        except Exception as e:
            print e
            base_bitrate = None
            base_samplerate = None
            base_filesize = None
            base_duration = None
            self.processed = 2
          
        """  
        self.base_format = iext
        self.base_bitrate = base_bitrate
        self.base_samplerate = base_samplerate
        self.base_filesize = base_filesize
        """
        self.duration = base_duration
        
        meta = None
        try:
            meta = EasyID3(self.master.path)
            log.debug('using EasyID3')
        except Exception as e:
            meta = MutagenFile(self.master.path)
            log.debug('using MutagenFile')
        
        
        print meta
        
        if 'title' in meta:
            self.name = meta['title'][0]
        if 'artist' in meta:
            self.artist, created = Artist.objects.get_or_create(name=meta['artist'][0])

        self.save()
        
        try:
            self.create_waveform_image()
        except:
            pass
        return
Beispiel #13
0
class Song(AudioUtil):
    def __init__(self, path):
        try:
            self.path = path.decode('utf-8')
        except UnicodeDecodeError, e:
            latin1path = path.decode('latin1')
            # decoding file name into utf8 failed but latin1 worked.
            # filename contains latin1-only characters (?)
            # for example \xc2, \xa0
            # encode path in in utf8
            self.path = latin1path.encode('utf-8').decode('utf-8')
            log.info(u"bad chars, mv {} -> {}".format(latin1path, self.path))
            import shutil
            shutil.move(path, self.path)  # yes, first arg should be `path'.
            path = None  # <- be sure not to use this again - it no longer exists.

        self.ext = os.path.splitext(self.path)[1].lower().strip('.')
        self.corrupt = False
        self.bitrate = self.length = 0
        self.title = self.artist = self.album = u''
        self.tracknumber = -1
        self.mimetype = subprocess.Popen(
            [u"/usr/bin/file", u"--mime-type", self.path],
            stdout=subprocess.PIPE).communicate()[0].split(": ")[-1].rstrip()
        av = self.mimetype[0:5]
        maybeaudio = (self.mimetype == u'application/octet-stream') and (
            self.ext in Config.audio_types.values())

        # enqueue any audio file, or file that looks like an audio file
        if (av == u"audio") or maybeaudio:
            audio = None
            try:
                audio = MutagenFile(self.path, easy=True)
            except Exception, e:
                # e.g.,
                # "header size not synchsafe"
                # mutagen.mp3.HeaderNotFoundError: can't sync to an MPEG frame
                log.error(u"{} {}".format(e, self.path))
                self.corrupt = True

            if audio is None or self.corrupt:
                log.error(u"Mutagen is None {}".format(self.path))
            else:
                if len(audio) < 1:
                    # couldn't read metadata for some reason
                    log.warn(u"mutagen failed {}".format(self.path))
                else:
                    try:
                        self.bitrate = int(audio.info.bitrate)
                    except:
                        pass

                    try:
                        self.length = int(audio.info.length)
                    except:
                        pass

                    try:
                        self.artist = audio.get(u'artist', [''])[0]
                        self.album = audio.get(u'album', [''])[0]
                        self.title = audio.get(u'title', [''])[0]
                        if u'tracknumber' in audio:
                            tn = audio.get(u'tracknumber')[0]
                            # test for track number listed as i/n
                            tn = tn.split(u"/")[0]
                            # convert to a number
                            try:
                                self.tracknumber = int(tn, base=10)
                            except ValueError:
                                pass
                                #  not a base10 integer.  hex?
                                # try:
                                #     self.tracknumber = int(tn, base=16)
                                # except ValueError:
                                #     pass # give up
                    except Exception, e:
                        log.debug(u"track data error %s %s %s %s", self.path,
                                  self.mimetype, e, audio)