AVPictureInPictureController 在背景应用程序时不会自动启动画中画
AVPictureInPictureController doesn't automatically start picture-in-picture when backgrounding the app
使用 AVPlayer
+ AVPlayerLayer
+ AVPictureInPictureController
创建自定义视频播放器时 iPhone 运行ning iOS 14 ( beta 7) 在从 UIButton 操作调用 player.start()
后应用程序进入后台时,视频不会自动进入画中画模式。
问题不会在使用 AVPlayerViewController
时重现,这似乎表明 iOS 14 上的 AVPictureInPictureController
通常有问题,但我想知道是否还有其他人 运行 进入这个问题并知道任何解决方法。我还在 rdar://8620271
下向 Apple 提交了这个问题
示例代码。
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
private let player = AVPlayer(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
private var pictureInPictureController: AVPictureInPictureController!
private var playerView: PlayerView!
private var playButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
playerView = PlayerView(frame: CGRect(x: 0, y: 44, width: view.bounds.width, height: 200))
playerView.backgroundColor = .black
playerView.playerLayer.player = player
view.addSubview(playerView)
playButton = UIButton(frame: CGRect(x: view.bounds.midX - 50, y: playerView.frame.maxY + 20, width: 100, height: 22))
playButton.setTitleColor(.blue, for: .normal)
playButton.setTitle("Play", for: .normal)
playButton.addTarget(self, action: #selector(play), for: .touchUpInside)
view.addSubview(playButton)
pictureInPictureController = AVPictureInPictureController(playerLayer: playerView.playerLayer)
do {
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setMode(.moviePlayback)
try audioSession.setActive(true)
} catch let e {
print(e.localizedDescription)
}
}
@objc func play() {
player.play()
}
}
class PlayerView: UIView {
override class var layerClass: AnyClass {
return AVPlayerLayer.self
}
var playerLayer: AVPlayerLayer! {
return layer as? AVPlayerLayer
}
}
问题的根本原因是双重的:
AVAudioSession.sharedInstance().setActive(true)
必须在 初始化 AVPictureInPictureController
之前调用。
AVPlayerLayer
的帧大小必须具有不大于 16/9 的宽高比(作为单独的错误提交,rdar://8689203
)
对于 iPad,视频必须与设备宽度相同(在任何给定方向上)。没有单独的 rdar,因为 Apple 已经承认了另一个错误。
(上面的例子中没有第二期)
Apple 已经承认了这些错误,并向我报告说它们已经/将被修复(雷达实际导致回复的罕见情况!)
从 iOS 14.2 开始,Apple 公开了一个 api 以在应用程序进入后台时启动 PIP:
if #available(iOS 14.2, *) {
pictureInPictureController.canStartPictureInPictureAutomaticallyFromInline = true
}
此外,值得注意的是,Apple 禁止在没有用户手动点击按钮的情况下启动画中画。这将导致应用程序被拒绝。
最好的办法是使用上面提到的 Apple API 来避免被拒绝。
使用 AVPlayer
+ AVPlayerLayer
+ AVPictureInPictureController
创建自定义视频播放器时 iPhone 运行ning iOS 14 ( beta 7) 在从 UIButton 操作调用 player.start()
后应用程序进入后台时,视频不会自动进入画中画模式。
问题不会在使用 AVPlayerViewController
时重现,这似乎表明 iOS 14 上的 AVPictureInPictureController
通常有问题,但我想知道是否还有其他人 运行 进入这个问题并知道任何解决方法。我还在 rdar://8620271
示例代码。
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
private let player = AVPlayer(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
private var pictureInPictureController: AVPictureInPictureController!
private var playerView: PlayerView!
private var playButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
playerView = PlayerView(frame: CGRect(x: 0, y: 44, width: view.bounds.width, height: 200))
playerView.backgroundColor = .black
playerView.playerLayer.player = player
view.addSubview(playerView)
playButton = UIButton(frame: CGRect(x: view.bounds.midX - 50, y: playerView.frame.maxY + 20, width: 100, height: 22))
playButton.setTitleColor(.blue, for: .normal)
playButton.setTitle("Play", for: .normal)
playButton.addTarget(self, action: #selector(play), for: .touchUpInside)
view.addSubview(playButton)
pictureInPictureController = AVPictureInPictureController(playerLayer: playerView.playerLayer)
do {
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setMode(.moviePlayback)
try audioSession.setActive(true)
} catch let e {
print(e.localizedDescription)
}
}
@objc func play() {
player.play()
}
}
class PlayerView: UIView {
override class var layerClass: AnyClass {
return AVPlayerLayer.self
}
var playerLayer: AVPlayerLayer! {
return layer as? AVPlayerLayer
}
}
问题的根本原因是双重的:
AVAudioSession.sharedInstance().setActive(true)
必须在 初始化AVPictureInPictureController
之前调用。AVPlayerLayer
的帧大小必须具有不大于 16/9 的宽高比(作为单独的错误提交,rdar://8689203
)对于 iPad,视频必须与设备宽度相同(在任何给定方向上)。没有单独的 rdar,因为 Apple 已经承认了另一个错误。
(上面的例子中没有第二期)
Apple 已经承认了这些错误,并向我报告说它们已经/将被修复(雷达实际导致回复的罕见情况!)
从 iOS 14.2 开始,Apple 公开了一个 api 以在应用程序进入后台时启动 PIP:
if #available(iOS 14.2, *) {
pictureInPictureController.canStartPictureInPictureAutomaticallyFromInline = true
}
此外,值得注意的是,Apple 禁止在没有用户手动点击按钮的情况下启动画中画。这将导致应用程序被拒绝。 最好的办法是使用上面提到的 Apple API 来避免被拒绝。