iOS画中画Picture in Picture:你需要知道的9个知识点

来源:互联网 发布:sql存储过程语法 编辑:程序博客网 时间:2024/06/05 06:36
      iOS9最后给我们带来了每个人期待已久的”多任务”,Slider Over、Split View 和画中画(PiP),已经使iPad成为一个比之前更强大、更便利的工具。使你在工作中需要在屏幕上同时做多个事情的时候增加工作效率,这在商务办公中将会备受欢迎。相比于转换为后台或者四指切换APP,用户能够更加集中注意力于更加重要的事情上。并且现在由于苹果对视频app更加优雅的处理方式,当你需要回复朋友的email或者浏览其他模块的时候,你不必暂停你喜爱的电视剧。同样,在iOS9上,当我们用Facebook上与其他人谈话的时候,还可以在网上搜索其他东西。
     所有的这些多任务特性都是非常棒的,并且画中画功能使iPad在苹果的其他产品中更加突出。比如在Mac上,我们把视频缩小放到一个屏幕的边角,而当我们有一些其他的窗口打开的时候,我们同样会担心视频是否会被其他的窗口覆盖,并且不得不重新调整窗口的层级。在我看来,Pipe如果加到了OSX上回更加nice,但是我们不得不把这个留给苹果去决定。

     如果你问自己是否真的需要把画中画功能添加到你的iOSapp中的话,回答是绝对的要假如。这个特性对于每一个媒体app将会是必须的。并且没有它你将会流失你的客户。并且将他假如到你的app中,并不会造成太多的影响,继续往下看你将会发现


 Picture in Picture Q & A

(官方demo)


1.怎么使其起作用

首先画中画(Picture in Picture)功能只有在iPad中才能使用。一旦你点击你的app中的工具栏中的PiP按钮,将会进入画中画模式,视频将会展示在一个漂浮在其他所有你打开的app的上方的窗口中。

PiP的窗口能被调整大小并且能够拖拽到屏幕的四个角,他同样能够被从屏幕上移除,点击PiP的窗口,将会展示控制面板,你可以暂停或开始视频,或者离开画中画模式或者你可以将画中画窗口卷起来。


2.如果我的app正在画中画模式中播放,而用户播放了其他的视频/音频,将会发生什么

这个不需要担心,你的画中画将会自动暂停,同样,如果用户想要重复播放你的视频,其他的视频或音频也会被暂停


3.用户可以禁止掉画中画功能吗?

当然,可以在设置>>通用>>多任务>>持续视频层叠 中将其关闭。所以当你测试画中画的时候,也要确定这个功能没有被关闭


4.我怎么能够在我的app实现画中画功能

如果你播放你的视频用AVPlayerViewController类,将会非常的简单。画中画按钮已经被放置好并且系统能够自动的处理好画中画模式和全屏模式。同样你的视频内容播放在WKWebView同样可以展示在画中画模式中。然而如果你想实现你自己定制的播放器中,你可能就要多做些工作了,你需要在库AVKit中实例化一个 AVPictureInPictureController类,你能够关联上 AVPlayerLayer实例。在任何情况下,你都需要为你的APP后台画中画模式做一些合理的配置

1.在工程中的Build settings 中,设置Base SDK为“Latest iOS.”


2.到工程的Target,在Capabilities中选择  Background Modes 为  Audio and AirPlay.



3.你的app播放任务需要设置为AVAudioSessionCategoryPlayback 或者AVAudioSessionCategoryPlayAndRecord
举个例子:

在苹果开发文档中的demo中在AppDelegate.swift 中


let audioSession = AVAudioSession.sharedInstance()do {try audioSession.setCategory(AVAudioSessionCategoryPlayback)}catch {print("Audio session setCategory failed")}


5.当我在用一个自定义的播放器的时候,怎么处理到画中画模式的过渡?

第一步就是确保你的app能够支持画中画模式(看上文),并且视频内容能够全屏播放
由于你没有用AVPlayerViewController,所以你需要创建一个button去选择到画中画模式。然而你还要去检查这种模式在用户的iPad上是否支持。AVPictureInPictureController类提供这种检测,所以你只能在AVPictureInPictureController.isPictureInPictureSupported()这个方法返回值是true的时候才能在app中用画中画模式。
事实上,AVPictureInPictureController才是真正能够初始化和退出画中画模式的类

