常规获取MP4某一帧画面的方法对m3u8流媒体而言并不适用,如果有需求中需要获取m3u8流媒体截图的小伙伴可以看一下这个方法。
首先,用AVPlayer创建一个视频播放器,并且对AVPlayerItem添加观察者,具体代码不在这里啰嗦了。
流媒体的某一帧在流媒体播放时才能获取,所以我们在KVO中去调用获取画面的方法:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ AVPlayerItem *playerItem=object; if ([keyPath isEqualToString:@"status"]) { AVPlayerStatus status= [[change objectForKey:@"new"] intValue]; if(status==AVPlayerStatusReadyToPlay){ NSLog(@"正在播放...,视频总长度:%.2f",CMTimeGetSeconds(playerItem.duration)); //image即为获取到的视频帧截图 UIImage *image = [self getPixelBufferForItem:playerItem]; } }}复制代码
获取视频帧的代码:
//获取m3u8视频帧画面- (UIImage *)getPixelBufferForItem:(AVPlayerItem *)playerItem{ AVPlayerItemVideoOutput *output = [[AVPlayerItemVideoOutput alloc] init]; [playerItem addOutput:output]; CVPixelBufferRef ref =[output copyPixelBufferForItemTime:CMTimeMake(1000, 60) itemTimeForDisplay:nil]; UIImage *image = [self CVImageToUIImage:ref]; return image;}复制代码
copyPixelBufferForItemTime: itemTimeForDisplay:这个方法获取到的视频帧是CVPixelBufferRef类型,我们需要将CVPixelBufferRef类型转化为UIImage类型
//CVPixelBufferRef转UIImage- (UIImage *)CVImageToUIImage:(CVPixelBufferRef)imageBuffer{ CVPixelBufferLockBaseAddress(imageBuffer, 0); void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer); size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0); CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, bufferSize, NULL); CGImageRef cgImage = CGImageCreate(width, height, 8, 32, bytesPerRow, rgbColorSpace, kCGImageAlphaNoneSkipFirst|kCGBitmapByteOrder32Little, provider, NULL, true, kCGRenderingIntentDefault); UIImage *image = [UIImage imageWithCGImage:cgImage]; CGImageRelease(cgImage); CGDataProviderRelease(provider); CGColorSpaceRelease(rgbColorSpace); NSData* imageData = UIImageJPEGRepresentation(image, 1.0); image = [UIImage imageWithData:imageData]; CVPixelBufferUnlockBaseAddress(imageBuffer, 0); return image;}复制代码