这个问题已经在这里进行了几次,但我仍然没有在任何地方看到任何答案。这已经杀了我几个小时了,我在这里得到一些帮助。我有以下代码:
NSURL *url = [NSURL URLWithString:sourceVideoName];
NSDictionary *options = @{ AVURLAssetPreferPreciseDurationAndTimingKey: @YES };
PHFetchResult *ph_fetch = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
PHAsset *ph_asset = [ph_fetch firstObject];
RCTLogInfo(@"Now we have PHAsset:\n%@", ph_asset);
[[PHImageManager defaultManager] requestAVAssetForVideo:ph_asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
RCTLogInfo(@"Now we have AVAsset:\n%@", asset);
NSError *error = nil;
AVKeyValueStatus tracksStatus = [asset statusOfValueForKey:@"tracks" error:&error];
switch (tracksStatus) {
case AVKeyValueStatusCancelled:
[self log:@"Early Tracks Canceled"];
break;
case AVKeyValueStatusLoading:
[self log:@"Early Tracks Loading"];
break;
case AVKeyValueStatusLoaded:
[self log:@"Early Tracks Loaded"];
break;
case AVKeyValueStatusFailed:
[self log:@"Early Tracks Failed"];
break;
case AVKeyValueStatusUnknown:
[self log:@"Early Tracks Unknown"];
break;
}
[asset loadValuesAsynchronouslyForKeys:@[@"tracks", @"duration"] completionHandler:^() {
RCTLogInfo(@"We finally have a track callback???");
}];
}];
当然,我们从未真正执行最终的回调。我不知道为什么也不知道如何解决它。
答案 0 :(得分:0)
对我的问题的评论让我深入了解答案。基本版本是在回调执行之前,asset
似乎从内存中释放出来。
ARC为属性提供了更强的内存保留,因此这可以通过添加到标题中的接口定义来实现:
@property AVAsset *asset;
@property PHAsset *photoAsset;
并将上述问题中的代码转换为:
NSURL *url = [NSURL URLWithString:sourceVideoName];
NSDictionary *options = @{ AVURLAssetPreferPreciseDurationAndTimingKey: @YES };
PHFetchResult *ph_fetch = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
[self setPhotoAsset:[ph_fetch firstObject]];
RCTLogInfo(@"Now we have instance PHAsset:\n%@", [self photoAsset]);
[[PHImageManager defaultManager] requestAVAssetForVideo:[self photoAsset] options:nil resultHandler:^(AVAsset * _Nullable localAsset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
RCTLogInfo(@"Now we have local AVAsset:\n%@", localAsset);
[self setAsset:localAsset];
RCTLogInfo(@"Now we have instance AVAsset:\n%@", [self asset ]);
NSError *error = nil;
AVKeyValueStatus tracksStatus = [[self asset] statusOfValueForKey:@"tracks" error:&error];
switch (tracksStatus) {
case AVKeyValueStatusCancelled:
[self log:@"Early Tracks Canceled"];
break;
case AVKeyValueStatusLoading:
[self log:@"Early Tracks Loading"];
break;
case AVKeyValueStatusLoaded:
[self log:@"Early Tracks Loaded"];
break;
case AVKeyValueStatusFailed:
[self log:@"Early Tracks Failed"];
break;
case AVKeyValueStatusUnknown:
[self log:@"Early Tracks Unknown"];
break;
}
[[self asset] loadValuesAsynchronouslyForKeys:@[@"tracks", @"duration"] completionHandler:^() {
RCTLogInfo(@"We finally have a track callback!!!");
}];
}];