如何在 AVPlayer 中强制横向模式?
How to force landscape mode in AVPlayer?
我正在寻找一种方法来强制 AVplayer(视频)仅在横向模式下显示自身(左侧的主页按钮)。这可能吗?
编辑:尝试添加
playerViewController.supportedInterfaceOrientations = .landscapeLeft
收到错误消息
"Cannot assign to property: 'supportedInterfaceOrientations' is a get-only property"
import AVKit
import AVFoundation
UIViewController {
var videoPlayer = AVPlayer()
var playerViewController = AVPlayerViewController()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
play()
}
func play() {
playerViewController.supportedInterfaceOrientations = .landscapeLeft
let moviePath = Bundle.main.path(forResource: "full video", ofType: "mov")
if let path = moviePath {
let url = NSURL.fileURL(withPath: path)
let videoPlayer = AVPlayer(url: url)
let playerViewController = AVPlayerViewController()
playerViewController.player = videoPlayer
self.present(playerViewController, animated: true) {
if let validPlayer = playerViewController.player {
validPlayer.play()
playerViewController.showsPlaybackControls = false
}
}
}
}
}
编辑:尝试添加 AVPlayerViewController 的新子类
import UIKit
import AVFoundation
import AVKit
class LandscapeVideoControllerViewController: AVPlayerViewController {
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .landscapeLeft
}
}
但收到错误消息 "Method does not override any method from its superclass"
如果您使用 AVPlayerViewController
来呈现视频,您应该能够使用视图控制器的继承支持的界面方向 属性,像这样:
let vc = AVPlayerViewController()
vc.supportedInterfaceOrientations = .landscapeRight
// other configs and code to present VC
我还没有机会测试这个,但它应该可以工作,试一试,如果你有任何问题,请 post 你的代码,我会看看并更新答案.
编辑:Taytee 指出这是只读的 属性。
您应该能够通过扩展 AVPlayerController 并覆盖支持的方向属性来实现它,在单独的文件中创建此 class:
import AVKit
class LandscapeAVPlayerController: AVPlayerViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeLeft
}
}
然后在上面的代码中,您将更改 class 的用法,如
var playerViewController = LandscapeAVPlayerController()
注意 1:在上面的代码中,您创建了两个 AVPlayerController 实例,不需要第二个。
注意 2:您通常会在 Swift 中覆盖的许多与配置相关的方法现在是 Swift 3 中的属性,因此您无需覆盖方法,而是覆盖 'getter'对于 属性
只需创建 AVPlayerViewController
的子class
import AVKit
class LandscapePlayer: AVPlayerViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
return .landscapeLeft
}
}
如下图
let player = AVPlayer(url:Video_URL)
let playerController = LandscapePlayer()
playerController.player = player
present(playerController, animated: true) {
player.play()
}
自 Apple warns not to subclass AVPlayerViewController 以来,我发现一个更简单的解决方案是在呈现 AVPlayerViewController 实例之前将应用程序的方向更改为 .landscape,并在它被关闭时将其更改回来。
1。在应用代表中
我们为应用设置了支持的方向。就我而言,该应用程序仅支持 .portrait,但如果需要可以将其设置为 .all
class AppDelegate: UIResponder, UIApplicationDelegate {
var orientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return orientation
}
}
2。在 VC 中呈现 AVPlayerViewController
我们将使用 present 方法的完成处理程序将 playerController 的方向更改为横向。
class VCThatOpensTheVideo: UIViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
@IBAction func tappedPlayVideo(_ sender: Any) {
guard let path = Bundle.main.path(forResource: "video-name", ofType:"mp4") else { return }
let playerController = AVPlayerViewController()
let player = AVPlayer(url: URL(fileURLWithPath: path))
playerController.player = player
present(playerController, animated: true) {
player.play() // Optionally autoplay the video when it starts
self.appDelegate.orientation = .landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}
}
}
然后我们重写呈现VC到return的viewWillAppear方法回到.portrait
class VCThatOpensTheVideo: UIViewController {
override func viewWillAppear(_ animated: Bool) {
appDelegate.orientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
}
}
我最近遇到了这个问题并发布了一个类似的解决方案 here modifying Zell B. 的答案。
这是一个 Swift 5 版本,它将检测 AVPlayer 并更新方向设置。它不涉及对 AVPlayerViewController 进行子类化,因此它避免了任何意外行为。
只需将以下代码复制并粘贴到您的 AppDelegate 中(无需编辑):
func application(_ application: UIApplication,
supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if fetchCurrentVC(self.window?.rootViewController) is AVPlayerViewController {
return .allButUpsideDown
}
return .portrait
}
func fetchCurrentVC(_ viewController: UIViewController?) -> UIViewController? {
if let tabBarController = viewController as? UITabBarController {
return fetchCurrentVC(tabBarController.selectedViewController)
}
if let navigationController = viewController as? UINavigationController{
return fetchCurrentVC(navigationController.visibleViewController)
}
if let viewController = viewController?.presentedViewController {
return fetchCurrentVC(viewController)
}
return viewController
}
您可以将 .landscapeLeft 修改为您需要的任何方向。
我正在寻找一种方法来强制 AVplayer(视频)仅在横向模式下显示自身(左侧的主页按钮)。这可能吗?
编辑:尝试添加 playerViewController.supportedInterfaceOrientations = .landscapeLeft
收到错误消息 "Cannot assign to property: 'supportedInterfaceOrientations' is a get-only property"
import AVKit
import AVFoundation
UIViewController {
var videoPlayer = AVPlayer()
var playerViewController = AVPlayerViewController()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
play()
}
func play() {
playerViewController.supportedInterfaceOrientations = .landscapeLeft
let moviePath = Bundle.main.path(forResource: "full video", ofType: "mov")
if let path = moviePath {
let url = NSURL.fileURL(withPath: path)
let videoPlayer = AVPlayer(url: url)
let playerViewController = AVPlayerViewController()
playerViewController.player = videoPlayer
self.present(playerViewController, animated: true) {
if let validPlayer = playerViewController.player {
validPlayer.play()
playerViewController.showsPlaybackControls = false
}
}
}
}
}
编辑:尝试添加 AVPlayerViewController 的新子类
import UIKit
import AVFoundation
import AVKit
class LandscapeVideoControllerViewController: AVPlayerViewController {
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .landscapeLeft
}
}
但收到错误消息 "Method does not override any method from its superclass"
如果您使用 AVPlayerViewController
来呈现视频,您应该能够使用视图控制器的继承支持的界面方向 属性,像这样:
let vc = AVPlayerViewController()
vc.supportedInterfaceOrientations = .landscapeRight
// other configs and code to present VC
我还没有机会测试这个,但它应该可以工作,试一试,如果你有任何问题,请 post 你的代码,我会看看并更新答案.
编辑:Taytee 指出这是只读的 属性。
您应该能够通过扩展 AVPlayerController 并覆盖支持的方向属性来实现它,在单独的文件中创建此 class:
import AVKit
class LandscapeAVPlayerController: AVPlayerViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeLeft
}
}
然后在上面的代码中,您将更改 class 的用法,如
var playerViewController = LandscapeAVPlayerController()
注意 1:在上面的代码中,您创建了两个 AVPlayerController 实例,不需要第二个。
注意 2:您通常会在 Swift 中覆盖的许多与配置相关的方法现在是 Swift 3 中的属性,因此您无需覆盖方法,而是覆盖 'getter'对于 属性
只需创建 AVPlayerViewController
import AVKit
class LandscapePlayer: AVPlayerViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
return .landscapeLeft
}
}
如下图
let player = AVPlayer(url:Video_URL)
let playerController = LandscapePlayer()
playerController.player = player
present(playerController, animated: true) {
player.play()
}
自 Apple warns not to subclass AVPlayerViewController 以来,我发现一个更简单的解决方案是在呈现 AVPlayerViewController 实例之前将应用程序的方向更改为 .landscape,并在它被关闭时将其更改回来。
1。在应用代表中
我们为应用设置了支持的方向。就我而言,该应用程序仅支持 .portrait,但如果需要可以将其设置为 .all
class AppDelegate: UIResponder, UIApplicationDelegate {
var orientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return orientation
}
}
2。在 VC 中呈现 AVPlayerViewController
我们将使用 present 方法的完成处理程序将 playerController 的方向更改为横向。
class VCThatOpensTheVideo: UIViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
@IBAction func tappedPlayVideo(_ sender: Any) {
guard let path = Bundle.main.path(forResource: "video-name", ofType:"mp4") else { return }
let playerController = AVPlayerViewController()
let player = AVPlayer(url: URL(fileURLWithPath: path))
playerController.player = player
present(playerController, animated: true) {
player.play() // Optionally autoplay the video when it starts
self.appDelegate.orientation = .landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}
}
}
然后我们重写呈现VC到return的viewWillAppear方法回到.portrait
class VCThatOpensTheVideo: UIViewController {
override func viewWillAppear(_ animated: Bool) {
appDelegate.orientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
}
}
我最近遇到了这个问题并发布了一个类似的解决方案 here modifying Zell B. 的答案。
这是一个 Swift 5 版本,它将检测 AVPlayer 并更新方向设置。它不涉及对 AVPlayerViewController 进行子类化,因此它避免了任何意外行为。
只需将以下代码复制并粘贴到您的 AppDelegate 中(无需编辑):
func application(_ application: UIApplication,
supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if fetchCurrentVC(self.window?.rootViewController) is AVPlayerViewController {
return .allButUpsideDown
}
return .portrait
}
func fetchCurrentVC(_ viewController: UIViewController?) -> UIViewController? {
if let tabBarController = viewController as? UITabBarController {
return fetchCurrentVC(tabBarController.selectedViewController)
}
if let navigationController = viewController as? UINavigationController{
return fetchCurrentVC(navigationController.visibleViewController)
}
if let viewController = viewController?.presentedViewController {
return fetchCurrentVC(viewController)
}
return viewController
}
您可以将 .landscapeLeft 修改为您需要的任何方向。