本文共 2318 字,大约阅读时间需要 7 分钟。
最近开发遇到一个点击按钮实现直播视频流截屏的功能,去网上查了一下资料,总结了一下iOS中截屏相关的知识,然后自己做了个demo。
demo主要实现了3种截屏方法,分别对应三种不同的应用场景。 1、imageView截图,这个截图方法可以用来实现截取项目中的控件,可截取的控件可包括UIImageView、UIView等。截图方法如下:-(UIImage *)screenshotsWithView:(UIView *)view{ UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image;}
2、MP4格式的视频流截图,即获取MP4格式视频流中的某一帧。截取方法如下:
-(UIImage *)screenshotsMP4WithCurrentTime:(CMTime)currentTime videoUrl:(NSString *)url{ AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:url] options:nil]; AVAssetImageGenerator * gen = [[AVAssetImageGenerator alloc] initWithAsset:asset]; gen.appliesPreferredTrackTransform = YES; gen.requestedTimeToleranceAfter = kCMTimeZero; gen.requestedTimeToleranceBefore = kCMTimeZero; CMTime time = CMTimeMakeWithSeconds(CMTimeGetSeconds(currentTime), 600); NSError * error = nil; CMTime actualTime; CGImageRef imageRef = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error]; UIImage * image = [[UIImage alloc] initWithCGImage:imageRef]; return image;}
这个方法是不是仅限于MP4格式的视频我不是很清楚,但是可以确定的是,MP4截取某一帧的方法不适用于m3u8格式的视频流。
3、m3u8格式视频流截图。方法如下:-(UIImage *)screenshotsm3u8WithCurrentTime:(CMTime)currentTime playerItemVideoOutput:(AVPlayerItemVideoOutput *)output{ CVPixelBufferRef pixelBuffer = [output copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil]; CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer]; CIContext *temporaryContext = [CIContext contextWithOptions:nil]; CGImageRef videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer))]; UIImage *frameImg = [UIImage imageWithCGImage:videoImage]; CGImageRelease(videoImage); CVBufferRelease(pixelBuffer); return frameImg;}
需要特别指出来的那两个release方法,不调用的话会造成内存泄漏(可用Instruments调试)。
另外还有一点需要注意,m3u8格式的视频流在截取时需要传入一个AVPlayerItemVideoOutput对象,这个对象一定要在AVPlayerItem初始化的时候设置好,如果以临时变量的形式传入或导致截取失败。 在截屏事件里直接调用以上方法即可获取到截取的image。demo链接地址:转载地址:http://qdifb.baihongyu.com/