视频分解图片,图片合成视频

 

转载自: http://blog.csdn.net/ioswyl88219/article/details/18152419

工作当中用到了相关的技术,现在特别记录一下


分解视频

  1. <span style="font-size:18px;">  
  2. //分解视频  
  3. - (void)resolveMovWithUrl:(NSURL *)movUrl{  
  4.       
  5.     //得到url的资源,转为asset  
  6.     AVAsset *myAsset = [[AVURLAsset alloc] initWithURL:movUrl options:nil];  
  7.     NSParameterAssert(myAsset);  
  8.       
  9.     //初始化AVAssetImageGenerator  
  10.     self.imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:myAsset] ;  
  11.     self.imageGenerator.appliesPreferredTrackTransform = YES;//加这句话,取出的是正确方向的图片  
  12.     self.imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;  
  13.     self.imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;  
  14.       
  15.     //得到秒数  
  16.     Float64 _durationSeconds = CMTimeGetSeconds([myAsset duration]);  
  17.       
  18.     __block float Second = 0.0;  
  19.     __block int num = 0;  
  20.       
  21.     NSString *path = [self backPath];  
  22.     NSLog(@"%@",path);  
  23.       
  24.     dispatch_semaphore_t sem = dispatch_semaphore_create(0);  
  25.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{  
  26.           
  27.         dispatch_async(dispatch_get_main_queue(), ^{  
  28.             [MBProgressHUD showHUDAddedTo:self.view animated:YES];  
  29.         });  
  30.           
  31.         while ((_durationSeconds - Second)>0) {  
  32.   
  33.             NSLog(@"%f",_durationSeconds - Second);  
  34.             CMTime rTime = CMTimeMakeWithSeconds(Second, NSEC_PER_SEC);  
  35.               
  36.             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{  
  37.                 @autoreleasepool  
  38.                 {  
  39.                     //根据帧数取出图片  
  40.                     CGImageRef image= [self.imageGenerator copyCGImageAtTime:rTime actualTime:NULL error:NULL];  
  41.                     if (image)  
  42.                     {  
  43.                         UIImage *img = [[UIImage alloc] initWithCGImage:image];  
  44.                         NSData *imageData = UIImagePNGRepresentation(img);  
  45.                           
  46.                           
  47.                         NSString *pathNum = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",num]];  
  48.                         [imageData writeToFile:pathNum atomically:NO];  
  49.                           
  50.                           
  51.                         CGImageRelease(image);  
  52.                           
  53.                         NSString *actualTimeString =CFBridgingRelease(CMTimeCopyDescription(NULL, rTime));  
  54.                         NSLog(@"photo:%d",num);  
  55.                         NSLog(@"%@",actualTimeString);  
  56.                           
  57.                         //调用dispatch_semaphore_signal函数,使计数器+1  
  58.                         dispatch_semaphore_signal(sem);  
  59.                     }else{  
  60.                         dispatch_async(dispatch_get_main_queue(), ^{  
  61.                             [MBProgressHUD hideAllHUDsForView:self.view animated:YES];  
  62.                               
  63.                         });  
  64.                     }  
  65.                       
  66.                 }  
  67.             });  
  68.             Second +=0.083;  
  69.             //一直等待,直到信号量计数器大于等于1  
  70.             dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);  
  71.             num+=1;  
  72.         }  
  73.         dispatch_async(dispatch_get_main_queue(), ^{  
  74.             num = 0;  
  75.             Second = 0.0;  
  76.             [MBProgressHUD hideAllHUDsForView:self.view animated:YES];  
  77.         });  
  78.     });  
  79.   
  80. }</span>  



