0

我正在尝试在后台播放视频。我遵循了很多教程,但我没有得到适当的结果。为此,我正在使用 AVPlayer。只要应用程序状态处于活动状态,我就可以播放我的视频。但我想在后台播放音乐为此,我需要从 AVPlayer 中分离 AVPlayerLayer,如果您有任何替代解决方案,以便我可以在后台播放我的视频。请帮助我。

这是我的代码:

视图控制器.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];

}
4

1 回答 1

0

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

当然,您还需要将值为 'audio' 的条目 UIBackgroundModes 添加到应用程序的 info.plist 文件中(或在项目的 Info 选项卡中,添加条目 'Required background mode' 然后值 'App 播放音频或使用 AirPlay 流式传输音频/视频)。

我希望这是有帮助的。一开始我也很难实现后台播放,这个方法似乎效果很好。

于 2015-04-08T18:07:44.507 回答