简体   繁体   English

AVPlayerLayer和AVPlayer

[英]AVPlayerLayer and AVPlayer

I build a Video player in my app with AVPlayerLayer and AVPlayer . 我使用AVPlayerLayerAVPlayer在我的应用程序中构建了一个视频播放器。

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. 我注意到播放5首歌曲后会发生这种情况。

You have a memory leak. 您有内存泄漏。 Each time you create an AVPlayer with alloc: init: and assign it to audioPlayer . 每次您使用alloc: init:创建一个AVPlayer并将其分配给audioPlayer This gives it a retain count of 1. Then you create an AVPlayerLayer which increments its retain count again. 这使其保留计数为1。然后创建一个AVPlayerLayer ,它再次增加其保留计数。

Later, you release the avPlayerLayer which decrements the retain count on audioPlayer but it never goes back to zero and thus never gets deallocated. 稍后,您释放avPlayerLayer ,它会减少audioPlayer上的保留计数,但是它永远不会回到零,因此永远不会被释放。

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 . iOS中的基础架构限制为最多4个音频/视频渲染管道 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. 使用playerWithURL:静态工厂构造函数将隐式执行autorelease:减少该对象的保留计数并避免泄漏。

There's really no reason to create new AVPlayer and AVPlayerLayer instances just to change inputs. 确实没有理由仅为了更改输入而创建新的AVPlayer和AVPlayerLayer实例。 All you really need is a new AVPlayerItem. 您真正需要的只是一个新的AVPlayerItem。 Assign it to the current AVPlayer and continue to use your existing AVPlayerLayer. 将其分配给当前的AVPlayer,然后继续使用现有的AVPlayerLayer。

Generally to customize your MPMovie player it is better to go with AVPlayerLayer with AVPlayer. 通常,要自定义MPMovie播放器,最好将AVPlayerLayer与AVPlayer一起使用。

By using this customized player you can customize the player controls(play/pause,backward,forward,stop and volume etc.) as you like. 通过使用此自定义播放器,您可以根据需要自定义播放器控件(播放/暂停,后退,前进,停止和音量等)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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