Skip to content

Commit

Permalink
Merge pull request #206 from Kivenhaoyu/master
Browse files Browse the repository at this point in the history
phasset memory fix
  • Loading branch information
longbai authored Nov 2, 2016
2 parents 0c3344a + 9133b0a commit ba91cb5
Showing 1 changed file with 90 additions and 91 deletions.
181 changes: 90 additions & 91 deletions QiniuSDK/Common/QNPHAssetFile.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,10 @@
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
#import <AVFoundation/AVFoundation.h>
#import <Photos/Photos.h>
enum {
kAMASSETMETADATA_PENDINGREADS = 1,
kAMASSETMETADATA_ALLFINISHED = 0
};

#import "QNResponseInfo.h"

@interface QNPHAssetFile () {
BOOL _hasGotInfo;
}
@interface QNPHAssetFile ()

@property (nonatomic) PHAsset *phAsset;

Expand All @@ -32,6 +26,10 @@ @interface QNPHAssetFile () {

@property (nonatomic, strong) NSURL *assetURL;

@property (nonatomic, readonly) NSString *filepath;

@property (nonatomic) NSFileHandle *file;

@end

@implementation QNPHAssetFile
Expand All @@ -45,30 +43,69 @@ - (instancetype)init:(PHAsset *)phAsset error:(NSError *__autoreleasing *)error
}
_fileModifyTime = t;
_phAsset = phAsset;
[self getInfo];
_filepath = [self getInfo];
if (PHAssetMediaTypeVideo == self.phAsset.mediaType) {
NSError *error2 = nil;
NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:_filepath error:&error2];
if (error2 != nil) {
if (error != nil) {
*error = error2;
}
return self;
}
_fileSize = [fileAttr fileSize];
NSFileHandle *f = nil;
NSData *d = nil;
if (_fileSize > 16 * 1024 * 1024) {
f = [NSFileHandle fileHandleForReadingAtPath:_filepath];
if (f == nil) {
if (error != nil) {
*error = [[NSError alloc] initWithDomain:_filepath code:kQNFileError userInfo:nil];
}
return self;
}
} else {
d = [NSData dataWithContentsOfFile:_filepath options:NSDataReadingMappedIfSafe error:&error2];
if (error2 != nil) {
if (error != nil) {
*error = error2;
}
return self;
}
}
_file = f;
_assetData = d;
}

}
return self;
}

