在Swift中,如何在AVPlayerViewController播放视频时检测触摸?

6

我已经以编程方式向UIViewController添加了一个AVPlayerViewController。当播放器完成播放(playerDidFinishPlaying)时,我能够收到通知。我还想知道用户在视频播放期间是否触摸了屏幕,但是我没有找到任何相关的通知。


如何在用户按下前进/后退按钮时检测触摸? - pkc456
3个回答

7
解决方案是创建一个AVPlayerViewController的基类,并重写touches​Began(_:​with:​)方法:

Swift 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()
}

Swift 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"。


2
关于参考文档,有什么想法吗?请勿子类化AVPlayerViewController。覆盖此类的方法是不受支持的,并会导致未定义的行为。 - Bruce
1
参考@Bruce的评论(Apple文档):_touchesBegan_是一个UIResponder方法(UIResponder->UIViewController->AVPlayerViewController)。在我们的情况下,UIResponder应该负责触摸事件,它与AVPlayerViewController的核心功能无关。也就是说,覆盖此方法不会影响AVPlayerViewController处理视频的方式-例如-不应覆盖执行此操作的方法。 感谢您的注意。 - Ahmad F
@AhmadF,如何在用户按下前进/后退按钮时检测触摸? - pkc456
这不是一个干净的解决方案。正确的方法是将手势识别器放入AVPlayerViewController的contentOverlayView中。请参见我的回复(Objective C源代码,抱歉)https://dev59.com/mloU5IYBdhLWcg3w_KeN - TyR
@TyR 的 ContentOverlay 解决方案没有起作用。 - Rajesh Budhiraja

0
我遇到了同样的问题。contentOverlayView 只在 tvOS 上可用,所以那不是一个选项。
于是我在添加 AVPlayer 的 UIImageView 上又加了一个 UIView。我将这个 UIView 的背景颜色设为透明,这样它就看不见了,但可以接收手势。这样就提供了一个目标供触摸手势识别器使用。

0
我解决了同样的问题。在iOS 11.4.1上,子类化AVPlayerViewController可以工作,但在iOS 12及以上版本上不行。因此,解决方案是在playerviewcontroller contentoverlayview上添加子视图,然后在该子视图上添加任何手势或按钮以检测触摸。以下是相应的代码片段:
//为了持续播放视频而添加此通知,如果您只需要播放一次视频,则可以将其删除。
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+上运行? - Rajesh Budhiraja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接