AVPlayerViewController 不显示字幕控件

问题描述

我有一个应用可以在 AVPlayer 中播放 Vimeo 视频。以前,我在 AVPlayerLayer 中播放它们并使用我实现的 UI 处理切换字幕语言(或隐藏字幕)。现在我被要求切换到 AVPlayerViewController,但是当它播放相同的视频时,它的字幕语言切换 UI(基本上是语言菜单的一个小文本气泡图标)永远不会出现,并且视频总是以英文字幕播放,无论在 iOS 设置:常规中选择何种语言。

要为 AVAsset 创建 AVPlayer,我将字幕提取为 .vtt 文件,并使用以下代码创建包含视频、音频和文本轨道的组合 AVMutableComposition。视频可以在本地缓存或流式传输,因此 URL 路径可以是远程服务器或本地,但我总是下载文本轨道,因此 textTrackPath 始终是本地的。

func createCaptionedVideoFrom(_ localVideoAsset: AVAsset,url: URL) -> AVMutableComposition? {
    do {
        let fileName = url.lastPathComponent
        
        guard let tracksRecord = TextTracks.tracksForGroupLesson(self) else {
            return nil // no langauge tracks
        }
        
        // Create resource for combined tracks
        let videoPlusSubtitles = AVMutableComposition()
        
        // Add video track
        guard let existingVideo = localVideoAsset.tracks(withMediaType: .video)[safe: 0] else {
            Logger.error("No video track in local video asset named: \(name) fileName: \(fileName)")
            return nil
        }
        guard let videoTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .video,preferredTrackID: kCMPersistentTrackID_Invalid) else {
            Logger.error("Could not create video track in new video named: \(name) fileName: \(fileName)")
            return nil
        }
        try videoTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero,duration: localVideoAsset.duration),of: existingVideo,at: CMTime.zero)
        
        // Add audio track
        guard let existingAudio = localVideoAsset.tracks(withMediaType: .audio)[safe: 0] else {
            Logger.error("No audio track in local video asset named: \(name) fileName: \(fileName)")
            return nil
        }
        guard let audioTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .audio,preferredTrackID: kCMPersistentTrackID_Invalid) else {
            Logger.error("Can't create audio track in new video named: \(name) fileName: \(fileName)")
            return nil
        }
        try audioTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero,of: existingAudio,at: CMTime.zero)
        
        for textTrack in tracksRecord.tracks {
            // add text track
            guard let textTrackPath = textTrack.cachedLocalPath else {
                Logger.error("Text track: \(textTrack) for group lesson: \(id) not cached for offline use.")
                return nil
            }
            let subtitleAsset = AVURLAsset(url: URL(fileURLWithPath: textTrackPath))
            guard let existingTrack = subtitleAsset.tracks(withMediaType: .text).first else {
                Logger.error("No text track in local video asset named: \(name) fileName: \(fileName)")
                return nil
            }
            
            guard let subtitleTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .text,preferredTrackID: kCMPersistentTrackID_Invalid) else {
                Logger.error("Could not create text track in new video named: \(name) fileName: \(fileName)")
                return nil
            }
            
            subtitleTrack.languageCode = textTrack.language
            subtitleTrack.extendedLanguageTag = textTrack.language
            try subtitleTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero,of: existingTrack,at: CMTime.zero)
            
            if subtitleTrack.hasMediaCharacteristic(AVMediaCharacteristic.legible) {
                print("New \(textTrack.language) is legible")
            }
        }
        return videoPlusSubtitles
    } catch {
        Logger.error("Could not write text track for video lesson: \(name),error: \(error)")
    }
    return nil
}

func playVideo(_ video: AVAsset) {
    let assetKeys = [
        "playable"
    ]
    
    let playerItem = AVPlayerItem(asset: video,automaticallyLoadedAssetKeys: assetKeys)
    let videoPlayer = AVPlayer(playerItem: playerItem)
    videoPlayer.allowsExternalPlayback = true
    
    let avPVC = AVPlayerViewController()
    avPVC.player = videoPlayer
    avPVC.showsPlaybackControls = true
    self.present(avPVC,animated: true) {
        self.playerController = avPVC
        videoPlayer.play()
    }
}

视频、音频和文本轨道始终正确创建,文本轨道始终具有 mediaCharacteristiclegible,视频始终具有西班牙语和英语轨道。但奇怪的是完成的 AVMutableComposition 没有 mediaCharacteristics

a) videoPlusSubtitles.availableMediaCharacteristicsWithMediaSelectionOptions 总是返回 nil,

b) videoPlusSubtitles.hasMediaCharacteristic(.legible) 总是返回 nil。

那么,如果 AVPlayerViewController 可以看到英语字幕轨道,为什么不显示英语和西班牙语轨道的字幕控件?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...