如何解决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()
}
}
视频、音频和文本轨道始终正确创建,文本轨道始终具有 mediaCharacteristic
的 legible
,视频始终具有西班牙语和英语轨道。但奇怪的是完成的 AVMutableComposition
没有 mediacharacteristics
。
a) videoPlusSubtitles.availableMediacharacteristicsWithMediaSelectionoptions
总是返回 nil,
b) videoPlusSubtitles.hasMediaCharacteristic(.legible)
总是返回 nil。
那么,如果 AVPlayerViewController
可以看到英语字幕轨道,为什么不显示英语和西班牙语轨道的字幕控件?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。