【问题标题】:Getting Blank Image while trying to capture MPMoviePlayerViewController view using UIGraphicsGetImageFromCurrentImageContext()尝试使用 UIGraphicsGetImageFromCurrentImageContext() 捕获 MPMoviePlayerViewController 视图时获取空白图像
【发布时间】:2012-08-18 16:40:01
【问题描述】:

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

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

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

【问题讨论】:

  • 谢谢,但是上面的链接对我有用...
  • 但是为什么呢?如果您还没有得到解决方案,请告诉我也许我可以帮助您

标签: iphone ios ipad ios5


【解决方案1】:

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

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

第二种方式。

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

在这里,我更喜欢使用AVPlayer而不是 MPMoviePlayer,我不确定我是否真实,但因为我觉得 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 将 Both 视图的图像和缩略图结合起来,在这里准确解释:Link

【讨论】:

  • 谢谢兄弟,因为 MPMoviePlayerViewController 提供了默认且美观的布局。所以我使用了 MPMoviePlayerViewController。但我在 MPMoviePlayer 和 AVPlayer 中都发现了同步问题。 MPMoviePlayerViewController 本身在搜索/搜索时显示错误帧。希望可以通过 UIGraphics api 完成......无论如何,感谢第二种方法。
  • 那么你没有得到正确的视频帧吗?据我所知,没有任何其他方法可以获取视频照片。当他们使功能: UIGetScreenImage() 私有时,他们建议获取视频帧来捕获视频。虽然寻找任何解决方案可能是任何天才都有一些解决方法。
【解决方案2】:

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

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];

【讨论】:

    【解决方案3】:

    好吧,我似乎找到了在 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;
    }
    

    【讨论】:

    • 你能详细说明你的答案吗?
    • 虽然这在理论上可以回答这个问题,但最好在你的答案中包含一些解释代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多