QNPHAssetFile.m 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //
  2. // QNPHAssetFile.m
  3. // Pods
  4. //
  5. // Created by 何舒 on 15/10/21.
  6. //
  7. //
  8. #import "QNPHAssetFile.h"
  9. #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
  10. #import <AVFoundation/AVFoundation.h>
  11. #import <Photos/Photos.h>
  12. #import "QNResponseInfo.h"
  13. @interface QNPHAssetFile ()
  14. @property (nonatomic) PHAsset *phAsset;
  15. @property (readonly) int64_t fileSize;
  16. @property (readonly) int64_t fileModifyTime;
  17. @property (nonatomic, strong) NSData *assetData;
  18. @property (nonatomic, strong) NSURL *assetURL;
  19. @property (nonatomic, readonly) NSString *filepath;
  20. @property (nonatomic) NSFileHandle *file;
  21. @end
  22. @implementation QNPHAssetFile
  23. - (instancetype)init:(PHAsset *)phAsset error:(NSError *__autoreleasing *)error {
  24. if (self = [super init]) {
  25. NSDate *createTime = phAsset.creationDate;
  26. int64_t t = 0;
  27. if (createTime != nil) {
  28. t = [createTime timeIntervalSince1970];
  29. }
  30. _fileModifyTime = t;
  31. _phAsset = phAsset;
  32. _filepath = [self getInfo];
  33. if (PHAssetMediaTypeVideo == self.phAsset.mediaType) {
  34. NSError *error2 = nil;
  35. NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:_filepath error:&error2];
  36. if (error2 != nil) {
  37. if (error != nil) {
  38. *error = error2;
  39. }
  40. return self;
  41. }
  42. _fileSize = [fileAttr fileSize];
  43. NSFileHandle *f = nil;
  44. NSData *d = nil;
  45. if (_fileSize > 16 * 1024 * 1024) {
  46. f = [NSFileHandle fileHandleForReadingAtPath:_filepath];
  47. if (f == nil) {
  48. if (error != nil) {
  49. *error = [[NSError alloc] initWithDomain:_filepath code:kQNFileError userInfo:nil];
  50. }
  51. return self;
  52. }
  53. } else {
  54. d = [NSData dataWithContentsOfFile:_filepath options:NSDataReadingMappedIfSafe error:&error2];
  55. if (error2 != nil) {
  56. if (error != nil) {
  57. *error = error2;
  58. }
  59. return self;
  60. }
  61. }
  62. _file = f;
  63. _assetData = d;
  64. }
  65. }
  66. return self;
  67. }
  68. - (NSData *)read:(long)offset size:(long)size {
  69. if (_assetData != nil) {
  70. return [_assetData subdataWithRange:NSMakeRange(offset, (unsigned int)size)];
  71. }
  72. [_file seekToFileOffset:offset];
  73. return [_file readDataOfLength:size];
  74. }
  75. - (NSData *)readAll {
  76. return [self read:0 size:(long)_fileSize];
  77. }
  78. - (void)close {
  79. if (PHAssetMediaTypeVideo == self.phAsset.mediaType) {
  80. if (_file != nil) {
  81. [_file closeFile];
  82. }
  83. [[NSFileManager defaultManager] removeItemAtPath:_filepath error:nil];
  84. }
  85. }
  86. - (NSString *)path {
  87. return _filepath;
  88. }
  89. - (int64_t)modifyTime {
  90. return _fileModifyTime;
  91. }
  92. - (int64_t)size {
  93. return _fileSize;
  94. }
  95. - (NSString *)getInfo {
  96. __block NSString *filePath = nil;
  97. if (PHAssetMediaTypeImage == self.phAsset.mediaType) {
  98. PHImageRequestOptions *options = [PHImageRequestOptions new];
  99. options.version = PHImageRequestOptionsVersionCurrent;
  100. options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
  101. options.resizeMode = PHImageRequestOptionsResizeModeNone;
  102. //不支持icloud上传
  103. options.networkAccessAllowed = NO;
  104. options.synchronous = YES;
  105. [[PHImageManager defaultManager] requestImageDataForAsset:self.phAsset
  106. options:options
  107. resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
  108. _assetData = imageData;
  109. _fileSize = imageData.length;
  110. _assetURL = [NSURL URLWithString:self.phAsset.localIdentifier];
  111. filePath = _assetURL.path;
  112. }];
  113. } else if (PHAssetMediaTypeVideo == self.phAsset.mediaType) {
  114. NSArray *assetResources = [PHAssetResource assetResourcesForAsset:self.phAsset];
  115. PHAssetResource *resource;
  116. for (PHAssetResource *assetRes in assetResources) {
  117. if (assetRes.type == PHAssetResourceTypePairedVideo || assetRes.type == PHAssetResourceTypeVideo) {
  118. resource = assetRes;
  119. }
  120. }
  121. NSString *fileName = @"tempAssetVideo.mov";
  122. if (resource.originalFilename) {
  123. fileName = resource.originalFilename;
  124. }
  125. PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new];
  126. //不支持icloud上传
  127. options.networkAccessAllowed = NO;
  128. NSString *PATH_VIDEO_FILE = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
  129. [[NSFileManager defaultManager] removeItemAtPath:PATH_VIDEO_FILE error:nil];
  130. [[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource toFile:[NSURL fileURLWithPath:PATH_VIDEO_FILE] options:options completionHandler:^(NSError *_Nullable error) {
  131. if (error) {
  132. filePath = nil;
  133. } else {
  134. filePath = PATH_VIDEO_FILE;
  135. }
  136. }];
  137. }
  138. return filePath;
  139. }
  140. @end
  141. #endif