最近需要一个对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