如何获取AVPlayer的视频帧?

And*_*kov 10 objective-c avfoundation avplayer avplayerlayer

我有用于显示AVPlayer播放的PlayerView类.文档代码.

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface PlayerView : UIView
@property (nonatomic) AVPlayer *player;
@end

@implementation PlayerView
+ (Class)layerClass {
    return [AVPlayerLayer class];
}
- (AVPlayer*)player {
    return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
    [(AVPlayerLayer *)[self layer] setPlayer:player];
}
@end
Run Code Online (Sandbox Code Playgroud)

我在此PlayerView中设置了我的AVPlayer(包含大小为320x240的视频资产)(frame.size.width = 100,frame.size.height = 100)并调整了我的视频大小.添加PlayerView后如何获得视频大小?

And*_*kov 29

iOS 7.0中添加了新功能:

AVPlayerLayer具有属性videoRect.

  • 对我来说,即使我可以在屏幕上看到视频,videoRect也会返回CGRectZero.我正在使用iOS 8 (13认同)
  • 经过另一次尝试,它的确有效.所以你需要AVPlayerItem上的KVO,而不是AVPlayer,要检查的状态是AVPlayerItemStatus.ReadyToPlay,而不是AVPlayerStatusReadyToPlay.这种方法是正确的,但@Yocoh的评论有点误导. (2认同)

And*_*kov 6

这对我有用。当您没有 AVPLayerLayer 时。

- (CGRect)videoRect {
    // @see http://stackoverflow.com/a/6565988/1545158

    AVAssetTrack *track = [[self.player.currentItem.asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    if (!track) {
        return CGRectZero;
    }

    CGSize trackSize = [track naturalSize];
    CGSize videoViewSize = self.videoView.bounds.size;

    CGFloat trackRatio = trackSize.width / trackSize.height;
    CGFloat videoViewRatio = videoViewSize.width / videoViewSize.height;

    CGSize newSize;

    if (videoViewRatio > trackRatio) {
        newSize = CGSizeMake(trackSize.width * videoViewSize.height / trackSize.height, videoViewSize.height);
    } else {
        newSize = CGSizeMake(videoViewSize.width, trackSize.height * videoViewSize.width / trackSize.width);
    }

    CGFloat newX = (videoViewSize.width - newSize.width) / 2;
    CGFloat newY = (videoViewSize.height - newSize.height) / 2;

    return CGRectMake(newX, newY, newSize.width, newSize.height);

}
Run Code Online (Sandbox Code Playgroud)


And*_*kov 5

找到了解决方案:

添加到PlayerView类:

- (CGRect)videoContentFrame {
    AVPlayerLayer *avLayer = (AVPlayerLayer *)[self layer];
    // AVPlayerLayerContentLayer
    CALayer *layer = (CALayer *)[[avLayer sublayers] objectAtIndex:0];
    CGRect transformedBounds = CGRectApplyAffineTransform(layer.bounds, CATransform3DGetAffineTransform(layer.sublayerTransform));
    return transformedBounds;
}
Run Code Online (Sandbox Code Playgroud)