通过的方法:

stopPictureInPicture()startPictureInPicture()



它能够给你提供一些当前画中画的状态,例如:
pictureInPicturePossible——告诉你画中画窗口是可用的。如果其他的app再使用PiP模式,他将会返回false。这个实行也能够通过KVO来观察,同样通过观察这种状态的改变,你也能够很好地额处理PiP按钮的的隐藏于展示。
pictureInPictureActive——表示PiP窗口当前时间是否在屏幕上
pictureInPictureSuspended——如果你的app因为其他的app在使用PiP而导致你的视频后台播放播放状态为暂停并且不可见,将会返回true。当其他的app离开了PiP时,你的视频会被重新播放

AVPictureInPictureController的初始化通过将要展示视频的视图的view的 AVPlayerLayer来初始化。为了达到这种目的视频播放的视图的layer返回应该是AVPlayerLayer。


var player: AVPlayer? {get {return playerLayer.player}set {playerLayer.player = newValue}}var playerLayer: AVPlayerLayer {return layer as! AVPlayerLayer}override class func layerClass() -> AnyClass {return AVPlayerLayer.self}

 

 下面是当你的视频内容已经准备好展示的时候PiP是如何设置的:

private func setupPictureInPicturePlayback() { if AVPictureInPictureController.isPictureInPictureSupported() { pictureInPictureController = AVPictureInPictureController(playerLayer: playerView.playerLayer)pictureInPictureController.delegate = selfaddObserver(self, forKeyPath: "pictureInPictureController.pictureInPicturePossible", options: [.New, .Initial], context: &playerViewControllerKVOContext)}else {pictureInPictureButton.enabled = false}}


注意在这个例子中,包含了视频播放器的视图控制器遵守AVPictureInPictureControllerDelegate协议。这个协议里面定义了你可以响应PiP播放事件的方法,包含了:
pictureInPictureController(_:restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:)pictureInPictureControllerDidStartPictureInPicture(_:)pictureInPictureControllerDidStopPictureInPicture(_:)pictureInPictureControllerWillStartPictureInPicture(_:)pictureInPictureControllerWillStopPictureInPicture(_:)pictureInPictureControllerFailedToStartPictureInPicture(_:withError:)


下面的这些代码是根据pictureInPicturePossible这个属性来控制PiP按钮的状态(可用于不可用):
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [NSObject : AnyObject]?, context: UnsafeMutablePointer<Void>) { …             if keyPath == "pictureInPictureController.pictureInPicturePossible" {let newValue = change?[NSKeyValueChangeNewKey] as! NSNumberlet isPictureInPicturePossible: Bool = newValue.boolValuepictureInPictureButton.enabled = isPictureInPicturePossible}}



最后,如果用户点击了PiP按钮,AVPictureInPictureController将会重新初始化或者停止PIP模式
@IBAction func togglePictureInPictureMode(sender: UIButton) {if pictureInPictureController.pictureInPictureActive {pictureInPictureController.stopPictureInPicture()}else {pictureInPictureController.startPictureInPicture()}}


6.我可以关闭掉PiP功能吗?

当然!你所需要做的就是设置实例AVPlayerViewController 或者 WKWebView的属性  allowsPictureInPictureMediaPlayback为NO就行了。


7.我可以写AVPictureInPictureController的子类吗?

尽管写一个子类将会是很大的诱惑,但是确实不建议的。Apple警告道: “overriding this class’s methods is unsupported and results in undefined behavior.” 重写这个类的方法是不支持的,并且会造成意想不到的后果。同样,也可能会造成在你的app会被审核部门拒绝。


8.有什么方法可以在PiP窗口中设置主题吗或者改变扁标准的控制,或者添加更多的控制?

就现在来说,官方的AVKit框架文档并没有谈到任何的对于开发者来说的接口。所以有点轻微的失望,我们希望在下一个iOS版本中Apple将会给我们更多的自由设计。


9.关于使用画中画有更好的建议吗?

基本上同样的建议就是当你的app使用了画中画模式之后,你要及时的释放一些后台的资源,因为这可能会造成你的app被系统杀掉,所以当你的app转换到PIP模式的时候需要释放掉不用的资源

序:如有需要 iOS demo的可以联系



1 0
原创粉丝点击