防止AVPlayer进入后台暂停?

问题描述 投票:0回答:2

我有一个简单的应用程序,其中有一个播放 M3U8 内容的 AVPlayer。在应用程序中,我执行以下操作以允许背景音频:

    NSError *audioError;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&audioError];
    if (audioError == nil)
    {
        [[AVAudioSession sharedInstance] setActive:YES error:nil];
    }

当我按下手机上的锁定按钮时,音频暂停。如果我再次按下锁定按钮(查看锁定屏幕),我会看到媒体控件,并且可以取消暂停内容以收听音频。

我的问题是,如何防止这种自动暂停,以便在首次按下锁定按钮时继续播放?我尝试了类似以下的方法:

- (id) init
{
    // ...
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleEnteredBackground) name: UIApplicationDidEnterBackgroundNotification object: nil];
    // ...
}

- (void) handleEnteredBackground
{
    // [player play];
    [player performSelector:@selector(play) withObject:nil afterDelay:1];
}

但这似乎不起作用。

ios objective-c avplayer
2个回答
3
投票

经过一番搜索,我找到了我的问题:

https://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/creating_a_basic_video_player_ios_and_tvos/playing_audio_from_a_video_asset_in_the_background

如果您正在播放纯音频资源,例如 MP3 或 M4A 文件,则您的设置已完成,您的应用程序可以播放背景音频。 如果您需要播放视频资源的音频部分,则需要执行额外的步骤。 如果播放器的当前项目正在设备上显示视频,则当应用程序发送到后台时,AVPlayer 实例的播放会自动暂停. 如果您想继续播放音频,请在进入后台时断开 AVPlayer 实例与演示文稿的连接,并在返回前台时重新连接。

他们的(Swift)示例代码如下所示:

func applicationDidEnterBackground(_ application: UIApplication) {

    // Disconnect the AVPlayer from the presentation when entering background

    // If presenting video with AVPlayerViewController
    playerViewController.player = nil

    // If presenting video with AVPlayerLayer
    playerLayer.player = nil
}

func applicationWillEnterForeground(_ application: UIApplication) {
    // Reconnect the AVPlayer to the presentation when returning to foreground

    // If presenting video with AVPlayerViewController
    playerViewController.player = player

    // If presenting video with AVPlayerLayer
    playerLayer.player = player
}

Objective-C 的等价物是:

- (void) applicationDidEnterBackground:(UIApplication*)application
{
    playerViewController.player = nil;
}
- (void) applicationWillEnterForeground:(UIApplication*)application
{
    playerViewController.player = player;
}

或者在我的例子中,播放器嵌入到视图中,并且不直接由应用程序委托或视图控制器控制,因此我使用了以下内容:

- (id) init
{
    // ...
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleEnteredBackground) name: UIApplicationDidEnterBackgroundNotification object: nil];
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleEnteredForeground) name: UIApplicationDidBecomeActiveNotification object: nil];
    // ...
}

- (void) handleEnteredBackground
{
    controller.player = nil;
}

- (void) handleEnteredForeground
{
    controller.player = player;
}

0
投票

很快就可能是这样的

private func setupPlayInBackground() {
    NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main, using: { [weak self] _ in
        self?.playerLayer?.player = nil
    })

    NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main, using: { [weak self] _ in
        self?.playerLayer?.player = self?.player
    })

    // Add controls to lock screen if needed
    
    let commandCenter = MPRemoteCommandCenter.shared()
    commandCenter.playCommand.isEnabled = true
    commandCenter.pauseCommand.isEnabled = true

    commandCenter.playCommand.addTarget { [weak self] _ -> MPRemoteCommandHandlerStatus in
        self?.player?.play()
        return MPRemoteCommandHandlerStatus.success
    }

    commandCenter.pauseCommand.addTarget { [weak self] _ -> MPRemoteCommandHandlerStatus in
        self?.player?.pause()
        return MPRemoteCommandHandlerStatus.success
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.