QNPHAssetResource.m 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //
  2. // QNPHAssetResource.m
  3. // QiniuSDK
  4. //
  5. // Created by 何舒 on 16/2/14.
  6. // Copyright © 2016年 Qiniu. All rights reserved.
  7. //
  8. #import "QNPHAssetResource.h"
  9. #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100)
  10. #import <AVFoundation/AVFoundation.h>
  11. #import <Photos/Photos.h>
  12. enum {
  13. kAMASSETMETADATA_PENDINGREADS = 1,
  14. kAMASSETMETADATA_ALLFINISHED = 0
  15. };
  16. #import "QNResponseInfo.h"
  17. @interface QNPHAssetResource ()
  18. {
  19. BOOL _hasGotInfo;
  20. }
  21. @property (nonatomic) PHAsset *phAsset;
  22. @property (nonatomic) PHLivePhoto *phLivePhoto;
  23. @property (nonatomic) PHAssetResource *phAssetResource;
  24. @property (readonly) int64_t fileSize;
  25. @property (readonly) int64_t fileModifyTime;
  26. @property (nonatomic, strong) NSData *assetData;
  27. @property (nonatomic, strong) NSURL *assetURL;
  28. @end
  29. @implementation QNPHAssetResource
  30. - (instancetype)init:(PHAssetResource *)phAssetResource
  31. error:(NSError *__autoreleasing *)error {
  32. if (self = [super init]) {
  33. PHAsset *phasset = [PHAsset fetchAssetsWithBurstIdentifier:self.phAssetResource.assetLocalIdentifier options:nil][0];
  34. NSDate *createTime = phasset.creationDate;
  35. int64_t t = 0;
  36. if (createTime != nil) {
  37. t = [createTime timeIntervalSince1970];
  38. }
  39. _fileModifyTime = t;
  40. _phAssetResource = phAssetResource;
  41. [self getInfo];
  42. }
  43. return self;
  44. }
  45. - (NSData *)read:(long)offset size:(long)size {
  46. NSRange subRange = NSMakeRange(offset, size);
  47. if (!self.assetData) {
  48. self.assetData = [self fetchDataFromAsset:self.phAssetResource];
  49. }
  50. NSData *subData = [self.assetData subdataWithRange:subRange];
  51. return subData;
  52. }
  53. - (NSData *)readAll {
  54. return [self read:0 size:(long)_fileSize];
  55. }
  56. - (void)close {
  57. }
  58. - (NSString *)path {
  59. return self.assetURL.path;
  60. }
  61. - (int64_t)modifyTime {
  62. return _fileModifyTime;
  63. }
  64. - (int64_t)size {
  65. return _fileSize;
  66. }
  67. - (void)getInfo {
  68. if (!_hasGotInfo) {
  69. _hasGotInfo = YES;
  70. NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS];
  71. NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:self.phAssetResource.originalFilename];
  72. NSURL *localpath = [NSURL fileURLWithPath:pathToWrite];
  73. PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new];
  74. options.networkAccessAllowed = YES;
  75. [[PHAssetResourceManager defaultManager] writeDataForAssetResource:self.phAssetResource toFile:localpath options:options completionHandler:^(NSError *_Nullable error) {
  76. if (error == nil) {
  77. AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:localpath options:nil];
  78. NSNumber *fileSize = nil;
  79. [urlAsset.URL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil];
  80. _fileSize = [fileSize unsignedLongLongValue];
  81. _assetURL = urlAsset.URL;
  82. self.assetData = [NSData dataWithData:[NSData dataWithContentsOfURL:urlAsset.URL]];
  83. } else {
  84. NSLog(@"%@", error);
  85. }
  86. BOOL blHave = [[NSFileManager defaultManager] fileExistsAtPath:pathToWrite];
  87. if (!blHave) {
  88. NSLog(@"no have");
  89. return;
  90. } else {
  91. NSLog(@" have");
  92. BOOL blDele = [[NSFileManager defaultManager] removeItemAtPath:pathToWrite error:nil];
  93. if (blDele) {
  94. NSLog(@"dele success");
  95. } else {
  96. NSLog(@"dele fail");
  97. }
  98. }
  99. [assetReadLock lock];
  100. [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED];
  101. }];
  102. [assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED];
  103. [assetReadLock unlock];
  104. assetReadLock = nil;
  105. }
  106. }
  107. - (NSData *)fetchDataFromAsset:(PHAssetResource *)videoResource {
  108. __block NSData *tmpData = [NSData data];
  109. NSConditionLock *assetReadLock = [[NSConditionLock alloc] initWithCondition:kAMASSETMETADATA_PENDINGREADS];
  110. NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:videoResource.originalFilename];
  111. NSURL *localpath = [NSURL fileURLWithPath:pathToWrite];
  112. PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new];
  113. options.networkAccessAllowed = YES;
  114. [[PHAssetResourceManager defaultManager] writeDataForAssetResource:videoResource toFile:localpath options:options completionHandler:^(NSError *_Nullable error) {
  115. if (error == nil) {
  116. AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:localpath options:nil];
  117. NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL];
  118. tmpData = [NSData dataWithData:videoData];
  119. } else {
  120. NSLog(@"%@", error);
  121. }
  122. BOOL blHave = [[NSFileManager defaultManager] fileExistsAtPath:pathToWrite];
  123. if (!blHave) {
  124. NSLog(@"no have");
  125. return;
  126. } else {
  127. NSLog(@" have");
  128. BOOL blDele = [[NSFileManager defaultManager] removeItemAtPath:pathToWrite error:nil];
  129. if (blDele) {
  130. NSLog(@"dele success");
  131. } else {
  132. NSLog(@"dele fail");
  133. }
  134. }
  135. [assetReadLock lock];
  136. [assetReadLock unlockWithCondition:kAMASSETMETADATA_ALLFINISHED];
  137. }];
  138. [assetReadLock lockWhenCondition:kAMASSETMETADATA_ALLFINISHED];
  139. [assetReadLock unlock];
  140. assetReadLock = nil;
  141. return tmpData;
  142. }
  143. @end
  144. #endif