本文字数:11934字
预计阅读时间:40分钟
背景
之前有看到有人用画中画实现时分秒的计时,顺手收藏了,一直没来及看。最近使用《每日英语听力》,突然发现它用画中画实现了听力语句的显示,顿时来了兴趣,所以来研究一下是怎么实现的?顺便也研究下画中画时分秒计时的实现——每次遇到某些平台每天固定时间开抢的时候,我都希望iPhone能够显示具体到秒的计时,这样就能知道什么时候开始点击合适,而不是每次都提前一分钟在那里不停的点点点却什么都抢不到...
实现
画中画一般是用来浮窗播放视频的,那如何让画中画播放自定义的界面而不是视频?下面分为5步具体来看下:
实现画中画功能,需要设置哪些开关,实现哪些方法;
基本的使用系统播放器时,画中画的实现;
自定义播放器时,画中画功能的实现又需要如何设置,有哪些不同;
如何通过画中画实现时分秒计时功能;
《每日英语听力》通过画中画播放英语听力语句时怎么实现的?
APP支持画中画功能
如何让APP支持画中画功能?首先需要设置App支持BackgroundModes
,然后勾选BackgroundModes
中的Audio, Airplay, and Picture in Picture
。
操作如下:
然后需要设置AVAudioSession
,在AppDelegate.Swift
中application(_:didFinishLaunchingWithOptions:)
方法设置如下代码:
导入
AVFoundation
设置
AVAudioSession
支持后台播放
// 导入AVFoundation
import AVFoundation
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 添加设置代码
do {
// 设置AVAudioSession.Category.playback后,在静音模式下,或者APP进入后台,或者锁定屏幕后还可以继续播放。
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.moviePlayback)
} catch {
print(error)
}
return true
}
使用系统播放器时画中画的实现
使用系统播放器AVPlayerViewController
来实现播放器画中画,首先导入AVKit
,获取要播放的资源,然后使用AVPlayerViewController
来进行播放,代码如下:
import AVKit
/// 获取播放的资源
fileprivate func playerResource() -> AVQueuePlayer? {
guard let videoURL = Bundle.main.url(forResource: "suancaidegang", withExtension: "mp4") else {
return nil
}
let item = AVPlayerItem(url: videoURL)
let player = AVQueuePlayer(playerItem: item)
player.actionAtItemEnd = .pause
return player
}
@IBAction func systemPlayerAction(_ sender: Any) {
guard let player = playerResource() else {
return
}
let avPlayerVC = AVPlayerViewController()
avPlayerVC.player = player
present(avPlayerVC, animated: true) {
player.play()
}
}
这里需要注意的是,一定要在真机上才可以看到画中画的效果,使用模拟器不行。运行后可以看到AVPlayerViewController
直接支持了画中画的播放;点击进入画中画后,之前全屏的播放界面自动关掉;点击画中画返回播放界面后,画中画关闭,但是之前的播放界面也没有重新打开,效果如下:而这里很明显,画中画返回不了之前的播放界面是有问题的,所以要修改一下,加入可以设置再进入画中画时全屏的播放界面不关闭,点击画中画的返回是否可以正常呢?这里
AVPlayerViewControllerDelegate
的方法 playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(_ playerViewController: AVPlayerViewController) -> Bool
可以控制进入画中画时是否关闭当前界面。
// 在此方法中添加avPlayerVC.delegate = self
@IBAction func systemPlayerAction(_ sender: Any) {