iOS 开发中 通过AVAssetWriter将录像视频写到指定文件

 


分类: iphone 2012-10-07 16:37  583人阅读  评论(0)  收藏  举报
iphone 图像处理 string 算法 工作

转自:http://flhs-wdw.blog.sohu.com/207300574.html

 iphone提供了AVFoundation库来方便的操作多媒体设备,AVAssetWriter这个类可以方便的将图像和音频写成一个完整的视频文件。甚至将整个应用的操作录制下来,也不是什么困难的事情。

      这里先说一下如何将录像的视频写到指定文件中去:
      首先先准备好AVCaptureSession,当录制开始后,可以控制调用相关回调来取音视频的每一贞数据。

[cpp]  view plain copy
  1.     NSError * error;  
  2.   
  3.     session = [[AVCaptureSession alloc] init];  
  4.   
  5.     [session beginConfiguration];  
  6.   
  7.     [session setSessionPreset:AVCaptureSessionPreset640x480];  
  8.   
  9.     [self initVideoAudioWriter];  
  10.   
  11.     AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];  
  12.   
  13.     AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];  
  14.   
  15.       
  16.   
  17.     AVCaptureDevice * audioDevice1 = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];  
  18.   
  19.     AVCaptureDeviceInput *audioInput1 = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice1 error:&error];  
  20.   
  21.     videoOutput = [[AVCaptureVideoDataOutput alloc] init];  
  22.   
  23.     [videoOutput setAlwaysDiscardsLateVideoFrames:YES];   
  24.   
  25.     [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]forKey:(id)kCVPixelBufferPixelFormatTypeKey]];   
  26.   
  27.     [videoOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];  
  28.   
  29.   
  30.   
  31.     audioOutput = [[AVCaptureAudioDataOutput alloc] init];  
  32.   
  33. numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];   
  34.   
  35.     [audioOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];  
  36.   
  37.     [session addInput:videoInput];  
  38.   
  39.     [session addInput:audioInput1];  
  40.   
  41.     [session addOutput:videoOutput];  
  42.   
  43.     [session addOutput:audioOutput];  
  44.   
  45.       
  46.   
  47.     [session commitConfiguration];  
  48.   
  49.     [session startRunning];  


回调函数:

[cpp]  view plain copy
  1. -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {  
  2.   
  3.       
  4.   
  5.     //CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);  
  6.   
  7.       
  8.   
  9.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];   
  10.   
  11.   
  12.   
  13.     static int frame = 0;  
  14.   
  15.     CMTime lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);  
  16.   
  17.     if( frame == 0 && videoWriter.status != AVAssetWriterStatusWriting  )  
  18.   
  19.     {  
  20.   
  21.         [videoWriter startWriting];  
  22.   
  23.         [videoWriter startSessionAtSourceTime:lastSampleTime];  
  24.   
  25.     }  
  26.   
  27.     if (captureOutput == videoOutput)  
  28.   
  29.     {  
  30.   
  31.               
  32.   
  33. /           if( videoWriter.status > AVAssetWriterStatusWriting )  
  34.   
  35.            {  
  36.   
  37.                 NSLog(@"Warning: writer status is %d", videoWriter.status);  
  38.   
  39.                 if( videoWriter.status == AVAssetWriterStatusFailed )  
  40.   
  41.                     NSLog(@"Error: %@", videoWriter.error);  
  42.   
  43.                 return;  
  44.   
  45.             }  
  46.   
  47.             if ([videoWriterInput isReadyForMoreMediaData])  
  48.   
  49.                 if( ![videoWriterInput appendSampleBuffer:sampleBuffer] )  
  50.   
  51.                     NSLog(@"Unable to write to video input");  
  52.   
  53.                 else  
  54.   
  55.                     NSLog(@"already write vidio");  
  56.   
  57.         }  
  58.   
  59.     }  
  60.   
  61.     else if (captureOutput == audioOutput)  
  62.   
  63.     {  
  64.   
  65.         if( videoWriter.status > AVAssetWriterStatusWriting )  
  66.   
  67.         {  
  68.   
  69.             NSLog(@"Warning: writer status is %d", videoWriter.status);  
  70.   
  71.             if( videoWriter.status == AVAssetWriterStatusFailed )  
  72.   
  73.                 NSLog(@"Error: %@", videoWriter.error);  
  74.   
  75.             return;  
  76.   
  77.         }  
  78.   
  79.         if ([audioWriterInput isReadyForMoreMediaData])  
  80.   
  81.             if( ![audioWriterInput appendSampleBuffer:sampleBuffer] )  
  82.   
  83.                 NSLog(@"Unable to write to audio input");  
  84.   
  85.             else  
  86.   
  87.                 NSLog(@"already write audio");  
  88.   
  89.     }  
  90.   
  91.     if (frame == FrameCount)  
  92.   
  93.     {  
  94.   
  95.         [self closeVideoWriter];  
  96.   
  97.     }  
  98.   
  99.     frame ++;  
  100.   
  101.     [pool drain];   
  102.   
  103. }  


