美文网首页视频AVFoundation 拍片专用视频
AV Foundation系列(四)AVAssetReader和

AV Foundation系列(四)AVAssetReader和

作者: jiangamh | 来源:发表于2015-12-28 19:18 被阅读2133次

    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往往对应的是一个格式容器,里面包含了很多格式的数据,音频,视频,字幕等。

    这是第一次使用markdown格式编辑,之前一直不回使用,后来百度才知道,需要在设置中指定markdwon编辑,而非富文本编辑。

    相关文章

      网友评论

      • boovit:你好,咨询各问题 AVAssetReader 不能加载非本地的url。
      • puppySweet:我都没有用 不知道你怎么弄的 demo 也没有啊
      • puppySweet:AVAssetReader根本没用吧
      • NicWhite:那音频数据怎么读入呢?
        我现在要写一个类似的就是播放出来没有声音
      • puppySweet:求demo

      本文标题:AV Foundation系列(四)AVAssetReader和

      本文链接:https://www.haomeiwen.com/subject/isabhttx.html