Я пытаюсь создать AVURLAsset из mp4 в памяти. Итак, я создал реализацию AVAssetResourceLoaderDelegate.
@interface RLDelegate : NSObject <AVAssetResourceLoaderDelegate>
- (instancetype)initWithData:(NSData *)data contentType:(NSString *)contentType;
@end
@interface RLDelegate()
@property (nonatomic) NSData *data;
@property (nonatomic) NSString *contentType;
@end
@implementation RLDelegate
- (instancetype)initWithData:(NSData *)data contentType:(NSString *)contentType {
if (self = [super init]) {
self.data = [data copy];
self.contentType = contentType;
}
return self;
}
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
if (!self->_data)
return NO;
NSString * scheme = loadingRequest.request.URL.scheme;
AVAssetResourceLoadingContentInformationRequest* contentRequest = loadingRequest.contentInformationRequest;
if (contentRequest) {
contentRequest.contentType = self.contentType;
contentRequest.contentLength = self.data.length;
contentRequest.byteRangeAccessSupported = NO;
}
AVAssetResourceLoadingDataRequest* dataRequest = loadingRequest.dataRequest;
if (dataRequest) {
if (dataRequest.requestsAllDataToEndOfResource)
{
[dataRequest respondWithData:[self.data copy]];
}
else
{
NSRange range = NSMakeRange((NSUInteger)dataRequest.requestedOffset, (NSUInteger)dataRequest.requestedLength);
[dataRequest respondWithData:[[self.data subdataWithRange:range] copy]];
}
[loadingRequest finishLoading];
return YES;
}
return NO;
}
@end
Я использую его для чтения MP4 следующим образом:
void AssetFromMP4Data(NSData* videData)
{
@autoreleasepool {
tetRLDelegate = [[RLDelegate alloc] initWithData:videData contentType:AVFileTypeMPEG4];
NSURL *url = [NSURL URLWithString:@"tetData://"];
asset = [[AVURLAsset alloc] initWithURL:url options:nil];
loaderQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// or some other queue != main queue
[asset.resourceLoader setDelegate:tetRLDelegate queue:loaderQueue];
}
}
Я могу читать кадры из видео трек. Однако память других процессов постоянно увеличивается до тех пор, пока не израсходует всю память устройства. Я считаю, что этот делегат загрузчика является причиной, потому что до того, как я использовал делегат загрузчика, я бы записал NSDATA в файл и прочитал его с помощью AVAsset, используя диск вместо чтения непосредственно из NSData. Это сработало без проблем с памятью, но читать такие файлы MP4 не идеально, нужно сначала записывать их на диск.
Есть предложения, откуда берутся утечки памяти других процессов? Я также не вижу утечки памяти из моего собственного приложения с инструментарием Xcode.