AVPlayer 强制全屏横向模式
AVPlayer force landscape mode for fullscreen
我正在使用我的应用程序中大约 320x200 帧的 AVPlayer 播放视频。 avplayer 还添加了一个自定义 'fullscreen' 按钮作为叠加层,就像 youtube 应用程序播放器一样。我如何实现它,以便当应用程序处于纵向模式并且用户单击全屏按钮时,视频将旋转到全屏但处于横向模式?我尝试使用 transform 并且它部分起作用,因为当它处于全屏模式时,如果用户将设备切换到纵向; avplayer 框架突然改变。我希望它像 youtube 应用程序一样工作,即在全屏模式下,即使用户旋转设备,它也应该保持不变。关闭全屏时只应 return 到原始大小。由于应用程序的设计,我不想使用 avplayerviewcontroller。在此先感谢您的帮助。
在我看来,您应该创建一个 FullScreenViewController,强制始终支持横向。然后在按下 "fullscreen" 按钮时从您当前的视图控制器显示该视图控制器,并将 AVPlayer 实例传递给它,然后为 AVPlayerLayer 设置框架并继续播放。解雇后,它会恢复正常,我的意思是你的 "portrait" 模式。
好问题!允许 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)
}
}
}
我正在使用我的应用程序中大约 320x200 帧的 AVPlayer 播放视频。 avplayer 还添加了一个自定义 'fullscreen' 按钮作为叠加层,就像 youtube 应用程序播放器一样。我如何实现它,以便当应用程序处于纵向模式并且用户单击全屏按钮时,视频将旋转到全屏但处于横向模式?我尝试使用 transform 并且它部分起作用,因为当它处于全屏模式时,如果用户将设备切换到纵向; avplayer 框架突然改变。我希望它像 youtube 应用程序一样工作,即在全屏模式下,即使用户旋转设备,它也应该保持不变。关闭全屏时只应 return 到原始大小。由于应用程序的设计,我不想使用 avplayerviewcontroller。在此先感谢您的帮助。
在我看来,您应该创建一个 FullScreenViewController,强制始终支持横向。然后在按下 "fullscreen" 按钮时从您当前的视图控制器显示该视图控制器,并将 AVPlayer 实例传递给它,然后为 AVPlayerLayer 设置框架并继续播放。解雇后,它会恢复正常,我的意思是你的 "portrait" 模式。
好问题!允许 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)
}
}
}