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

时间:2022-08-31 23:31:01

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