AVURLAsset 无法在文档目录中获取 mp3 持续时间,但它与应用程序包中的 mp3 配合得很好

AVURLAsset can't get mp3 duration in documents directory, but it works well with mp3 in app bundle

我有两个 mp3 文件。一个在应用程序包中,另一个在用户的文档目录中。我想获取mp3文件的时长。

AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:newPath] options:nil];
[audioAsset loadValuesAsynchronouslyForKeys:@[@"duration"] completionHandler:^{
    CMTime audioDuration = audioAsset.duration;
    float audioDurationSeconds = CMTimeGetSeconds(audioDuration);

    NSLog(@"duration:%f",audioDurationSeconds);
}];

这些代码适用于应用程序包中的 mp3 文件,但不适用于仅记录 "duration:0.000000" 的 Documents 目录中的 mp3。为什么?

下面是在文件目录下给mp3文件关联路径的方法。

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"Professor_and_the_Plant.mp3"];

NSURL *mp3_url = [[NSURL alloc] initFileURLWithPath:path];

NSURLAsset 默认为快速工作。如果长度或元数据不容易获得(即在 ID3 header 中),它不会产生它。要请求正确的数据,即使需要更长的时间,你也必须给它选项:

    static NSDictionary *options;
    if (!options) {
        NSNumber *val = [[NSNumber alloc] initWithBool: YES];
        options = [[NSDictionary alloc] initWithObjectsAndKeys:val, AVURLAssetPreferPreciseDurationAndTimingKey, nil];
    }
    AVAsset *asset = [[AVURLAsset alloc] initWithURL:url options:options];

(我将选项固定在静态中,这样我就不必继续重新创建和处理它。)

如果文档中的资产与应用程序包中的资产标记不同,这可能是您的问题。