简体   繁体   中英

AVPlayerLayer and AVPlayer

I build a Video player in my app with AVPlayerLayer and AVPlayer .

when a new video is chosen i make this method:

//this to remove the current video
    if (avPlayerLayer) {
            [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[audioPlayer currentItem]];
            [avPlayerLayer.player pause];
            [avPlayerLayer removeFromSuperlayer];
            avPlayerLayer = nil;
    }

//and this is to add a new one
    audioPlayer = [[AVPlayer alloc]initWithURL:[NSURL fileURLWithPath:fileName]];
    avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:audioPlayer] retain];
    [avPlayerLayer setFrame:self.view.bounds];

    CGRect frame = avPlayerLayer.frame;
    [avPlayerLayer setFrame:CGRectMake(frame.origin.x, frame.origin.y - 30, frame.size.width, frame.size.height)];

    [[self.view layer] addSublayer:avPlayerLayer];

    [audioPlayer play];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(finishPlayingSong)
                                                     name:AVPlayerItemDidPlayToEndTimeNotification
                                                   object:[audioPlayer currentItem]];
    [audioPlayer release];

Now, some times when i performed this method the device not start playing the video(it's occurs simultaneity and not on the same video). any idea why it happen? and how can i handle it?

Edit

I noticed it happen after i play 5 songs.

You have a memory leak. Each time you create an AVPlayer with alloc: init: and assign it to audioPlayer . This gives it a retain count of 1. Then you create an AVPlayerLayer which increments its retain count again.

Later, you release the avPlayerLayer which decrements the retain count on audioPlayer but it never goes back to zero and thus never gets deallocated.

Leaks are bad, but you're running into another problem too. There's an infrastructural limit in iOS to a maximum of 4 audio/video render pipelines . When you create the fifth one, it's unable to grab a render pipeline, and so playback fails.

To solve your problem, correct the memory leak.

audioPlayer = [AVPlayer playerWithURL:[NSURL fileURLWithPath:fileName]];

Using the playerWithURL: static factory constructor will implicitly perform an autorelease: , decrementing the retain count of that object and avoiding the leak.

There's really no reason to create new AVPlayer and AVPlayerLayer instances just to change inputs. All you really need is a new AVPlayerItem. Assign it to the current AVPlayer and continue to use your existing AVPlayerLayer.

Generally to customize your MPMovie player it is better to go with AVPlayerLayer with AVPlayer.

By using this customized player you can customize the player controls(play/pause,backward,forward,stop and volume etc.) as you like.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM