【问题标题】:How do I add gesture to AVPlayerController's subtitles?如何向 AVPlayerController 字幕添加手势?
【发布时间】:2021-07-08 02:09:53
【问题描述】:

请帮我解决问题..我找不到任何关于这个的问题..

我要在 AVPlayerViewController 中添加字幕。

我做到了。但是,我的客户想为字幕添加手势。

例如,

  1. 点击字幕的某个关键字
  2. 将“点击的关键字”传递给另一个控制器
  3. 只需使用 clikced 关键字显示另一个控制器。

首先...可以给字幕添加手势吗?

我没有太多的编码经验...

我的英语不太好.. sry..TT

【问题讨论】:

    标签: ios swift avplayer avplayerviewcontroller


    【解决方案1】:

    안녕金宇成!欢迎来到论坛。不幸的是,简短的回答是。没有 api 可以在特定的点击位置查询单词,甚至没有使用UILabel(或CATextLayer)呈现内容。

    更长的答案是:如果您真的想这样做,有一些选择,但我不会将其用于生产。在显示字幕时检查AVPlayerViewController 的视图层次结构将显示字幕是在FigFCRCALayerOutputNodeLayer 中呈现的。在运行 iOS 14.4 的模拟器上,该层位于 avPlayerVc.view.subviews.first?.subviews.first?.subviews.first?.layer.sublayers?.first?.sublayers?[1].sublayers?.first?.sublayers?.first?.sublayers?.first(这可能会在将来随时更改,甚至可能在此版本以下不起作用)。文字直接设置为图层content(包括圆角半透明背景视图)。

    我玩了一会儿 Vision,虽然它有点滞后,但它可以将图层内容 (CGImage) 提供给文本识别请求,然后将结果拆分为单词并检查触摸位置是否在边界内的话。为了获得触摸点,我将AVPlayerViewController 子类化(我知道,这很糟糕,但如果你直接使用AVPlayerLayer 会更容易)并将触摸从touchesBegan 转换为屏幕坐标:

    final class PlayerVC: AVPlayerViewController {
      var onTap: ((CGPoint) -> Void)?
    
      override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
    
        guard let tapLocation = touches.first?.location(in: nil) else { return }
        onTap?(tapLocation)
      }
    }
    

    在该位置获取单词的实际代码如下所示(playerVc 指向 PlayerVC 实例:

    func tap(tapLocation: CGPoint) {
        guard
            let subtitleLayer = playerVc.view.subviews.first?.subviews.first?.subviews.first?.layer.sublayers?.first?.sublayers?[1].sublayers?.first?.sublayers?.first?.sublayers?.first,
            CFGetTypeID(subtitleLayer.contents as CFTypeRef) == CGImage.typeID
        else { return }
    
        let image = subtitleLayer.contents as! CGImage
        let requestHandler = VNImageRequestHandler(cgImage: image)
        let recognizeTextHandler: (VNRequest, Error?) -> Void = { request, error in
            guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
    
            for observation in observations {
                guard let topCandidate = observation.topCandidates(1).first, topCandidate.string != "" else { continue }
    
                for word in topCandidate.string.components(separatedBy: " ") {
                    guard let range = topCandidate.string.range(of: word) else { continue }
    
                    if let boundinBox = try? topCandidate.boundingBox(for: range) {
    
                        let transform = CGAffineTransform.identity
                            .scaledBy(x: 1, y: -1)
                            .translatedBy(x: 0, y: -subtitleLayer.frame.size.height)
                            .scaledBy(x: subtitleLayer.frame.size.width, y: subtitleLayer.frame.size.height)
    
                        let convertedTopLeft = boundinBox.topLeft.applying(transform)
                        let convertedBottomRight = boundinBox.bottomRight.applying(transform)
    
                        let localRect = CGRect(x: convertedTopLeft.x,
                                                                     y: convertedTopLeft.y,
                                                                     width: convertedBottomRight.x - convertedTopLeft.x,
                                                                     height: convertedBottomRight.y - convertedTopLeft.y)
    
                        let globalRect = subtitleLayer.convert(localRect, to: nil)
    
                        if globalRect.contains(tapLocation) {
                            print("You tapped \(word)")
                        }
                    }
                }
            }
        }
    
        let request = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
        request.usesLanguageCorrection = false
        request.recognitionLevel = .accurate
    
        do {
            try requestHandler.perform([request])
        } catch {
            print("Unable to perform the request \(error)")
        }
    }
    

    【讨论】:

    • 谢谢。我在兰的SSABOO(主人)!!谢谢你的好意。我很好理解。您添加到代码和照片中的内容...真的非常感谢您。感觉是这样的。我觉得我在山洞里看到了光!!祝你好运一整天!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多