You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何检测AVPlayerViewController中用户的字幕选择设置

好问题!我之前在做视频播放项目的时候刚好研究过这个,完全可以通过AVPlayerViewController和AVFoundation的相关API来检测用户的字幕选择,下面给你一步步拆解:

检测AVPlayerViewController的字幕设置方法

核心思路

AVPlayerViewController的preferredMediaSelection属性是关键,它存储了用户对音轨、字幕等媒体选项的选择。我们可以通过这个属性结合AVFoundation的AVMediaSelectionGroupAVMediaSelectionOption类来判断用户的字幕状态(关闭、自动、特定语言)。

具体实现步骤

1. 获取字幕媒体组

首先需要从当前播放的资源中获取字幕对应的媒体组(对应AVMediaCharacteristicLegible类型),如果资源本身没有字幕,这一步会返回nil,需要提前判断。

2. 判断字幕选择状态

拿到字幕组后,我们可以对比用户选择的选项和系统提供的“关闭”选项、默认(自动)选项,来区分不同状态:

func checkSubtitleSelection(for playerVC: AVPlayerViewController) {
    guard let player = playerVC.player,
          let asset = player.currentItem?.asset else {
        print("当前没有播放的媒体资源")
        return
    }
    
    // 获取字幕对应的媒体组
    guard let legibleGroup = asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else {
        print("该媒体没有字幕资源")
        return
    }
    
    // 获取用户当前选择的字幕选项
    let selectedOption = playerVC.preferredMediaSelection.selectedMediaOption(in: legibleGroup)
    
    // 1. 判断是否为「关闭字幕」
    let closedCaptionOption = AVMediaSelectionOption.mediaSelectionOptionWithoutMediaCharacteristics([.legible], mediaGroup: legibleGroup)
    if selectedOption == closedCaptionOption {
        print("用户选择了关闭字幕")
        return
    }
    
    // 2. 判断是否为「自动模式」
    if selectedOption == legibleGroup.defaultMediaSelectionOption {
        print("用户选择了自动字幕模式")
        return
    }
    
    // 3. 特定语言字幕的情况
    if let locale = selectedOption.locale {
        print("用户选择了字幕语言:\(locale.identifier)(比如zh-CN、en-US)")
    } else if let displayName = selectedOption.displayName {
        print("用户选择了字幕:\(displayName)")
    }
}

3. 监听字幕设置的变化

如果需要实时监听用户在播放过程中更改字幕设置的操作,可以通过KVO监听preferredMediaSelection的变化:

// 在合适的地方添加监听(比如viewDidLoad)
playerViewController.addObserver(self, forKeyPath: #keyPath(AVPlayerViewController.preferredMediaSelection), options: [.new], context: nil)

// 实现KVO回调方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard keyPath == #keyPath(AVPlayerViewController.preferredMediaSelection),
          let playerVC = object as? AVPlayerViewController else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    }
    // 调用检测方法
    checkSubtitleSelection(for: playerVC)
}

// 记得在销毁时移除监听
deinit {
    playerViewController.removeObserver(self, forKeyPath: #keyPath(AVPlayerViewController.preferredMediaSelection))
}

注意事项

  • 有些媒体资源的“自动”选项可能会根据系统语言自动匹配字幕,这时候defaultMediaSelectionOption就是对应系统语言的字幕选项,判断逻辑依然有效。
  • 如果需要兼容更早版本的iOS,注意部分API的可用性(比如mediaSelectionOptionWithoutMediaCharacteristics:是iOS 9+可用)。
  • 字幕选项的displayName是本地化后的名称,比如中文环境下会显示“中文”“英文”,而locale.identifier是标准的语言代码,更适合做逻辑判断。

内容的提问来源于stack exchange,提问作者picciano

火山引擎 最新活动