在 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】:

解决方案是创建一个AVPlayerViewControllerBase类并覆盖touches​Began(_:​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 AVKitimport 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中制作一个二维数组

Swift - 如何在 Swift 中获取另一个应用程序的 NSDockTile 对象?

如何在 Swift 中归档和取消归档自定义对象?或者如何在 Swift 中将自定义对象保存到 NSUserDefaults?

如何在 Swift 中使用 MKPolylineView

如何在 kotlin native 中使用 swift 库?

如何在 Swift 中使用`syslog`