Swift:调整 AVPlayerLayer 的大小以匹配其父容器的边界
Posted
技术标签:
【中文标题】Swift:调整 AVPlayerLayer 的大小以匹配其父容器的边界【英文标题】:Swift: Resize an AVPlayerLayer to match the bounds of its parent container 【发布时间】:2015-03-12 01:06:24 【问题描述】:我有一个使用AVPlayer
和AVPlayerLayer
(Swift,ios 8.2)播放的本地视频,当它的父视图(introView
)调整大小时,我需要调整AVPlayerLayer
(introPlayerLayer
)的大小,包括方向变化。到目前为止,我尝试过的任何方法似乎都不起作用,而且 playerLayer
的大小和位置错误。
AVPlayer
使用本地 mp4 视频设置,AVPlayerLayer
使用该播放器初始化。然后将该层作为子层添加到父视图。
这是我的代码:
func playIntro()
let path = NSBundle.mainBundle().pathForResource("intro", ofType: "mp4")
let url = NSURL.fileURLWithPath(path!)
let introPlayer = AVPlayer(URL: url)
introPlayer.allowsExternalPlayback = false
var introPlayerLayer = AVPlayerLayer(player: introPlayer)
introView.layer.addSublayer(introPlayerLayer)
introPlayerLayer.frame = introView.bounds
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: introPlayer.currentItem)
introView.hidden = false
introPlayer.play()
我应该将AVPlayerLayer
添加为UIView
的子层,还是应该将父容器(UIView
) 子类化,如https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html 的“播放器视图”部分所示。如果是这样,我将如何在 Swift 中编写 PlayerView
子类(在 Objective-C 中显示)?
提前感谢您的任何帮助。
【问题讨论】:
introPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
:)
@DeVladinci - 谢谢!
【参考方案1】:
斯威夫特 3.
private func playVideo()
guard let path = Bundle.main.path(forResource: "video", ofType:"mp4") else
debugPrint("video.m4v not found")
return
let player = AVPlayer(url: URL(fileURLWithPath: path))
var playerLayer: AVPlayerLayer?
playerLayer = AVPlayerLayer(player: player)
playerLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
playerLayer!.frame = self.view.frame
self.view!.layer.addSublayer(playerLayer!)
player.play()
【讨论】:
在使用子视图而不是主视图时甚至不显示我的播放器。 好答案。谢谢。【参考方案2】:我想,在我自己的项目中,我能够做你想做的事情。这是没有子类化的。这是我的代码:
override func viewWillLayoutSubviews()
previewScene()
func previewScene()
var firstAsset: AVAsset!, secondAsset: AVAsset!, thirdAsset: AVAsset!
firstAsset = MediaController.sharedMediaController.s3Shot1
secondAsset = MediaController.sharedMediaController.s3Shot2
thirdAsset = MediaController.sharedMediaController.s3Shot3
if firstAsset != nil && secondAsset != nil && thirdAsset != nil
let assets = [firstAsset, secondAsset, thirdAsset]
var shots = [AVPlayerItem]()
for item in assets
let shot = AVPlayerItem(asset: item)
shots.append(shot)
self.videoPlayer = AVQueuePlayer(items: shots)
self.playerLayer = AVPlayerLayer(player: self.videoPlayer)
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
AVPlayerItemDidPlayToEndTimeNotification, object: self.videoPlayer.items().last)
self.videoPreviewLayer.layer.addSublayer(playerLayer)
self.playerLayer.frame = self.videoPreviewLayer.bounds
【讨论】:
videoPreviewLayer 是我的视图控制器内部的一个矩形视图。 @IBOutlet weak var videoPreviewLayer: UIView! 可以在这里给我建议:***.com/questions/54745359/…【参考方案3】:introView.layer.masksToBounds = true
也可能有帮助
【讨论】:
你能扩展一下这个答案吗? ***.com/help/how-to-answer @RichBenner 我在让视频层保持在父层范围内时遇到问题。我使用self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
填充框架,但还需要masksToBounds = true
将其包含在父层的边界内。我不是经验丰富的 iOS 开发人员,但它对我有用。以上是关于Swift:调整 AVPlayerLayer 的大小以匹配其父容器的边界的主要内容,如果未能解决你的问题,请参考以下文章
iOS Swift UIImage 调整大小影响性能的问题;调整大小时出现意外尺寸[重复]
禁用 UILabel、UIText 等的自动调整字体。在 iOS/Swift 中?