如何从AVPlayer分离AVPlayerLayer以在后台状态播放视频?

时间:2014-09-08 12:17:14

标签: ios objective-c ios7 avplayer avplayerlayer

我正在尝试在后台播放视频。我按照这么多教程但我没有得到合适的结果。因为我正在使用AVPlayer。我能够在应用程序状态处于活动状态时播放我的视频。但我想玩音乐在背景中我需要从AVPlayer分离AVPlayerLayer,如果你有任何替代解决方案,以便我可以在后台播放我的视频。请帮助我。

这是我的代码:

ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    [[AVAudioSession sharedInstance] setDelegate: self];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    [[AVAudioSession sharedInstance] setActive: YES error: nil];

    NSURL *url = [[NSBundle mainBundle] URLForResource:@"sample"
              withExtension:@"m4v" subdirectory:nil];
avPlayerItem = [AVPlayerItem playerItemWithURL:url];
    self.songPlayer = [AVPlayer playerWithPlayerItem:avPlayerItem];
    self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer: self.songPlayer];
    self.avPlayerLayer.frame = self.view.layer.bounds;
    UIView *newView = [[UIView alloc] initWithFrame:self.view.bounds];
    [newView.layer addSublayer:avPlayerLayer];
    [self.view addSubview:newView];
    [self.songPlayer play];
   }

AppDelegate.m

- (void)applicationWillResignActive:(UIApplication *)application
{
    ViewController *vc=[[ViewController alloc]init];
    vc.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:nil];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    ViewController *vc=[[ViewController alloc]init];
    vc.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:vc.songPlayer];

}

1 个答案:

答案 0 :(得分:0)

您正在应用程序委托方法中创建一个新的视图控制器,使用新的播放器等。这不会改变任何事情。您必须使用在视图控制器的viewDidLoad方法中创建的播放器和图层,稍后在委托方法中修改该播放器和图层。为此,您的应用程序委托可以将主视图控制器存储在其属性中,或者您可以在视图控制器类中实现应用程序委托的NSNotifications,如下所示:(可以添加到视图控制器' s viewDidLoad方法)

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];

要将播放器层与播放器分离,正如它在文档中说的那样,略微不正确,至少令人困惑。实际上你必须将玩家从玩家层分离出来。 将此代码添加到applicationDidEnterBackground(而不是applicationWillResignActive)方法:

// Detach player from playerlayer to avoid pause while in background
if (self.playerLayer && self.player)
{
    [self.playerLayer setPlayer: nil];
}

在你的applicationWillEnterForeground中,存储一个标志,以便记住当应用程序变为活动状态时,它应该进入前台,而不是可以调用applicationDidBecomeActive的其他众多原因之一:

self.enteringForeground = true;

然后,在您的applicationDidBecomeActive:方法中,

if (self.enteringForeground)
{
    // Re-attach player to playerlayer
    if (self.playerLayer && self.player)
    {
        if (self.playerLayer.player != self.player)
            [self.playerLayer setPlayer: self.player];
    }

    self.enteringForeground = false;
}

要使其正常工作,您需要在应用程序委托.h文件或视图控制器.h文件中使用新属性,具体取决于您选择的实现:

@property (readwrite)           BOOL            enteringForeground;

当然,您还需要添加条目UIBackgroundModes,其值为' audio'到您的应用程序的info.plist文件(或在项目的“信息”选项卡中,添加条目'所需的背景模式'然后值'应用播放音频或流音频/视频使用AirPlay')。

我希望这会有所帮助。我一开始很难实现后台播放,这种方法看起来效果很好。