1

当我的应用程序处于前台时,我需要捕获 iPhone 屏幕。我已经为此使用UIGraphicsGetImageFromCurrentImageContaxt()了它,它在大多数 synerio 中都可以使用,但在使用MPMoviePlayerViewController或 AVPlayer 播放视频时失败,并通过播放器控制返回黑色图像。

可能我的猜测是MPMoviePlayerViewController使用 OpenGL 渲染帧并且方法UIGraphicsGetImageFromCurrentImageContaxt()无法捕获图像??

我遗漏了一些东西,或者在应用程序处于前台时是否有任何替代解决方案可用于捕获 iPhone 屏幕?

4

3 回答 3

3

对此没有任何简单的解决方案(即我可能不知道),但您需要弄清楚。在这里,我描述了可能的解决方案。当您尝试简单地在上下文中渲染视图时,它将给出空白屏幕代替播放器,其他事情将保持原样。

我知道的可能解决方案
Private API
您可以使用UIGetScreenImage()函数来捕获设备的整个屏幕,包括播放器及其控件。这是您可以轻松获得具有视图的播放器图像的方式。
注意:有些小伙伴说使用这个功能可能会导致申请被拒绝(我从来没有用过应用商店的应用,所以我没有太多经验:))。

第二种方式。

如果您想获取播放器的图像以及驻留在主视图或 iPhone 屏幕中的其他内容,那么基本想法是捕获两个图像(即一个电影播放器​​和另一个像您正在使用的整个屏幕UIGraphicsGetImageFromCurrentImageContext)并将它们组合为一张图像使用一些适当的计算。这样你需要做一些计算,所以准确性取决于你的计算。

在这里,我更喜欢使用AVPlayerMPMoviePlayer 而不是我不确定我是否真实,但因为我觉得 AVPlayer 在特定时间提供了准确的帧(准确度好。屏幕上显示的准确图像。)

请将 AVPlayer 的重力模式设置为AVLayerVideoGravityResizeAspect。此模式将保留纵横比并适合图层范围(即此选项是默认选项)。你可以这样设置。

playerLayer.videoGravity = setVideoFillMode:AVLayerVideoGravityResizeAspect;

其中 playerLayer 是 的对象AVPlayerLayer

现在得到图像AVPlayerLayer

AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] 
                                                     initWithAsset:asset];
            imageGenerator.appliesPreferredTrackTransform=YES;
            /*AVAssetImageGenerator will scale images such that they fit within the defined bounding box. Images will never be scaled up. So provide this should be the size of AVPlayer. */
            imageGenerator.maximumSize=CGSizeMake(400, 400); 
            CGImageRef imgRef = [imageGenerator copyCGImageAtTime:storedCMTime actualTime:NULL error:NULL];
            [imageGenerator release];

请注意,此生成的图像可能不是您正在寻找的确切尺寸,或者您提供的最大尺寸,因为正如我在上面的评论中提到的,这里的图像永远不会按比例放大。如果图像不是您正在查看的确切大小,则使用一些图像实用程序功能根据播放器的大小缩放图像,但不要破坏纵横比,因为我们已将 AVPLayer 的模式设置为 AVLayerVideoGravityResizeAspect.store 此图像临时.

现在使用 UIGraphicsGetImageFromCurrentImageContext 捕获 View 的图像(即就像您当前正在做的那样)。绘制我们已经捕获并存储在您视图上显示的黑色区域的 AVplayer 图像(即,您需要进行一些试验和错误才能获得完全相同的结果)。

在这里,我试图涵盖所有可能引起恐慌或不立即明显的要点。

更新: 来自 APPLE 的屏幕捕获解决方案:http: //developer.apple.com/library/ios/#qa/qa1703/_index.html#//apple_ref/doc/uid/DTS40010193

如果您想使用 MPMoviewPlayerController,那没关系。使用@Kuldeep 显示的代码获取缩略图。并使用 Image Masking结合两个视图的图像和缩略图在这里准确解释:链接

于 2012-08-27T06:49:37.527 回答
0

我宁愿建议使用下面的代码段,可能会更容易使用。您只需要传递需要捕获视频的时间因素。

float timeFactor = 60.0;
CGRect rect = CGRectMake(self.view.center.x, self.view.center.y, 100.0, 100.0)
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
UIImage *thumbnail = [player thumbnailImageAtTime:timeFactor timeOption:MPMovieTimeOptionNearestKeyFrame];
UIImageView *imagV=[[UIImageView alloc]initWithImage:thumbnail];
[imagV setFrame:rect];
于 2012-09-01T06:21:03.087 回答
0

好吧,似乎我找到了在 AVPlayer 中捕获帧的解决方案:

    - (UIImage*) captureFrame {

    AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:[self.player.currentItem asset]];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5) {
        [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero];
        [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero];
    }

    CGImageRef ref = [imageGenerator copyCGImageAtTime:self.player.currentItem.currentTime actualTime:nil error:nil];
    UIImage *img = [UIImage imageWithCGImage:ref];
    CGImageRelease(ref);

    return img;
}
于 2012-10-19T16:01:20.167 回答