使用AVPlayer播放m3u8视频时,实现视频截图

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

你可能感兴趣的:(iOS,SDK)