如何在 AVPlayer 中强制横向模式?

Posted

技术标签:

【中文标题】如何在 AVPlayer 中强制横向模式?【英文标题】:How to force landscape mode in AVPlayer? 【发布时间】:2016-09-15 20:35:42 【问题描述】:

我正在寻找一种方法来强制 AVplayer(视频)仅在横向模式下显示(左侧的主页按钮)。这可能吗?

编辑:尝试添加 playerViewController.supportedInterfaceOrientations = .landscapeLeft

收到错误消息 "无法分配给属性:'supportedInterfaceOrientations' 是一个只能获取的属性"

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
  


但收到错误消息“方法未覆盖其超类中的任何方法”

【问题讨论】:

【参考方案1】:

如果您使用AVPlayerViewController 来呈现视频,您应该能够使用视图控制器继承的受支持的 iterface 方向属性,如下所示:

let vc = AVPlayerViewController()
vc.supportedInterfaceOrientations = .landscapeRight
// other configs and code to present VC

我没有机会对此进行测试,但它应该可以工作,试一试,如果您有任何问题,请发布您的代码,我会查看并更新答案。

编辑:Taytee 指出这是一个只读属性。

您应该能够通过扩展 AVPlayerController 并覆盖支持的方向属性来实现它,在单独的文件中创建此类:

import AVKit

class LandscapeAVPlayerController: AVPlayerViewController 

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask 
        return .landscapeLeft
    

然后在上面的代码中,您将更改使用的类

var playerViewController = LandscapeAVPlayerController()

注意 1:在上面的代码中,您创建了两个 AVPlayerController 实例,您不需要第二个。

注意 2:您通常会在 Swift 中覆盖的许多与配置相关的方法现在在 Swift 3 中是属性,因此您无需覆盖方法,而是覆盖属性的“getter”

【讨论】:

尝试添加继承的受支持的界面方向属性,并收到错误消息“无法分配给属性:'supportedInterfaceOrientations' 是仅获取属性” - 有什么想法吗? 啊,是的,我应该记得对不起。我已经更新了答案 编辑了我的问题-我创建了一个新的 swift 文件并添加了覆盖,但是我收到错误“方法不会覆盖其超类中的任何方法”,如果我取消覆盖我得到“方法supportedInterfaceOrientations() 与objective-c 选择器'supportedInterfaceOrientations' 与getter 冲突'supportedInterfaceOrientations 从超类'UIViewController' 与相同的objective-c 选择器” - 任何想法? 但是苹果限制了这个控制器的继承。 link on apple docDo not subclass AVPlayerViewController. Overriding this class’s methods is unsupported and results in undefined behavior. 是的,我不认为覆盖这个属性会导致任何问题。该警告更多地与控制器的整体功能有关【参考方案2】:

只需创建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()

【讨论】:

阅读苹果文档:developer.apple.com/documentation/avkit/… 重要不要继承 AVPlayerViewController。不支持覆盖此类的方法,并导致未定义的行为。【参考方案3】:

从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

我们将使用本方法的完成处理程序将 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的viewWillAppear方法返回到.portrait

class VCThatOpensTheVideo: UIViewController 

    override func viewWillAppear(_ animated: Bool) 
        appDelegate.orientation = .portrait
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
    

【讨论】:

【参考方案4】:

我最近遇到了这个问题并发布了类似的解决方案here修改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 中强制横向模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制对话框的横向模式?

使用移动浏览器(Unity webgl)时如何强制横向模式?

即使 iPad 处于纵向模式,如何强制 iPad 上的电视处于横向模式

AVPlayer 在 Swift 中横向播放视频

如何强制 iOS 应用以纵向模式启动

AS3 - 仅 iOS 强制横向模式?