在 swift 中,如何在 AVPlayerViewController 中播放视频时检测触摸
Posted
技术标签:
【中文标题】在 swift 中,如何在 AVPlayerViewController 中播放视频时检测触摸【英文标题】:In swift, how to detect touch while playing video in AVPlayerViewController 【发布时间】:2016-10-05 23:06:18 【问题描述】:我以编程方式将AVPlayerViewController
添加到UIViewController
。当播放器完成播放(playerDidFinishPlaying)时,我能够收到通知。我也想知道用户在播放视频时是否触摸过屏幕,我没有找到任何相关通知。
【问题讨论】:
当用户按下前进/后退按钮时如何检测触摸? 【参考方案1】:解决方案是创建一个AVPlayerViewController
的Base类并覆盖touchesBegan(_:with:)方法:
斯威夫特 2:
自定义基类:
class CustomAVPlayerViewController: AVPlayerViewController
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
print("touchesBegan")
视图控制器:
let videoURL = NSURL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(URL: videoURL!)
let playerViewController = CustomAVPlayerViewController()
playerViewController.player = player
self.presentViewController(playerViewController, animated: true)
playerViewController.player!.play()
斯威夫特 3:
自定义基类:
class CustomAVPlayerViewController: AVPlayerViewController
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
print("touchesBegan")
视图控制器:
let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(url: videoURL!)
let playerViewController = CustomAVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true)
playerViewController.player!.play()
别忘了import AVKit
和import AVFoundation
。
每次点击playerViewController
,都会打印“touchesBegan”。
【讨论】:
关于参考文档的任何想法:不要继承 AVPlayerViewController。不支持覆盖此类的方法并导致未定义的行为。 参考@Bruce 的评论 (Apple Documentation):touchesBegan 是一个 [UIResponder] (developer.apple.com/reference/uikit/uiresponder) 方法 (UIResponder->UIViewController->AVPlayerViewController)。在我们的例子中,UIResponder 应该处理触摸事件,它与 AVPlayerViewController 的核心功能无关,即重写此方法不会反映 AVPlayerViewController 如何处理视频 - 例如 - 这样做的方法不应该是被覆盖。感谢您的注意。 @AhmadF,当用户按下前进/后退按钮时如何检测触摸? 这不是一个干净的解决方案。正确的做法是将手势识别器放入 AVPlayerViewController 的 contentOverlayView 中。请参阅我对***.com/questions/36878609/…的回复(Objective C 源,抱歉) @TyR ContentOverlay 解决方案不起作用。【参考方案2】:我遇到了同样的问题。 contentOverlayView 仅在 tvos 中可用,所以这不是一个选项。
我最终在我添加 AVPlayer 的 UIImageView 上添加了一个 UIView。我在 UIView 上将背景颜色设置为清除,因此它不可见,但可以接收手势。这为点击手势识别器提供了一个目标。
【讨论】:
【参考方案3】:我也是这样解决的。子类化 AVPlayerViewController 将适用于 ios 11.4.1,但不适用于 iOS 12 及更高版本。因此,解决方案是在 playerviewcontroller contentoverlayview 上添加子视图,然后在该子视图上添加任何手势或按钮来检测触摸。这是相同的代码sn-p::
//此通知是为连续播放视频而添加的,如果您只需要播放一次视频,您可以将其删除。
private func playVideo()
guard let path = Bundle.main.path(forResource: "BG01", ofType:"mp4") else
debugPrint("video.m4v not found")
return
self.player = AVPlayer(url: URL(fileURLWithPath: path))
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: .main) [weak self] _ in
self?.player?.seek(to: kCMTimeZero)
self?.player?.play()
let playerController : AVPlayerViewController? = AVPlayerViewController()
let btn : UIButton = UIButton()
btn.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
btn.addTarget(self, action: #selector(touchDetect), for: .touchUpInside)
btn.backgroundColor = UIColor.clear
playerController?.contentOverlayView?.addSubview(btn)
// playerController?.homeVCProtocolDelegate = self as HomeVCProtocol
playerController?.player = player
playerController?.showsPlaybackControls = false
self.player?.play()
present(playerController!, animated: false)
self.player?.play()
@objc func touchDetect()
// Here you will get the call
【讨论】:
为什么不能在 iOS 12+ 上运行?以上是关于在 swift 中,如何在 AVPlayerViewController 中播放视频时检测触摸的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 如何在 Swift 中获取另一个应用程序的 NSDockTile 对象?
如何在 Swift 中归档和取消归档自定义对象?或者如何在 Swift 中将自定义对象保存到 NSUserDefaults?