I have an mp3 file on a server. I want to get this file's information like what's the size of this file, what's the artists name, what's the album name, when was the file created, when was it modified, etc. I want all this information.
Is it possible to get this information without actually downloading the whole file? Using NSURLConnection
or otherwise?
EDIT:
The following code doesn't give me the required information, i.e. file created by, artist name, etc
NSError *rerror = nil;
NSURLResponse *response = nil;
NSURL *url = [NSURL URLWithString:@"http://link.to.mp3"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"HEAD"];
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&rerror];
NSString *resultString = [[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding] autorelease];
NSLog(@"URL: %@", url);
NSLog(@"Request: %@", request);
NSLog(@"Result (NSData): %@", result);
NSLog(@"Result (NSString): %@", resultString);
NSLog(@"Response: %@", response);
NSLog(@"Error: %@", rerror);
if ([response isMemberOfClass:[NSHTTPURLResponse class]]) {
NSLog(@"AllHeaderFields: %@", [((NSHTTPURLResponse *)response) allHeaderFields]);
}
The "AllHeaderFields" is:
AllHeaderFields: {
"Cache-Control" = "max-age=0";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Type" = "text/plain; charset=ascii";
Date = "Fri, 17 Feb 2012 12:44:59 GMT";
Etag = 19202n;
Pragma = public;
Server = dbws;
"x-robots-tag" = "noindex,nofollow";
}
It is quite possible to get the ID3 information embedded in an MP3 file (artist name, track title) without downloading the whole file or using low-level APIs. The functionality is part of the AVFoundation
framework.
The class to look at is AVAsset
and specifically it's network friendly subclass AVURLAsset
. AVAsset
has an NSArray
property named commonMetadata
. This commonMetadata
property will contain instances of AVMetadataItem
, assuming of course that the reference URL contains metadata. You will usually use the AVMetadataItem
's commonKey
property to reference the item. I find this method of iterating through an array checking commonKeys
irritating so I create an NSDictionary
using the commonKey
property as the key
and the value
property as the object
. Like so:
-(NSDictionary *)dictionaryOfMetadataFromAsset:(AVAsset *)asset{
NSMutableDictionary *metaData = [[NSMutableDictionary alloc] init];
for (AVMetadataItem *item in asset.commonMetadata) {
if (item.value && item.commonKey){
[metaData setObject:item.value forKey:item.commonKey];
}
}
return [metaData copy];
}
With the addition of this simple method the AVAsset
's metadata becomes quite easy to use. Here is an example of getting an MP3's metadata through a URL:
NSURL *mp3URL = [NSURL URLWithString:@"http://'AddressOfMP3File'"];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:mp3URL options:nil];
NSDictionary *metaDict = [self dictionaryOfMetadataFromAsset:asset];
NSLog(@"Available Metadata :%@",metaDict.allKeys);
NSLog(@"title:%@",[metaDict objectForKey:@"title"]);
I have found that this code seems to load just the first few seconds of your MP3 file. Also note that this code is synchronous; So use with caution. But AVURLAsset
does have some async functionality described in the docs.
Once you have the AVAsset
you can create a AVPlayerItem
with it and feed that to an AVPlayer
and play it, or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With