iOS:获取文件的元数据

Posted

技术标签:

【中文标题】iOS:获取文件的元数据【英文标题】:iOS: Get file's metadata 【发布时间】:2012-02-17 12:39:49 【问题描述】:

我在服务器上有一个 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";

【问题讨论】:

【参考方案1】:

无需下载整个文件或使用低级 API 即可获取嵌入在 MP3 文件中的 ID3 信息(艺术家姓名、曲目标题)。该功能是AVFoundation 框架的一部分。

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

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

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

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

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

一旦你有了AVAsset,你就可以用它创建一个AVPlayerItem,然后把它提供给AVPlayer,然后播放它,或者不播放。

【讨论】:

我无法从 mp3 文件中检索元数据,但是当我大胆地查看文件时,我能够看到。可能是什么原因?。任何的想法?。我也尝试使用“availableMetadataFormats”进行枚举。 @Vignesh 我会先确保你有一个有效的AVAsset(不是nil)。如果这是有效的,我将只记录commonMetadata,例如:NSLog(@"%@",asset.commonMetadata);。也许元数据格式有一些特殊性。 AVAsset 不为 nil 但通用元数据数组为空。是的。其奇特。我将尝试使用音频工具箱。会更新。谢谢。 我可以在 ***.com/a/8248941/641062 的帮助下使用 AudioToolBox 检索所有信息。但我不明白为什么 AVAsset 不起作用。【参考方案2】:

是和不是。诸如文件大小和修改日期之类的东西通常是 HEAD 响应的一部分。但并非总是如此:使用大量动态 URL,您不会获得所有信息。

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

【讨论】:

我什至没有得到创建日期/修改日期值(请参阅 AllHeaderFields 字典的值)。有什么猜测吗? 就像我说的,您经常在 HEAD 响应中获得该信息,但不一定。尤其是动态 URL。【参考方案3】:

是的,NSURLConnection 的目标是正确的。

我想你想为你想了解的资源发送一个 HEAD 请求,然后检查你在 connection:didReceiveResponse:connection:didReceiveData: 中收到的信息

编辑

诚然,我没有完整阅读您的问题。无法获取 ID3 信息,但您应该能够获取文件大小以及创建日期等。

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

【讨论】:

我什至没有得到创建日期/修改日期值(请参阅 AllHeaderFields 字典的值)。有什么猜测吗?

以上是关于iOS:获取文件的元数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 html5 文件系统 api 获取本地 mp3 文件的元数据

上传前如何获取视频的元数据(长度)?

如何在 gradle 中获取依赖项的元数据?

BigQuery 获取外部代码资源的元数据时出错

按位置从 iOS 照片库中获取照片

如何检索 PHAsset 的元数据?