视频其实就是一张张图片组成的,将视频拆分成图片。
这里视频分解图片使用的是AVAssetImageGenerator,利用这个类可以很方便的实现不同时间戳下,视频帧的抓取。注意一般这种视频分解图片帧的方法都是放在子线程中的,而UI更新操作都是放在主线程中的。
- 使用下面方法获取视频的每一帧图片进行处理:
/* !
@method generateCGImagesAsynchronouslyForTimes:completionHandler
@abstract Returns a series of CGImageRefs for an asset at or near the specified times.
@param requestedTimes An NSArray of NSValues, each containing a CMTime, specifying the asset times at which an image is requested.
@param handler A block that will be called when an image request is complete.
@discussion Employs an efficient "batch mode" for getting images in time order. The client will receive exactly one handler callback for each requested time in requestedTimes. Changes to generator properties (snap behavior, maximum size, etc...) will not affect outstanding asynchronous image generation requests. The generated image is not retained. Clients should retain the image if they wish it to persist after the completion handler returns.
*/
// 获取每一帧图片
- (void)generateCGImagesAsynchronouslyForTimes:(NSArray<NSValue *> *)requestedTimes completionHandler:(AVAssetImageGeneratorCompletionHandler)handler;
- 下面核心代码:
- (void)splitVideo:(NSURL *)fileUrl fps:(float)fps splitCompleteBlock:(void(^)(BOOL success, NSMutableArray *splitimgs))splitCompleteBlock {
if (!fileUrl) {
return;
}
NSMutableArray *splitImages = [NSMutableArray array];
NSDictionary *optDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVURLAsset *avasset = [[AVURLAsset alloc] initWithURL:fileUrl options:optDict];
CMTime cmtime = avasset.duration; //视频时间信息结构体
Float64 durationSeconds = CMTimeGetSeconds(cmtime); //视频总秒数
NSMutableArray *times = [NSMutableArray array];
Float64 totalFrames = durationSeconds * fps; //获得视频总帧数
CMTime timeFrame;
for (int i = 1; i <= totalFrames; i++) {
timeFrame = CMTimeMake(i, fps); //第i帧 帧率
NSValue *timeValue = [NSValue valueWithCMTime:timeFrame];
[times addObject:timeValue];
}
AVAssetImageGenerator *imgGenerator = [[AVAssetImageGenerator alloc] initWithAsset:avasset]; //防止时间出现偏差
imgGenerator.requestedTimeToleranceBefore = kCMTimeZero;
imgGenerator.requestedTimeToleranceAfter = kCMTimeZero;
NSInteger timesCount = [times count]; // 获取每一帧的图片
[imgGenerator generateCGImagesAsynchronouslyForTimes:times completionHandler:^(CMTime requestedTime, CGImageRef _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error) {
NSLog("current-----: %lld", requestedTime.value);
NSLog("timeScale----: %d",requestedTime.timescale); // 帧率
BOOL isSuccess = NO;
switch (result) {
case AVAssetImageGeneratorCancelled:
NSLog(@"Cancelled");
break;
case AVAssetImageGeneratorFailed:
NSLog(@"Failed");
break;
case AVAssetImageGeneratorSucceeded: {
UIImage *frameImg = [UIImage imageWithCGImage:image];
[splitImages addObject:frameImg];
if (requestedTime.value == timesCount) {
isSuccess = YES;
NSLog(@"completed");
}
}
break;
}
if (splitCompleteBlock) {
splitCompleteBlock(isSuccess,splitImages);
}
}];
贴上github地址:https://github.com/ismilesky/MaxVideo.git
网友评论