TXUGCPublishUtil.m 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #import <Foundation/Foundation.h>
  2. #import <AVFoundation/AVFoundation.h>
  3. #import <CommonCrypto/CommonDigest.h>
  4. #import <CoreMedia/CoreMedia.h>
  5. #import <ImageIO/ImageIO.h>
  6. #import <UIKit/UIKit.h>
  7. #import "TXUGCPublishUtil.h"
  8. #undef _MODULE_
  9. #define _MODULE_ "TXUGCPublishUtil"
  10. #define degreesToRadians( degrees ) ( ( degrees ) / 180.0 * M_PI )
  11. @implementation TXUGCPublishUtil
  12. +(CMSampleBufferRef)createAudioSample:(void *)audioData
  13. size:(UInt32)len
  14. timingInfo:(CMSampleTimingInfo)info
  15. numberChannels:(int)channels
  16. SampleRate:(int)sampleRate
  17. {
  18. AudioBufferList audioBufferList;
  19. audioBufferList.mNumberBuffers = 1;
  20. audioBufferList.mBuffers[0].mNumberChannels=channels;
  21. audioBufferList.mBuffers[0].mDataByteSize=len;
  22. audioBufferList.mBuffers[0].mData = audioData;
  23. AudioStreamBasicDescription asbd;
  24. asbd.mSampleRate = sampleRate;
  25. asbd.mFormatID = kAudioFormatLinearPCM;
  26. asbd.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
  27. asbd.mBytesPerPacket = 2*channels;
  28. asbd.mFramesPerPacket = 1;
  29. asbd.mBytesPerFrame = 2*channels;
  30. asbd.mChannelsPerFrame = channels;
  31. asbd.mBitsPerChannel = 16;
  32. asbd.mReserved = 0;
  33. CMSampleBufferRef buff = NULL;
  34. CMFormatDescriptionRef format = NULL;
  35. OSStatus error = 0;
  36. error = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &asbd, 0, NULL, 0, NULL, NULL, &format);
  37. error = CMSampleBufferCreate(kCFAllocatorDefault, NULL, false, NULL, NULL, format, len/(2*channels), 1, &info, 0, NULL, &buff);
  38. CFRelease(format);
  39. if ( error ) {
  40. return NULL;
  41. }
  42. error = CMSampleBufferSetDataBufferFromAudioBufferList(buff, kCFAllocatorDefault, kCFAllocatorDefault, 0, &audioBufferList);
  43. if( error )
  44. {
  45. CFRelease(buff);
  46. return NULL;
  47. }
  48. return buff;
  49. }
  50. +(NSString*) getFileSHA1Signature:(NSString*)filePath
  51. {
  52. if (filePath == nil) {
  53. return nil;
  54. }
  55. if (NO == [[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
  56. return nil;
  57. }
  58. CFStringRef strSHA1Ref = NULL;
  59. CFURLRef fileURL = NULL;
  60. CFReadStreamRef readStream = NULL;
  61. do {
  62. fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)filePath, kCFURLPOSIXPathStyle, (Boolean)false);
  63. if (!fileURL) {
  64. break;
  65. }
  66. readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL);
  67. if (!readStream) {
  68. break;
  69. }
  70. bool openSuccess = (bool)CFReadStreamOpen(readStream);
  71. if (!openSuccess) {
  72. break;
  73. }
  74. CC_SHA1_CTX sha1Ctx;
  75. CC_SHA1_Init(&sha1Ctx);
  76. size_t chunkSizeForReadingData = 1024 * 8;
  77. uint8_t buffer[chunkSizeForReadingData];
  78. bool hasMoreData = true;
  79. while (hasMoreData) {
  80. memset(buffer, 0, sizeof(buffer));
  81. CFIndex readBytesCount = CFReadStreamRead(readStream, (UInt8*)buffer, (CFIndex)sizeof(buffer));
  82. if (readBytesCount == -1) {
  83. break;
  84. }
  85. if (readBytesCount == 0) {
  86. hasMoreData = false;
  87. continue;
  88. }
  89. CC_SHA1_Update(&sha1Ctx, (const void*)buffer, (CC_LONG)readBytesCount);
  90. }
  91. unsigned char digest[CC_SHA1_DIGEST_LENGTH];
  92. CC_SHA1_Final(digest, &sha1Ctx);
  93. if (hasMoreData) {
  94. break;
  95. }
  96. char hash[2 * sizeof(digest) + 1] = {0};
  97. for (size_t i = 0; i < sizeof(digest); ++i) {
  98. sprintf(hash + (2 * i), "%02x", (int)(digest[i]));
  99. }
  100. strSHA1Ref = CFStringCreateWithCString(kCFAllocatorDefault,
  101. (const char *)hash,
  102. kCFStringEncodingUTF8);
  103. } while (0);
  104. if (fileURL) {
  105. CFRelease(fileURL);
  106. }
  107. if (readStream) {
  108. CFReadStreamClose(readStream);
  109. CFRelease(readStream);
  110. }
  111. return (__bridge_transfer NSString *)strSHA1Ref;
  112. }
  113. +(NSString*) renameFile:(NSString*)filePath newFileName:(NSString*)newName {
  114. if (filePath == nil || [[NSFileManager defaultManager] fileExistsAtPath:filePath] != YES) {
  115. NSLog(@"rename file failed, file not exist [%s]", filePath == nil ? "" : [filePath UTF8String]);
  116. return nil;
  117. }
  118. if (newName == nil) {
  119. NSLog(@"rename file failed, invalid fileName");
  120. return nil;
  121. }
  122. NSString * newFileName = [NSString stringWithFormat:@"%@.%@", newName, [filePath pathExtension]];
  123. NSString * newFilePath = [filePath stringByDeletingLastPathComponent];
  124. newFilePath = [newFilePath stringByAppendingPathComponent:newFileName];
  125. NSError * error;
  126. if ([[NSFileManager defaultManager] fileExistsAtPath:newFilePath] == YES) {
  127. [[NSFileManager defaultManager] removeItemAtPath:newFilePath error:&error];
  128. }
  129. if ([[NSFileManager defaultManager] moveItemAtPath:filePath toPath:newFilePath error:&error]!= YES) {
  130. NSLog(@"rename file failed: %@", [error localizedDescription]);
  131. return nil;
  132. }
  133. return newFilePath;
  134. }
  135. +(void) removeCacheFile:(NSString*)filePath {
  136. if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] == YES) {
  137. [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; //发布成功,删除视频文件
  138. }
  139. }
  140. +(void)clearFileType:(NSArray*)extensions AtFolderPath:(NSString*)path
  141. {
  142. NSFileManager *fileManager = [NSFileManager defaultManager];
  143. NSArray *contents = [fileManager contentsOfDirectoryAtPath:path error:NULL];
  144. NSEnumerator *e = [contents objectEnumerator];
  145. NSString *filename;
  146. while ((filename = [e nextObject])) {
  147. for(int i=0; i<extensions.count; ++i)
  148. {
  149. if ([[filename pathExtension] isEqualToString:extensions[i]]) {
  150. [fileManager removeItemAtPath:[path stringByAppendingPathComponent:filename] error:NULL];
  151. }
  152. }
  153. }
  154. }
  155. +(NSString*)getCacheFolderPath
  156. {
  157. return [NSTemporaryDirectory() stringByAppendingPathComponent:@"TXUGC"];
  158. }
  159. +(NSString *)getFileNameByTimeNow:(NSString *)type fileType:(NSString *)fileType {
  160. NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
  161. NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
  162. [formatter setDateFormat:@"yyyyMMdd_HHmmss"];
  163. NSDate * NowDate = [NSDate dateWithTimeIntervalSince1970:now];
  164. ;
  165. NSString * timeStr = [formatter stringFromDate:NowDate];
  166. NSString *fileName = ((fileType == nil) ||
  167. (fileType.length == 0)
  168. ) ? [NSString stringWithFormat:@"%@_%@",type,timeStr] : [NSString stringWithFormat:@"%@_%@.%@",type,timeStr,fileType];
  169. return fileName;
  170. }
  171. +(UIImage*)imageFromPixelBuffer:(CVPixelBufferRef)pixelBuffer
  172. {
  173. CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
  174. CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
  175. CIContext *temporaryContext = [CIContext contextWithOptions:nil];
  176. CGImageRef videoImage = [temporaryContext createCGImage:ciImage
  177. fromRect:CGRectMake(0,
  178. 0,
  179. CVPixelBufferGetWidth(pixelBuffer),
  180. CVPixelBufferGetHeight(pixelBuffer)
  181. )];
  182. UIImage *image = [[UIImage alloc] initWithCGImage:videoImage];
  183. CGImageRelease(videoImage);
  184. CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
  185. return image;
  186. }
  187. +(int)savePixelBuffer:(CVPixelBufferRef)pixelBuffer ToJPEGPath:(NSString*)path
  188. {
  189. [TXUGCPublishUtil save:[TXUGCPublishUtil imageFromPixelBuffer:pixelBuffer] ToPath:path];
  190. return 0;
  191. }
  192. +(void)checkVideoPath:(NSString *)videoPath
  193. {
  194. NSFileManager *manager = [[NSFileManager alloc] init];
  195. if ([manager fileExistsAtPath:videoPath]) {
  196. BOOL success = [manager removeItemAtPath:videoPath error:nil];
  197. if (success) {
  198. //LOGD("Already exist. Removed!");
  199. }
  200. }
  201. }
  202. +(void)save:(UIImage*)uiImage ToPath:(NSString*)path
  203. {
  204. if (uiImage && path) {
  205. // 保证目录存在
  206. [[NSFileManager defaultManager] createDirectoryAtPath:[path stringByDeletingLastPathComponent]
  207. withIntermediateDirectories:YES
  208. attributes:nil
  209. error:nil];
  210. [UIImageJPEGRepresentation(uiImage, 1.0) writeToFile:path atomically:YES];
  211. }
  212. }
  213. +(UIImage *)loadThumbNail:(NSURL *)urlVideo
  214. {
  215. AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:urlVideo options:nil];
  216. AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
  217. generate.appliesPreferredTrackTransform= YES;
  218. NSError *err = NULL;
  219. CMTime time = CMTimeMake(15, 30);
  220. CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:nil error:&err];
  221. UIImage *image = [[UIImage alloc] initWithCGImage:imgRef];
  222. return image;
  223. }
  224. @end