iOS:获取文件的元数据

时间:2012-02-17 12:39:50

标签: ios nsurlconnection

我在服务器上有一个mp3文件。我想得到这个文件的信息,比如这个文件的大小,艺术家名称是什么,专辑名称是什么,文件创建时间,修改时间等等。我想要所有这些信息。

是否可以在不实际下载整个文件的情况下获取此信息?使用NSURLConnection或其他?

修改

以下代码未向我提供所需信息,即由艺术家姓名等创建的文件

    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]);
    }

“AllHeaderFields”是:

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";
}

3 个答案:

答案 0 :(得分:4)

很有可能在不下载整个文件或使用低级API的情况下将ID3信息嵌入MP3文件(艺术家姓名,曲目标题)中。该功能是AVFoundation框架的一部分。

要查看的类是AVAsset,特别是它是网络友好的子类AVURLAssetAVAsset有一个名为NSArray的{​​{1}}属性。此commonMetadata属性将包含commonMetadata的实例,当然假设参考URL包含元数据。您通常会使用AVMetadataItem的{​​{1}}属性来引用该项目。我发现这种迭代遍历数组检查AVMetadataItem的方法很烦人,因此我使用commonKey属性创建commonKeys作为NSDictionarycommonKey属性作为key。像这样:

value

通过添加这种简单方法,object的元数据变得非常容易使用。以下是通过URL获取MP3元数据的示例:

-(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];
}

我发现此代码似乎只加载MP3文件的前几秒。另请注意,此代码是同步的;所以要谨慎使用。但是AVAsset确实有一些文档中描述的异步功能。

获得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"]); 后,您可以使用AVURLAsset创建AVAsset并将其提供给AVPlayerItem并播放,或者不播放。

答案 1 :(得分:2)

是的,你是NSIDLConnection的目标。

我想您想要发送有关您想了解相关资源的HEAD请求,然后检查您在connection:didReceiveResponse:connection:didReceiveData:

中收到的信息

修改

诚然,我没有完整地阅读你的问题。获取ID3信息是不可能的,但您应该能够获得文件大小和创建日期等。

This answer确实提供了有关如何获取ID3信息的一些有用信息。您需要设置一个php页面来检查服务器端的mp3文件并返回您需要的信息而不是整个mp3。

答案 2 :(得分:1)

是和否。文件大小和修改日期之类的内容通常是HEAD响应的一部分。但并非总是如此:使用大量动态网址,您将无法获得所有信息。

对于艺术家和专辑名称,它们是MP3 ID3的一部分,它包含在文件中,因此您无法通过HEAD请求获取它们。由于ID3标记通常位于文件的开头,因此您可以尝试仅抓取该部分,然后读取ID3标记。但是你不能用NSURLConnection来完成它,因为它不支持只获取文件的一部分,所以你需要找到一种更低层次的HTTP获取数据的方式。