图片合成视频

    1. <span style="font-size:18px;">  
    2.   
    3. - (void)initRecord  
    4. {  
    5.     //是否是第一次添加图片  
    6.     self.firstImgAdded = FALSE;  
    7.       
    8.     //video路径  
    9.     NSString* fileName = [NSString stringWithFormat:@"%d.mov", (int)[[NSDate date] timeIntervalSince1970]];  
    10.     self.videoPath = [NSString stringWithFormat:@"%@/%@", [self getLibarayPath], fileName];  
    11.       
    12.     //设置一个gcd队列  
    13.     writeQueue = dispatch_queue_create("recording_queue", DISPATCH_QUEUE_PRIORITY_DEFAULT);  
    14.       
    15.     CGSize frameSize = imageRect.size;  
    16.       
    17.     NSError* error = nil;  
    18.       
    19.     //创建写入对象  
    20.     self.videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:self.videoPath] fileType:AVFileTypeQuickTimeMovie error:&error];  
    21.       
    22.     //如果出错,打印错误内容  
    23.     if(error)  
    24.     {  
    25.         NSLog(@"error creating AssetWriter: %@",[error description]);  
    26.         self.videoWriter = nil;  
    27.         return;  
    28.     }  
    29.       
    30.     //设置参数  
    31.     NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:  
    32.                                    AVVideoCodecH264, AVVideoCodecKey,  
    33.                                    [NSNumber numberWithInt:frameSize.width], AVVideoWidthKey,  
    34.                                    [NSNumber numberWithInt:frameSize.height], AVVideoHeightKey,  
    35.                                    nil nil];  
    36.       
    37.     //输入对象  
    38.     self.writerInput = [AVAssetWriterInput  
    39.                         assetWriterInputWithMediaType:AVMediaTypeVideo  
    40.                         outputSettings:videoSettings];  
    41.       
    42.     //属性设置  
    43.     NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];  
    44.     [attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];  
    45.     [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey];  
    46.     [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey];  
    47.       
    48.     //通过属性和writerInput 创建一个新的Adaptor  
    49.     self.adaptor = [AVAssetWriterInputPixelBufferAdaptor  
    50.                     assetWriterInputPixelBufferAdaptorWithAssetWriterInput:self.writerInput  
    51.                     sourcePixelBufferAttributes:attributes];  
    52.       
    53.     //添加输入,必须在开始写入之前  
    54.     [self.videoWriter addInput:self.writerInput];  
    55.       
    56.     self.writerInput.expectsMediaDataInRealTime = YES;  
    57.       
    58.     //开始写入  
    59.     [self.videoWriter startWriting];  
    60.     [self.videoWriter startSessionAtSourceTime:kCMTimeZero];  
    61. }  
    62.   
    63. #pragma mark - 视频合成  
    64. static int count = 0;  
    65. - (void)startCamera  
    66. {  
    67.       
    68.     NSMutableArray *arr = [self allFilesAtPath:[self backPath]];  
    69.       
    70.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    71.           
    72.         dispatch_async(dispatch_get_main_queue(), ^{  
    73.             [MBProgressHUD showHUDAddedTo:self.view animated:YES];  
    74.         });  
    75.           
    76.         while (arr.count -count) {  
    77.             UIImage *image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%d.png",[self backPath],count]];  
    78.             CGImageRef image1 = image.CGImage;  
    79.             [self writeImage:image1 withIndex:count];  
    80.             NSLog(@"%d",count);  
    81.             count ++;  
    82.         }  
    83.   
    84.           
    85.         [self.writerInput markAsFinished];  
    86.         [self.videoWriter finishWriting];  
    87.           
    88. //        [self combineWithAudio:num];  
    89.         dispatch_async(dispatch_get_main_queue(), ^{  
    90.             count = 0;  
    91.             [MBProgressHUD hideAllHUDsForView:self.view animated:YES];  
    92.         });  
    93.           
    94.     });  
    95. }  
    96.   
    97. - (void)writeImage:(CGImageRef)img withIndex:(NSInteger)curCount  
    98. {  
    99.     CVPixelBufferRef buffer = NULL;  
    100.     if (self.videoWriter == nil)  
    101.     {  
    102.         NSLog(@"error~~~~~~~~~~~");  
    103.     }  
    104.     if (self.firstImgAdded == FALSE)  
    105.     {  
    106.         buffer = [self pixelBufferFromCGImage:img];  
    107.         BOOL result = [self.adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];  
    108.         if (result == NO) //failes on 3GS, but works on iphone 4  
    109.         {  
    110.             NSLog(@"failed to append buffer");  
    111.         }  
    112.         if(buffer)  
    113.         {  
    114.             CVBufferRelease(buffer);  
    115.         }  
    116.         self.firstImgAdded = TRUE;  
    117.     }  
    118.     else  
    119.     {  
    120.         if (self.adaptor.assetWriterInput.readyForMoreMediaData)  
    121.         {  
    122.             CMTime frameTime = CMTimeMake(1, FramePerSec);  
    123.             CMTime lastTime = CMTimeMake(curCount, FramePerSec);  
    124.             CMTime presentTime = CMTimeAdd(lastTime, frameTime);  
    125.               
    126.             buffer = [self pixelBufferFromCGImage:img];  
    127.             BOOL result = [self.adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];  
    128.               
    129.             if (result == NO) //failes on 3GS, but works on iphone 4  
    130.             {  
    131.                 NSLog(@"failed to append buffer");  
    132.                 NSLog(@"The error is %@", [self.videoWriter error]);  
    133.             }  
    134.             else  
    135.             {  
    136.                 NSLog(@"write ok");  
    137.             }  
    138.             if(buffer)  
    139.             {  
    140.                 CVBufferRelease(buffer);  
    141.             }  
    142.         }  
    143.         else  
    144.         {  
    145.             NSLog(@"error");  
    146.         }  
    147.     }  
    148.       
    149. }  
    150.   
    151. - (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image  
    152. {  
    153.     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:  
    154.                              [NSNumber numberWithBool:TRUE], kCVPixelBufferCGImageCompatibilityKey,  
    155.                              [NSNumber numberWithBool:TRUE],kCVPixelBufferCGBitmapContextCompatibilityKey,  
    156.                              nil nil];//是否兼容  
    157.     CVPixelBufferRef pxbuffer = NULL;  
    158.     CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, imageRect.size.width,  
    159.                                           imageRect.size.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,  
    160.                                           &pxbuffer);//返回kCVReturnSuccess kCFAllocatorDefault = nil  
    161.     status=status;  
    162.     NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);//判断类型  
    163.       
    164.     CVPixelBufferLockBaseAddress(pxbuffer, 0);//访问地址  
    165.     voidvoid *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);  
    166.     NSParameterAssert(pxdata != NULL);  
    167.       
    168.     CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();  
    169.     CGContextRef context = CGBitmapContextCreate(pxdata, imageRect.size.width,  
    170.                                                  imageRect.size.height, 8, 4*imageRect.size.width, rgbColorSpace,  
    171.                                                  kCGImageAlphaNoneSkipFirst);  
    172.     NSParameterAssert(context);  
    173.       
    174.     CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));  
    175.       
    176.     CGContextDrawImage(context, CGRectMake(0, 0, imageRect.size.width, imageRect.size.height), image);  
    177.     CGColorSpaceRelease(rgbColorSpace);  
    178.     CGContextRelease(context);  
    179.       
    180.     CVPixelBufferUnlockBaseAddress(pxbuffer, 0);  
    181.       
    182.     return pxbuffer;  
    183. }</span> 

posted on 2015-01-07 10:46  奋进的闹钟  阅读(1056)  评论(0编辑  收藏  举报

导航