转换是转换成功了,但是出现了新的问题,使用ImageIO生成gif图片时会导致内存暴涨,瞬间涨到100M以上,如果多个gif图同时生成的话一样会crash掉,为了解决这个问题需要用一个串行队列来进行gif图的生成
1.2 视频转换为UIImages
主要是通过AVAssetReader、AVAssetTrack、AVAssetReaderTrackOutput 来进行转换
//转成UIImage
- (void)convertVideoUIImagesWithURL:(NSURL *)url finishBlock:(void (^)(id images, NSTimeInterval duration))finishBlock
{
AVAsset *asset = [AVAsset assetWithURL:url];
NSError *error = nil;
self.reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
NSTimeInterval duration = CMTimeGetSeconds(asset.duration);
__weak typeof(self)weakSelf = self;
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(backgroundQueue, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
NSLog(@"");
if (error) {
NSLog(@"%@", [error localizedDescription]);
}
NSArray *videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoTrack =[videoTracks firstObject];
if (!videoTrack) {
return ;
}
int m_pixelFormatType;
// 视频播放时,
m_pixelFormatType = kCVPixelFormatType_32BGRA;
// 其他用途,如视频压缩
// m_pixelFormatType = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:@(m_pixelFormatType) forKey:(id)kCVPixelBufferPixelFormatTypeKey];
AVAssetReaderTrackOutput *videoReaderOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:options];
if ([strongSelf.reader canAddOutput:videoReaderOutput]) {
[strongSelf.reader addOutput:videoReaderOutput];
}
[strongSelf.reader startReading];
NSMutableArray *images = [NSMutableArray array];
// 要确保nominalFrameRate>0,之前出现过android拍的0帧视频
while ([strongSelf.reader status] == AVAssetReaderStatusReading && videoTrack.nominalFrameRate > 0) {
@autoreleasepool {
// 读取 video sample
CMSampleBufferRef videoBuffer = [videoReaderOutput copyNextSampleBuffer];
if (!videoBuffer) {
break;
}
[images addObject:[WKVideoConverter convertSampleBufferRefToUIImage:videoBuffer]];
CFRelease(videoBuffer);
}
}
if (finishBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
finishBlock(images, duration);
});
}
});
}
在这里有一个值得注意的问题,在视频转image的过程中,由于转换时间很短,在短时间内videoBuffer不能够及时得到释放,在多个视频同时转换时任然会出现内存问题,这个时候就需要用autoreleasepool来实现及时释放










