how to fetch the details of the audio file in iPhone

后端 未结 2 1724
说谎
说谎 2020-12-25 10:15

I made the custom player by using AVAudioPlayer. Now, I want to fetch the details of the audio file such as artist name,album name,etc which is added in the resource folder.

2条回答
  •  长情又很酷
    2020-12-25 10:43

    You can get this information through the AudioToolbox.framework. The AudioToolbox.framework is a C API, so I wrote an Objective-C wrapper for it:

    ID3Tag .h:

    @interface ID3Tag : NSObject  {
        NSString* title_;
        NSString* album_;
        NSString* artist_;
        NSNumber* trackNumber_;
        NSNumber* totalTracks_;
        NSString* genre_;
        NSString* year_;
        NSNumber* approxDuration_;
        NSString* composer_;
        NSString* tempo_;
        NSString* keySignature_;
        NSString* timeSignature_;
        NSString* lyricist_;
        NSString* recordedDate_;
        NSString* comments_;
        NSString* copyright_;
        NSString* sourceEncoder_;
        NSString* encodingApplication_;
        NSString* bitRate_;
        NSStream* sourceBitRate_;
        NSString* channelLayout_;
        NSString* isrc_;
        NSString* subtitle_;  
    }
    
    @property (nonatomic, retain) NSString *title;
    @property (nonatomic, retain) NSString *album;
    @property (nonatomic, retain) NSString *artist;
    @property (nonatomic, retain) NSNumber *trackNumber;
    @property (nonatomic, retain) NSNumber *totalTracks;
    @property (nonatomic, retain) NSString *genre;
    @property (nonatomic, retain) NSString *year;
    @property (nonatomic, retain) NSNumber *approxDuration;
    @property (nonatomic, retain) NSString *composer;
    @property (nonatomic, retain) NSString *tempo;
    @property (nonatomic, retain) NSString *keySignature;
    @property (nonatomic, retain) NSString *timeSignature;
    @property (nonatomic, retain) NSString *lyricist;
    @property (nonatomic, retain) NSString *recordedDate;
    @property (nonatomic, retain) NSString *comments;
    @property (nonatomic, retain) NSString *copyright;
    @property (nonatomic, retain) NSString *sourceEncoder;
    @property (nonatomic, retain) NSString *encodingApplication;
    @property (nonatomic, retain) NSString *bitRate;
    @property (nonatomic, retain) NSStream *sourceBitRate;
    @property (nonatomic, retain) NSString *channelLayout;
    @property (nonatomic, retain) NSString *isrc;
    @property (nonatomic, retain) NSString *subtitle;
    
    @end
    

    ID3TagParser.h

    #import 
    #import "ID3Tag.h"
    
    @interface ID3Parser : NSObject {
    
    }
    
    - (ID3Tag*) parseAudioFileForID3Tag:(NSURL*) url;
    
    @end
    

    ID3TagParser.m

    #import "ID3Parser.h"
    #import 
    
    @implementation ID3Parser
    
    - (ID3Tag*) parseAudioFileForID3Tag:(NSURL*) url {
        if (url == nil) {
            return nil;
        }
    
        AudioFileID fileID  = nil;
        OSStatus err = noErr;
    
        err = AudioFileOpenURL( (CFURLRef) url, kAudioFileReadPermission, 0, &fileID );
        if( err != noErr ) {
            NSLog( @"AudioFileOpenURL failed" );
            return nil;
        } else {
            UInt32 id3DataSize = 0;
            char* rawID3Tag = NULL;
    
            //  Reads in the raw ID3 tag info
            err = AudioFileGetPropertyInfo(fileID, kAudioFilePropertyID3Tag, &id3DataSize, NULL);
            if(err != noErr) {
                return nil;
            }
    
            //  Allocate the raw tag data
            rawID3Tag = (char *) malloc(id3DataSize);
    
            if(rawID3Tag == NULL) {
                return nil;
            }
    
            err = AudioFileGetProperty(fileID, kAudioFilePropertyID3Tag, &id3DataSize, rawID3Tag);
            if(err != noErr) {
                return nil;
            }
    
            UInt32 id3TagSize = 0;
            UInt32 id3TagSizeLength = 0;
            err = AudioFormatGetProperty(kAudioFormatProperty_ID3TagSize, id3DataSize, rawID3Tag, &id3TagSizeLength, &id3TagSize);
    
            if(err != noErr) {
                switch(err) {
                    case kAudioFormatUnspecifiedError:
                        NSLog(@"err: audio format unspecified error");
                        return nil;
                    case kAudioFormatUnsupportedPropertyError:
                        NSLog(@"err: audio format unsupported property error");
                        return nil;
                    case kAudioFormatBadPropertySizeError:
                        NSLog(@"err: audio format bad property size error"); 
                        return nil;
                    case kAudioFormatBadSpecifierSizeError:
                        NSLog(@"err: audio format bad specifier size error"); 
                        return nil;
                    case kAudioFormatUnsupportedDataFormatError:
                        NSLog(@"err: audio format unsupported data format error"); 
                        return nil;
                    case kAudioFormatUnknownFormatError:
                        NSLog(@"err: audio format unknown format error");
                        return nil;
                    default:
                        NSLog(@"err: some other audio format error"); 
                        return nil;
                }
            }
    
            CFDictionaryRef piDict = nil;
            UInt32 piDataSize = sizeof(piDict);
    
            //  Populates a CFDictionary with the ID3 tag properties
            err = AudioFileGetProperty(fileID, kAudioFilePropertyInfoDictionary, &piDataSize, &piDict);
            if(err != noErr) {
                NSLog(@"AudioFileGetProperty failed for property info dictionary");
                return nil;
            }
    
            //  Toll free bridge the CFDictionary so that we can interact with it via objc
            NSDictionary* nsDict = (NSDictionary*)piDict;
    
            ID3Tag* tag = [[[ID3Tag alloc] init] autorelease];
    
            tag.album = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Album]];
            tag.approxDuration = [NSNumber numberWithInt:[[nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_ApproximateDurationInSeconds]] intValue]];
            tag.artist = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Artist]];
            tag.bitRate = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_NominalBitRate]];
            tag.channelLayout = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_ChannelLayout]];
            tag.comments = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Comments]];
            tag.composer = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Composer]];
            tag.copyright = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Copyright]];
            tag.encodingApplication = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_EncodingApplication]];
            tag.genre = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Genre]];
            tag.isrc = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_ISRC]];
            tag.keySignature = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_KeySignature]];
            tag.lyricist = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Lyricist]];
            tag.recordedDate = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_RecordedDate]];
            tag.sourceBitRate = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_SourceBitDepth]];
            tag.sourceEncoder = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_SourceEncoder]];
            tag.subtitle = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_SubTitle]];
            tag.tempo = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Tempo]];
            tag.timeSignature = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_TimeSignature]];
            tag.title = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Title]];
            tag.year = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_Year]];
    
            /*  
             *  We're going to parse tracks differently so that we can perform queries on the data. This means we need to look
             *  for a '/' so that we can seperate out the track from the total tracks on the source compilation (if it's there).
             */
            NSString* tracks = [nsDict objectForKey:[NSString stringWithUTF8String: kAFInfoDictionary_TrackNumber]];
    
            int slashLocation = [tracks rangeOfString:@"/"].location;
    
            if (slashLocation == NSNotFound) {
                tag.trackNumber = [NSNumber numberWithInt:[tracks intValue]];
            } else {
                tag.trackNumber = [NSNumber numberWithInt:[[tracks substringToIndex:slashLocation] intValue]];
                tag.totalTracks = [NSNumber numberWithInt:[[tracks substringFromIndex:(slashLocation+1 < [tracks length] ? slashLocation+1 : 0 )] intValue]];
            }
    
            //  ALWAYS CLEAN UP!
            CFRelease(piDict);
            nsDict = nil;
            free(rawID3Tag);
    
            return tag;
        }
    }
    
    @end
    

提交回复
热议问题