最近需要一个对m3u8文件的截图,但是搜索一段时间后发现方法都类似,但都不成功。经过测试该方法:普通的mp4和mov格式视频可以通过下面的方法获取截图。但是m3u8文件则不行,总提示:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x7fadf25f59f0 {NSUnderlyingError=0x7fadf25f1670 "The operation couldn’t be completed. (OSStatus error -12782.)", NSLocalizedFailureReason=An unknown error occurred (-12782), NSLocalizedDescription=The operation could not be completed}
下面的代码是网络上流传的方法,仅对pm4,mov格式生效。对m3u8的ts文件格式不生效。
// 根据视频的路径获取单帧图片
- (UIImage *)getThumbImage:(NSURL *)url {
//测试视频地址
NSURL *soundFileURL = nil;
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"jiangwan" ofType:@"mp4"];
if (soundFilePath.length) {
soundFileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
}
//截第一帧
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:soundFileURL options:nil];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
gen.appliesPreferredTrackTransform = YES;
CMTime time = CMTimeMakeWithSeconds(0.0, 1);
NSError *error = nil;
CMTime actualTime;
CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
return thumb;
}
无意中,网上查到资料:可以使用AVPlayerItemVideoOutput的[AVPlayerItemVideoOutput copyPixelBufferForItemTime:itemTimeForDisplay:]来实现,方法如下:
{
/*设置playitem 之后*/
[self replaceCurrentItemWithPlayerItem:item];
self.snapshotOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:NULL];
[item removeOutput:self.snapshotOutput];
[item addOutput:self.snapshotOutput];
}
/*
* 截取当前时间点,视频截图
*/
- (UIImage *)snapshotImage {
CMTime time = [self.snapshotOutput itemTimeForHostTime:CACurrentMediaTime()];
if ([self.snapshotOutput hasNewPixelBufferForItemTime:time]) {
CVPixelBufferRef lastSnapshotPixelBuffer = [self.snapshotOutput copyPixelBufferForItemTime:time itemTimeForDisplay:NULL];
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:lastSnapshotPixelBuffer];
CIContext *context = [CIContext contextWithOptions:NULL];
CGRect rect = CGRectMake(0,
0,
CVPixelBufferGetWidth(lastSnapshotPixelBuffer),
CVPixelBufferGetHeight(lastSnapshotPixelBuffer));
CGImageRef cgImage = [context createCGImage:ciImage fromRect:rect];
return [UIImage imageWithCGImage:cgImage];
}
return NULL;
}
参考文章:
http://darktechlabs.com/2016/07/15/iOS-小坑记录:如何给-AVPlayer-截图/
Real-time Video Processing Using AVPlayerItemVideoOutput