1. 程式人生 > >AV Foundation系列(四)AVAssetReader和AVAssetWrite

AV Foundation系列(四)AVAssetReader和AVAssetWrite

http://www.jianshu.com/p/aeb441816a7d

AV Foundation提供了直接處理媒體樣本的低階功能,其中需要使用的兩個重要的類,AVAssetReader和AVAssetWrite,AVAssetReader用於從AVAsset資源讀取媒體樣本,AVAssetWrite用於對媒體資源進行編碼並寫入到容器檔案中。下面簡單的使用一下:

初始化AVAssetReader

-(void)configAssetReader

{

       NSURL *videoUrl = [NSURL fileURLWithPath:[self resoucePath]];

       _asset = [AVAsset
assetWithURL:videoUrl]; //獲取資源的一個視訊軌道 AVAssetTrack *track = [[_asset tracksWithMediaType:AVMediaTypeVideo] firstObject]; _assetReader = [[AVAssetReader alloc] initWithAsset:_asset error:nil]; //指定將讀取的樣本資料壓縮為BGRA格式 NSDictionary *setting = @{(id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}; //初始化輸出,指定從track軌道中讀取樣本資料
_assetOutPut = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:setting]; //新增輸出 [_assetReader addOutput:_assetOutPut]; //開始讀取過程 [_assetReader startReading]; }

初始化AVAssetWrite

-(void)configWriteInput

{

     NSString *storePath = nil;

     NSString *path  = [self resoucePath];

    NSRange
range = [path rangeOfString:@"/" options:NSBackwardsSearch]; if (range.location != NSNotFound) { NSString *pathRoot = [path substringToIndex:range.location]; storePath = [pathRoot stringByAppendingPathComponent:@"copy.mp4"]; } if (storePath) { _assetWrite = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:storePath] fileType:AVFileTypeQuickTimeMovie error:nil]; //指定編碼格式,畫素寬高等資訊 NSDictionary *setting = @{ AVVideoCodecKey:AVVideoCodecH264, AVVideoWidthKey:@1280, AVVideoHeightKey:@720, AVVideoCompressionPropertiesKey:@{ AVVideoMaxKeyFrameIntervalKey:@1, AVVideoAverageBitRateKey:@10500000, AVVideoProfileLevelKey:AVVideoProfileLevelH264Main31 } }; 初始化寫入器,並制定了媒體格式 _assetInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:setting]; //新增寫入器 [_assetWrite addInput:_assetInput]; [_assetWrite startWriting]; } }

將讀取的資料寫入到_assetInput寫入器中

-(void)assertReadToAssetInput

{

        dispatch_queue_t queue = dispatch_queue_create("com.writequeue", DISPATCH_QUEUE_CONCURRENT);

      if (_assetInput) {

             __block NSInteger count = 0; 

             __block BOOL isComplete = NO;

            //開啟寫入會話,並指定樣本的開始時間

            [_assetWrite startSessionAtSourceTime:kCMTimeZero];

            [_assetInput requestMediaDataWhenReadyOnQueue:queue usingBlock:^{

           if (!isComplete && _assetInput.readyForMoreMediaData)

           {

                   //樣本資料

                    CMSampleBufferRef buffer = [_assetOutPut copyNextSampleBuffer];

                   if (buffer) {

                            [_assetInput appendSampleBuffer:buffer];

                             count++;

                             // 展示第2000幀資料

                             if (count == 2000) {

                              CGImageRef imgref = [UIImage imageFromSampleBufferRef:buffer];

                             //讀取CMSampleBuffer中的資料,將其轉化為CGImageRef

                            參考程式碼見:http://www.jianshu.com/p/3d5ccbde0de1

                             UIImage *img = [UIImage imageWithCGImage:imgref];

                             dispatch_sync(dispatch_get_main_queue(), ^{

                             _imageView.image = img;

                                  });

                            }

                     }

                    else

                   {

                          isComplete = YES;

                   }

                 if(isComplete)

                 {

                         //關閉寫入會話 

                         [_assetWrite finishWritingWithCompletionHandler:^{

                                   AVAssetWriterStatus status = self.assetWrite.status;

                                   if (status == AVAssetWriterStatusCompleted) {

                                    NSLog(@"finsished");

                                   }               

                                   else

                                     {

                                            NSLog(@"failure");

                                     }

                                 }];

                   }

          } 

     }];

 }

}

執行結果生成了copy.mp4視訊檔案,點選播放,發現只有視訊沒有音訊資訊,因為我們只有讀取了視訊的樣本資料並寫入,並沒有讀取裡面的音訊資料。所以沒有音訊,AVAsset往往對應的是一個格式容器,裡面包含了很多格式的資料,音訊,視訊,字幕等。



文/jiangamh(簡書作者)
原文連結:http://www.jianshu.com/p/aeb441816a7d
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。