【问题标题】:AVPlayer force landscape mode for fullscreenAVPlayer 强制横向模式全屏
【发布时间】:2016-09-12 00:33:43
【问题描述】:

我正在使用我的应用程序中大约 320x200 帧的 AVPlayer 播放视频。 avplayer 还添加了一个自定义的“全屏”按钮作为叠加层,就像 youtube 应用程序播放器一样。如何实现它,当应用程序处于纵向模式并且用户单击全屏按钮时,视频将旋转到全屏但处于横向模式?我尝试使用 transform 并且它部分工作,因为当它处于全屏模式时,如果用户将设备切换到纵向; avplayer 框架突然改变。我希望它像 youtube 应用程序一样工作,即在全屏模式下,即使用户旋转设备,它也应该保持不变。只有在关闭全屏时才应返回原始大小。由于应用程序的设计,我不想使用 avplayerviewcontroller。提前感谢您的帮助。

【问题讨论】:

  • 在全屏播放视频时,将supportedInterfaceOrientations设置为仅横向
  • 这与下面给出的答案一起工作,您是否也可以查看我的 cmets 以解决关闭全屏实现的问题?
  • 澄清一下:您的问题是当您关闭全屏播放器时 - 较小的播放器不知道从哪里继续播放?
  • 如果是这样,尝试通过unwindSegue 传递变量作为可能的解决方案
  • 我实际上并没有使用故事板。当在播放器上按下关闭全屏按钮时会发生什么情况,呈现控制器会关闭全屏控制器。传递给模态的播放器容器是呈现控制器的容器视图。为简化起见,VC A 具有包含播放器和控件的子视图 SV。在全屏上,VC A 向 VC B 显示 SV。 VC B 将其视图设置为 SV。在全屏关闭时,VC A 关闭 VC B。现在 VC A 中的 SV 为空白。

标签: ios iphone video avplayer avplayerlayer


【解决方案1】:

好问题!允许 AVPLayerLayer 全屏显示很重要。单个视图处理纵向和横向的大量应用程序配置,只是为了显示全屏视频?请。

变换和帧操作可以解决这个问题:

extension CGAffineTransform {

    static let ninetyDegreeRotation = CGAffineTransform(rotationAngle: CGFloat(M_PI / 2))
}

extension AVPlayerLayer {

    var fullScreenAnimationDuration: TimeInterval {
        return 0.15
    }

    func minimizeToFrame(_ frame: CGRect) {
        UIView.animate(withDuration: fullScreenAnimationDuration) {
            self.setAffineTransform(.identity)
            self.frame = frame
        }
    }

    func goFullscreen() {
        UIView.animate(withDuration: fullScreenAnimationDuration) {
            self.setAffineTransform(.ninetyDegreeRotation)
            self.frame = UIScreen.main.bounds
        }
    }
}

设置 AVPlayerLayer 的框架会改变它的父框架。将原始帧保存在您的视图子类中,以将 AVPLayerLayer 最小化回原来的位置。这允许自动布局。

重要 - 仅当播放器位于视图子类的中心时才有效。

不完整的例子:

class AVPlayerView: UIView {

    fileprivate var avPlayerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    fileprivate var hasGoneFullScreen = false
    fileprivate var isPlaying = false
    fileprivate var originalFrame = CGRect.zero

    func togglePlayback() {
        if !hasGoneFullScreen {
            originalFrame = frame
            hasGoneFullScreen = true
        }

        isPlaying = !isPlaying
        if isPlaying {
            avPlayerLayer.goFullscreen()
            avPlayerLayer.player?.play()
        } else {
            avPlayerLayer.player?.pause()
            avPlayerLayer.minimizeToFrame(originalFrame)
        }
    }
}

【讨论】:

    【解决方案2】:

    在我看来,您应该创建一个 FullScreenViewController,它强制始终支持横向。然后在按下“全屏”按钮时从当前视图控制器呈现该视图控制器并将 AVPlayer 实例传递给它,然后为 AVPlayerLayer 设置框架并继续播放。关闭后,它会恢复正常,我的意思是你的“肖像”模式。

    【讨论】:

    • 这是我的想法,也是一个可能的解决方案。希望看看有没有其他办法。
    • 我用 FullScreenViewController 尝试了这个解决方案,并传递了具有 AVPlayerLayer 以及自定义控件 UIView 的容器 UIView。到目前为止,一切都很好。但是,在单击关闭全屏时,我关闭了 FullScreenViewController,但是播放器不会在我的呈现视图中播放。如何在 FullScreenViewController 中实现关闭全屏?因为我认为既然它被解雇了,它的视图,即播放器容器视图就会被释放。
    • 部分代码:FullScreenViewController *controller = [[FullScreenViewController alloc] init]; controller.view = self.playerContainer; // the container uiview [self presentViewController:controller animated:YES completion:nil];
    • 好的,我只是将视频容器视图作为子视图读取到呈现视图,它工作正常..但是覆盖控件视图不再显示。知道会发生什么吗?
    • 如果您使用自定义View呈现视频,则不再支持内置控件,您必须创建自己的UI控件,例如控件底部栏和标题栏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多