2012-08-23 42 views
8

मेरे पास AVPlayer के प्लेबैक को प्रदर्शित करने के लिए प्लेयर व्यू क्लास है। documentation से कोड।AVPlayer के वीडियो फ्रेम कैसे प्राप्त करें?

#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 

मैं अपने AVPlayer इस PlayerView में (साथ frame.size.width = 100, frame.size.height = 100) (आकार 320x240 के साथ वीडियो संपत्ति शामिल है) की स्थापना की और अपने वीडियो का आकार बदला जाता है। प्लेयरव्यू में जोड़ने के बाद मैं वीडियो का आकार कैसे प्राप्त कर सकता हूं?

उत्तर

18

में आईओएस 7.0 नई सुविधा जोड़ी:

AVPlayerLayer संपत्ति videoRect है।

+11

मेरे लिए, वीडियोRect केवल CGRectZero देता है भले ही मैं स्क्रीन पर वीडियो देख सकूं। मैं आईओएस 8 – tettoffensive

+0

का उपयोग कर रहा हूं currentItem.status को == AVPlayerStatusReadyToplay पर प्रतीक्षा करें, और फिर आपको फ्रेम – YoCoh

+0

मिलेगा यह काम नहीं करता है, यहां तक ​​कि मैंने स्थिति को AVPlayerStatusReadyToPlay होने की प्रतीक्षा करने के लिए केवीओ जोड़ा है। VideoRect अभी भी सभी शून्य – codingrhythm

6

मिले एक समाधान:

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; 
} 
+1

यह मेरे लिए Xcode4.5, आईओएस 6 एसडीके, लक्ष्य 4.3 का निर्माण नहीं कर रहा है। आकार प्राप्त करें (0,0)। क्या यह अभी भी आपके लिए काम कर रहा है? – Mingming

+0

हाँ। xcode 4.5.1, आधार एसडीके 6.0। –

2

यहां समाधान है जो मेरे लिए काम कर रहा है, ध्यान में एवीप्लेयर की स्थिति को ध्यान में रखता है। मैंने इसे प्लेयरव्यू कस्टम क्लास में अभी जोड़ा है। मुझे इसे हल करना पड़ा क्योंकि ऐसा नहीं लगता कि videoRect 10.7 में काम कर रहा है।

- (NSRect) videoRect { 
    NSRect theVideoRect = NSMakeRect(0,0,0,0); 
    NSRect theLayerRect = self.playerLayer.frame; 

    NSSize theNaturalSize = NSSizeFromCGSize([[[self.movie asset] tracksWithMediaType:AVMediaTypeVideo][0] naturalSize]); 
    float movieAspectRatio = theNaturalSize.width/theNaturalSize.height; 
    float viewAspectRatio = theLayerRect.size.width/theLayerRect.size.height; 
    if (viewAspectRatio < movieAspectRatio) { 
     theVideoRect.size.width = theLayerRect.size.width; 
     theVideoRect.size.height = theLayerRect.size.width/movieAspectRatio; 
     theVideoRect.origin.x = 0; 
     theVideoRect.origin.y = (theLayerRect.size.height/2) - (theVideoRect.size.height/2); 
} 
    else if (viewAspectRatio > movieAspectRatio) { 

     theVideoRect.size.width = movieAspectRatio * theLayerRect.size.height; 
     theVideoRect.size.height = theLayerRect.size.height; 
     theVideoRect.origin.x = (theLayerRect.size.width/2) - (theVideoRect.size.width/2); 
     theVideoRect.origin.y = 0; 
    } 
    return theVideoRect; 
} 
1

यहां आईएसओ को पोर्ट किया गया Eric Badros' answer है। मैंने पसंदीदा ट्रान्सफॉर्म हैंडलिंग भी जोड़ा। इसमें यह माना जाता _player एक AVPlayer

- (CGRect) videoRect { 
    CGRect theVideoRect = CGRectZero; 

    // Replace this with whatever frame your AVPlayer is playing inside of: 
    CGRect theLayerRect = self.playerLayer.frame; 

    AVAssetTrack *track = [_player.currentItem.asset tracksWithMediaType:AVMediaTypeVideo][0]; 
    CGSize theNaturalSize = [track naturalSize]; 
    theNaturalSize = CGSizeApplyAffineTransform(theNaturalSize, track.preferredTransform); 
    theNaturalSize.width = fabs(theNaturalSize.width); 
    theNaturalSize.height = fabs(theNaturalSize.height); 

    CGFloat movieAspectRatio = theNaturalSize.width/theNaturalSize.height; 
    CGFloat viewAspectRatio = theLayerRect.size.width/theLayerRect.size.height; 

    // Note change this *greater than* to a *less than* if your video will play in aspect fit mode (as opposed to aspect fill mode) 
    if (viewAspectRatio > movieAspectRatio) { 
     theVideoRect.size.width = theLayerRect.size.width; 
     theVideoRect.size.height = theLayerRect.size.width/movieAspectRatio; 
     theVideoRect.origin.x = 0; 
     theVideoRect.origin.y = (theLayerRect.size.height - theVideoRect.size.height)/2; 
    } else if (viewAspectRatio < movieAspectRatio) { 
     theVideoRect.size.width = movieAspectRatio * theLayerRect.size.height; 
     theVideoRect.size.height = theLayerRect.size.height; 
     theVideoRect.origin.x = (theLayerRect.size.width - theVideoRect.size.width)/2; 
     theVideoRect.origin.y = 0; 
    } 
    return theVideoRect; 
} 
+0

आपको एक त्रुटि है। अगर दोनों और यदि दोनों हैं ">" – tettoffensive

+0

धन्यवाद @tettoffensive –

0

यह मेरे लिए काम किया है। जब आपके पास 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); 

}