剩下的工作就是初始化AVAssetWriter,包括音频与视频输入输出:

[cpp]  view plain copy
  1. -(void) initVideoAudioWriter  
  2.   
  3. {  
  4.   
  5.     CGSize size = CGSizeMake(480, 320);  
  6.   
  7.       
  8.   
  9.       
  10.   
  11.     NSString *betaCompressionDirectory = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents/Movie.mp4"];  
  12.   
  13.       
  14.   
  15.     NSError *error = nil;  
  16.   
  17.       
  18.   
  19.     unlink([betaCompressionDirectory UTF8String]);  
  20.   
  21.       
  22.   
  23.     //----initialize compression engine  
  24.   
  25.     self.videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURLfileURLWithPath:betaCompressionDirectory]  
  26.   
  27.                                                  fileType:AVFileTypeQuickTimeMovie  
  28.   
  29.                                                     error:&error];  
  30.   
  31.     NSParameterAssert(videoWriter);  
  32.   
  33.     if(error)  
  34.   
  35.         NSLog(@"error = %@", [error localizedDescription]);  
  36.   
  37.     NSDictionary *videoCompressionProps = [NSDictionary dictionaryWithObjectsAndKeys:  
  38.   
  39.                                            [NSNumber numberWithDouble:128.0*1024.0],AVVideoAverageBitRateKey,  
  40.   
  41.                                            nil ];  
  42.   
  43.       
  44.   
  45.     NSDictionary *videoSettings = [NSDictionarydictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,  
  46.   
  47.                                    [NSNumber numberWithInt:size.width], AVVideoWidthKey,  
  48.   
  49.                                    [NSNumber numberWithInt:size.height],AVVideoHeightKey,videoCompressionProps, AVVideoCompressionPropertiesKey, nil];  
  50.   
  51.     self.videoWriterInput = [AVAssetWriterInputassetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];  
  52.   
  53.       
  54.   
  55.     NSParameterAssert(videoWriterInput);  
  56.   
  57.       
  58.   
  59.     videoWriterInput.expectsMediaDataInRealTime = YES;  
  60.   
  61.       
  62.   
  63.     NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionarydictionaryWithObjectsAndKeys:  
  64.   
  65.                                                            [NSNumbernumberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];  
  66.   
  67.       
  68.   
  69.     self.adaptor = [AVAssetWriterInputPixelBufferAdaptorassetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput  
  70.   
  71.                                                                                    sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];  
  72.   
  73.     NSParameterAssert(videoWriterInput);  
  74.   
  75.     NSParameterAssert([videoWriter canAddInput:videoWriterInput]);  
  76.   
  77.       
  78.   
  79.     if ([videoWriter canAddInput:videoWriterInput])  
  80.   
  81.         NSLog(@"I can add this input");  
  82.   
  83.     else  
  84.   
  85.         NSLog(@"i can't add this input");  
  86.   
  87.   
  88.   
  89.     // Add the audio input  
  90.   
  91.     AudioChannelLayout acl;  
  92.   
  93.     bzero( &acl, sizeof(acl));  
  94.   
  95.     acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;  
  96.   
  97.   
  98.   
  99.     NSDictionary* audioOutputSettings = nil;    
  100.   
  101. //    audioOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys:                         
  102.   
  103. //                           [ NSNumber numberWithInt: kAudioFormatAppleLossless ], AVFormatIDKey,  
  104.   
  105. //                           [ NSNumber numberWithInt: 16 ], AVEncoderBitDepthHintKey,  
  106.   
  107. //                           [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,  
  108.   
  109. //                           [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey,                                        
  110.   
  111. //                           [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey,  
  112.   
  113. //                           nil ];  
  114.   
  115.     audioOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys:                         
  116.   
  117.                            [ NSNumber numberWithInt: kAudioFormatMPEG4AAC ], AVFormatIDKey,  
  118.   
  119.                            [ NSNumber numberWithInt:64000], AVEncoderBitRateKey,  
  120.   
  121.                            [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,  
  122.   
  123.                            [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey,                                        
  124.   
  125.                            [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey,  
  126.   
  127.                            nil ];  
  128.   
  129.   
  130.   
  131.     audioWriterInput = [[AVAssetWriterInput   
  132.   
  133.                       assetWriterInputWithMediaType: AVMediaTypeAudio   
  134.   
  135.                       outputSettings: audioOutputSettings ] retain];  
  136.   
  137.   
  138.   
  139.     audioWriterInput.expectsMediaDataInRealTime = YES;  
  140.   
  141.     // add input  
  142.   
  143.     [videoWriter addInput:audioWriterInput];  
  144.   
  145.     [videoWriter addInput:videoWriterInput];  
  146.   
  147. }  

你可能感兴趣的:(iOS 开发中 通过AVAssetWriter将录像视频写到指定文件)