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

时间:2016-09-15 20:35:42

标签: ios swift video orientation avplayer

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

编辑:尝试添加 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的新子类<​​/ p>

import UIKit
import AVFoundation
import AVKit

class LandscapeVideoControllerViewController: AVPlayerViewController {

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return .landscapeLeft
}

}

但是收到错误消息&#34;方法不会覆盖其超类中的任何方法&#34;

4 个答案:

答案 0 :(得分:19)

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

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

我还没有机会对此进行测试,但它应该有效,请尝试一下,如果您有任何问题,请发布您的代码,我会查看并更新答案。< / p>

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

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

import AVKit

class LandscapeAVPlayerController: AVPlayerViewController {

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscapeLeft
    }
}

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

var playerViewController = LandscapeAVPlayerController()

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

注意2:在Swift中你通常会覆盖的很多配置相关的方法现在都是Swift 3中的属性,所以不要覆盖方法,而是覆盖“getter”&#39;对于财产

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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")
    }
}

答案 3 :(得分:0)

我最近遇到了这个问题,并发布了类似的解决方案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修改为所需的任何方向。