手把手教你实现微信小视频iOS代码实现

2020-01-15 19:12:24王冬梅

还需要注意一个问题就是对于session的配置代码应该是这样的 
[self.session beginConfiguration];

...配置代码

[self.session commitConfiguration];

由于篇幅问题,后面的录制代码我就挑重点的讲了。
3.2  视频存储
现在我们需要在AVCaptureVideoDataOutputSampleBufferDelegate与AVCaptureAudioDataOutputSampleBufferDelegate的回调中,将音频和视频写入沙盒。在这个过程中需要注意的,在启动session后获取到的第一帧黑色的,需要放弃。
3.2.1 创建WKMovieWriter类来封装视频存储操作
WKMovieWriter的主要作用是利用AVAssetWriter拿到CMSampleBufferRef,剪裁后再写入到沙盒中。
这是剪裁配置的代码,AVAssetWriter会根据cropSize来剪裁视频,这里需要注意的一个问题是cropSize的width必须是320的整数倍,不然的话剪裁出来的视频右侧会出现一条绿色的线


 NSDictionary *videoSettings;
  if (_cropSize.height == 0 || _cropSize.width == 0) {
    
    _cropSize = [UIScreen mainScreen].bounds.size;
    
  }
  
  videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
           AVVideoCodecH264, AVVideoCodecKey,
           [NSNumber numberWithInt:_cropSize.width], AVVideoWidthKey,
           [NSNumber numberWithInt:_cropSize.height], AVVideoHeightKey,
           AVVideoScalingModeResizeAspectFill,AVVideoScalingModeKey,
           nil];

至此,视频录制就完成了。
接下来需要解决的预览的问题了 

Part 2 卡顿问题解决
1.1 gif图生成 
通过查资料发现了这篇blog 介绍说微信团队解决预览卡顿的问题使用的是播放图片gif,但是博客中的示例代码有问题,通过CoreAnimation来播放图片导致内存暴涨而crash。但是,还是给了我一些灵感,因为之前项目的启动页用到了gif图片的播放,所以我就想能不能把视频转成图片,然后再转成gif图进行播放,这样不就解决了问题了吗。于是我开始google功夫不负有心人找到了,图片数组转gif图片的方法。

gif图转换代码 


static void makeAnimatedGif(NSArray *images, NSURL *gifURL, NSTimeInterval duration) {
  NSTimeInterval perSecond = duration /images.count;
  
  NSDictionary *fileProperties = @{
                   (__bridge id)kCGImagePropertyGIFDictionary: @{
                       (__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever
                       }
                   };
  
  NSDictionary *frameProperties = @{
                   (__bridge id)kCGImagePropertyGIFDictionary: @{
                       (__bridge id)kCGImagePropertyGIFDelayTime: @(perSecond), // a float (not double!) in seconds, rounded to centiseconds in the GIF data
                       }
                   };
  
  CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)gifURL, kUTTypeGIF, images.count, NULL);
  CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
  
  for (UIImage *image in images) {
    @autoreleasepool {
      
      CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
    }
  }
  
  if (!CGImageDestinationFinalize(destination)) {
    NSLog(@"failed to finalize image destination");
  }else{
    
    
  }
  CFRelease(destination);
}