问题描述
我使用AVAudioPlayer创建了自定义播放器。现在,我想获取音频文件的详细信息,例如资源文件夹中添加的艺术家姓名,专辑名称等。
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.
MPMusicPlayer提供了用于获取详细信息的API,但它使用的是iPod库,而不是从应用程序的沙箱获取资源。因此,MPMusicPlayer在这种情况下不起作用。
MPMusicPlayer provides the API for fetching the details but its using iPod library and its not taking the resource from sandbox of application. So, MPMusicPlayer is not going to work in that scenario.
那么,我们如何才能在iPhone中获取音频文件的详细信息。
So, how can we fetch the details of audio file in iPhone.
推荐答案
您可以通过 AudioToolbox.framework
获取此信息。 AudioToolbox.framework
是一个C API,所以我为它写了一个Objective-C包装器:
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:
ID3Tag .h:
@interface ID3Tag : NSObject <NSCoding> {
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
ID3TagParser.h
#import <Foundation/Foundation.h>
#import "ID3Tag.h"
@interface ID3Parser : NSObject {
}
- (ID3Tag*) parseAudioFileForID3Tag:(NSURL*) url;
@end
ID3TagParser.m
ID3TagParser.m
#import "ID3Parser.h"
#import <AudioToolbox/AudioToolbox.h>
@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
这篇关于如何在iPhone中获取音频文件的详细信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!