- (void)getDurationWithCompletion:(void(^)(NSTimeInterval duration))comp { NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; AVURLAsset *audioAsset = [[[AVURLAsset alloc] initWithURL:_url options:options] autorelease]; NSArray *keys = [[NSArray alloc] initWithObjects:@"duration", nil]; [audioAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{ NSError *error = nil; switch ([audioAsset statusOfValueForKey:@"duration" error:&error]) { caseAVKeyValueStatusLoaded:{ CMTime audioDuration = audioAsset.duration; NSTimeInterval duration = CMTimeGetSeconds(audioDuration); if (comp) { dispatch_async(dispatch_get_main_queue(),^{ comp(duration); }); } } // duration is now known, so we can fetch it without blocking // CMTime duration = [asset duration]; // dispatch a block to the main thread that updates the display of asset duration in my user interface, // or do something else interesting with it default: ; // something went wrong; depending on what it was, we may want to dispatch a // block to the main thread to report th e error } }]; }