AVPlayer In View

12,139

Solution 1

From Apple's documentation:

You can display the visual content of items played by an instance of AVPlayer in a CoreAnimation layer of class AVPlayerLayer; to synchronize real-time playback with other CoreAnimation layers, you can use AVSynchronizedLayer. You cannot use an instance of AVVideoCompositionCoreAnimationTool with an AVPlayer object; for offline rendering you should instead use AVAssetExportSession.

Try this:

(playerView is just an IBOutlet of a UIView placed in storyboards)

 -(void)viewDidLoad {
    [super viewDidLoad];

    NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"]];

    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoURL];
    AVPlayer *player = [AVPlayer playerWithPlayerItem:item];

    CALayer *superlayer = self.playerView.layer;

    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    [playerLayer setFrame:self.playerView.bounds];
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [superlayer addSublayer:playerLayer];

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];


    [player seekToTime:kCMTimeZero];
    [player play];

}

-(void)playerDidFinishPlaying:(NSNotification *)notification {

    [self performSegueWithIdentifier:@"YourIdentifier" sender:self];
}

Solution 2

Swift version

func addVideoPlayer(videoUrl: URL, to view: UIView) {
    let player = AVPlayer(url: videoUrl)
    let layer: AVPlayerLayer = AVPlayerLayer(player: player)
    layer.backgroundColor = UIColor.white.cgColor
    layer.frame = view.bounds
    layer.videoGravity = .resizeAspectFill
    view.layer.sublayers?
        .filter { $0 is AVPlayerLayer }
        .forEach { $0.removeFromSuperlayer() }
    view.layer.addSublayer(layer)
}
Share:
12,139
BARIIIIIIICODE
Author by

BARIIIIIIICODE

Updated on June 27, 2022

Comments

  • BARIIIIIIICODE
    BARIIIIIIICODE almost 2 years

    I am trying to use a video on a view controller but not have it full screen, just enough room for a label on top and a button on bottom, is this possible? If not how can I have it so if the user skips the video or it finishes it goes to a certain viewController?

    - (void)viewDidLoad {
        [super viewDidLoad];
    
    NSURL *videoURL = [[NSBundle mainBundle]URLForResource:@"TTPlaneHits" withExtension:@"mp4"];
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
    
    
    AVPlayer *player = [AVPlayer playerWithURL:videoURL];
    playerLayer.frame = CGRectMake(0, 21, self.view.frame.size.width, self.view.frame.size.height - 45 - 21);
    [self.view.layer addSublayer:playerLayer];
    AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
    controller.player = player;
    [player play];
    
    
    [self.view addSubview:controller.view];
    controller.view.frame = self.view.frame;
    
  • BARIIIIIIICODE
    BARIIIIIIICODE almost 8 years
    Edited code, does not seem to adjust the sizing of the view still taking up the whole screen.
  • BARIIIIIIICODE
    BARIIIIIIICODE almost 8 years
    That worked well, video is kind of oversized though but will work, although if I navigate off that viewcontroller it continues to play in background which can be emptied by a audio.
  • Kaitis
    Kaitis almost 8 years
    Try changing the videoGravity property to AVLayerVideoGravityResizeAspectFit and you can stop the player in your prepareForSegue: method. You will have to also make the AVPlayer an instance variable