首页 文章

删除并恢复AVPlayer以启用后台视频播放

提问于
浏览
0

我有播放视频的 UIWebView . 我是'd like the video to continue playing when the app goes to the background state. In Apple' s Technical Q&A QA1668,他们说:

如果AVPlayer的当前项目正在设备的显示屏上显示视频,则当应用程序发送到后台时,AVPlayer的播放会自动暂停 . 有两种方法可以阻止此暂停:禁用播放器项目中的视频轨道(仅限基于文件的内容) . 请参阅清单2.从关联的AVPlayer中删除AVPlayerLayer(将AVPlayerLayer播放器属性设置为nil) . 参见清单3 .

以下代码如清单3所示 .

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface MyPlayerLayerView : UIView
@end

@implementation MyPlayerLayerView

- (AVPlayerLayer *)playerLayer {
  return (AVPlayerLayer *)[self layer];
}

+ (Class)layerClass {
  return [AVPlayerLayer class];
}

@end

@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
...
@end

@implementation MyAppDelegate

...

/* Remove the AVPlayerLayer from its associated AVPlayer
    once the app is in the background. */
- (void)applicationDidEnterBackground:(UIApplication *)application {
  MyPlayerLayerView *playerView = <#Get your player view#>;
  [[playerView playerLayer] setPlayer:nil]; // remove the player
}

/* Restore the AVPlayer when the app is active again. */
- (void)applicationDidBecomeActive:(UIApplication *)application {
  MyPlayerLayerView *playerView = <#Get your player view#>;
  [[playerView playerLayer] setPlayer:_player]; // restore the player
}

...

@end

我正在尝试将其转换为Swift,但我对在 <#Get your player view#>; 做什么感到困惑 . 有人能澄清这意味着什么和/或如何在Swift中解决这个问题?

2 回答

  • 0

    在AppDelegate中

    var error: NSError?
    var success = AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: &error)
    if !success {
     NSLog("Failed to set audio session category.  Error: \(error)")
    }
    

    在MoviePlayerViewController中

    override func viewDidLoad()
    {
       super.viewDidLoad()  
       NSNotificationCenter.defaultCenter().addObserver(self, selector: "playBgVideo", name: UIApplicationDidEnterBackgroundNotification, object: nil)
    }
    func playBgVideo()
    {
      NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "hello", userInfo: nil, repeats: false)
    }
    func hello()
    {
      movieplayer?.play()
    }
    

    试试这个我希望它的功能!!!!!!!

  • 0

    据推测,你有一个 UIViewController ,其中包含播放视频的 UIWebView . 您可以注册该视图控制器,以便在应用程序进入后台以及应用程序变为活动状态时接收通知 .

    当应用程序进入后台时,您可以递归遍历视图层次结构以查找带有 AVPlayerLayer 的视图 . 如果找到一个,可以将播放器保存到实例变量并将图层的播放器设置为nil .

    当应用程序再次变为活动状态时,您可以再次递归遍历视图层次结构以查找适当的视图并还原播放器 .

    我使用了类似的方法使 AVPlayerViewController 在后台继续播放视频 .

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationDidEnterBackgroundNotification:", name: UIApplicationDidEnterBackgroundNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationDidBecomeActiveNotification:", name: UIApplicationDidBecomeActiveNotification, object: nil)
    }
    
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIApplicationDidEnterBackgroundNotification, object: nil)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIApplicationDidBecomeActiveNotification, object: nil)
    }
    
    var playerViewToRestore: UIView? = nil
    var playerToRestore: AVPlayer? = nil
    
    func applicationDidEnterBackgroundNotification(notification: NSNotification) {
        guard let view = findPlayerView() else {
            return
        }
    
        guard let playerLayer = view.layer as? AVPlayerLayer else {
            return
        }
    
        playerViewToRestore = view
        playerToRestore = playerLayer.player
    
        playerLayer.player = nil
    }
    
    func applicationDidBecomeActiveNotification(notification: NSNotification) {
        if playerToRestore == nil {
            return
        }
    
        guard let playerLayer = playerViewToRestore?.layer as? AVPlayerLayer else {
            return
        }
    
        playerLayer.player = playerToRestore
    
        playerViewToRestore = nil
        playerToRestore = nil
    }
    
    private func findPlayerView() -> UIView? {
        return findViewWithAVPlayerLayer(self.view)
    }
    
    private func findViewWithAVPlayerLayer(view: UIView) -> UIView? {
        if view.layer.isKindOfClass(AVPlayerLayer) {
            return view
        }
    
        for v in view.subviews {
            if let found = findViewWithAVPlayerLayer(v) {
                return found
            }
        }
    
        return nil
    }
    

相关问题