- (NSData *)read:(long)offset size:(long)size {
NSRange subRange = NSMakeRange(offset, size);
if (!self.assetData) {
self.assetData = [self fetchDataFromAsset:self.phAsset];
if (_assetData != nil) {
return [_assetData subdataWithRange:NSMakeRange(offset, (unsigned int)size)];
}
NSData *subData = [self.assetData subdataWithRange:subRange];

return subData;
[_file seekToFileOffset:offset];
return [_file readDataOfLength:size];
}

- (NSData *)readAll {
return [self read:0 size:(long)_fileSize];
}

- (void)close {
if (PHAssetMediaTypeVideo == self.phAsset.mediaType) {
if (_file != nil) {
[_file closeFile];

}
[[NSFileManager defaultManager] removeItemAtPath: _filepath error: nil];

}
}

- (NSString *)path {
return self.assetURL.path;
return _filepath;
}

- (int64_t)modifyTime {
Expand All @@ -79,91 +116,53 @@ - (int64_t)size {
return _fileSize;
}

- (void)getInfo {
if (!_hasGotInfo) {
_hasGotInfo = YES;

if (PHAssetMediaTypeImage == self.phAsset.mediaType) {
PHImageRequestOptions *request = [PHImageRequestOptions new];
request.version = PHImageRequestOptionsVersionCurrent;
request.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
request.resizeMode = PHImageRequestOptionsResizeModeNone;
request.synchronous = YES;
- (NSString *)getInfo {
__block NSString * filePath = nil;
if (PHAssetMediaTypeImage == self.phAsset.mediaType) {
PHImageRequestOptions *options = [PHImageRequestOptions new];
options.version = PHImageRequestOptionsVersionCurrent;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.resizeMode = PHImageRequestOptionsResizeModeNone;
//不支持icloud上传
options.networkAccessAllowed = NO;
options.synchronous = YES;

[[PHImageManager defaultManager] requestImageDataForAsset:self.phAsset
options:request
options:options
resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
_assetData = imageData;
_fileSize = imageData.length;
_assetURL = [NSURL URLWithString:self.phAsset.localIdentifier];
filePath = _assetURL.path;
}];
} else if (PHAssetMediaTypeVideo == self.phAsset.mediaType) {
PHVideoRequestOptions *request = [PHVideoRequestOptions new];
request.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
request.version = PHVideoRequestOptionsVersionCurrent;

NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS];
[[PHImageManager defaultManager] requestPlayerItemForVideo:self.phAsset options:request resultHandler:^(AVPlayerItem *playerItem, NSDictionary *info) {
AVURLAsset *urlAsset = (AVURLAsset *)playerItem.asset;
NSNumber *fileSize = nil;
[urlAsset.URL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil];
_fileSize = [fileSize unsignedLongLongValue];
_assetURL = urlAsset.URL;

[assetReadLock lock];
[assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED];
NSArray * assetResources = [PHAssetResource assetResourcesForAsset: self.phAsset];
PHAssetResource * resource;
for (PHAssetResource * assetRes in assetResources) {
if (assetRes.type == PHAssetResourceTypePairedVideo || assetRes.type == PHAssetResourceTypeVideo) {
resource = assetRes;
}
}
NSString * fileName = @"tempAssetVideo.mov";
if (resource.originalFilename) {
fileName = resource.originalFilename;
}
PHVideoRequestOptions * options = [[PHVideoRequestOptions alloc] init];
options.version = PHImageRequestOptionsVersionCurrent;
//不支持icloud上传
options.networkAccessAllowed = NO;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
NSString * PATH_VIDEO_FILE = [NSTemporaryDirectory() stringByAppendingPathComponent: fileName];
[[NSFileManager defaultManager] removeItemAtPath: PATH_VIDEO_FILE error: nil];
[[PHAssetResourceManager defaultManager] writeDataForAssetResource: resource toFile: [NSURL fileURLWithPath: PATH_VIDEO_FILE] options: options completionHandler: ^(NSError * _Nullable error) {
if (error) {
filePath = nil;
} else {
filePath = PATH_VIDEO_FILE;
}
}];
[assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED];
[assetReadLock unlock];
assetReadLock = nil;
}
}
}

- (NSData *)fetchDataFromAsset:(PHAsset *)asset {
__block NSData *tmpData = [NSData data];

// Image
if (asset.mediaType == PHAssetMediaTypeImage) {
PHImageRequestOptions *request = [PHImageRequestOptions new];
request.version = PHImageRequestOptionsVersionCurrent;
request.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
request.resizeMode = PHImageRequestOptionsResizeModeNone;
request.synchronous = YES;

[[PHImageManager defaultManager] requestImageDataForAsset:asset
options:request
resultHandler:
^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
tmpData = [NSData dataWithData:imageData];
}];
}
// Video
else {

PHVideoRequestOptions *request = [PHVideoRequestOptions new];
request.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
request.version = PHVideoRequestOptionsVersionCurrent;

NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS];

[[PHImageManager defaultManager] requestAVAssetForVideo:asset
options:request
resultHandler:
^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
AVURLAsset *urlAsset = (AVURLAsset *)asset;
NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL];
tmpData = [NSData dataWithData:videoData];

[assetReadLock lock];
[assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED];
}];

[assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED];
[assetReadLock unlock];
assetReadLock = nil;
}

return tmpData;
return filePath;
}

@end
Expand Down

0 comments on commit ba91cb5

Please sign in to comment.