2

我的代码如下:

//init mix composition
let mixComposition = AVMutableComposition()

//video asset
let videoAsset = AVURLAsset(url: VIDEO_URL)
let videoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
try? videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoAsset.tracks(withMediaType: AVMediaTypeVideo).first!, at: kCMTimeZero)

//audio track
let audioTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
try? audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoAsset.tracks(withMediaType: AVMediaTypeAudio).first!, at: kCMTimeZero)

//subtitles
let path = Bundle.main.path(forResource: "subtitle", ofType: "vtt")!
let subtitleAsset = AVAsset(url: URL(fileURLWithPath: path))
let subtitleTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeText, preferredTrackID: kCMPersistentTrackID_Invalid)
try? subtitleTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: subtitleAsset.tracks(withMediaType: AVMediaTypeText)[0], at: kCMTimeZero)

 //setup player and play
 let item = AVPlayerItem(asset: videoAsset)
 let player = AVPlayer(playerItem: item)
 self.player = player
 self.player?.allowsExternalPlayback = true
 self.player?.usesExternalPlaybackWhileExternalScreenIsActive = true
 self.player?.play()

当被问及videoAsset.isCompatibleWithAirPlayVideo它是否返回 true 时。当您加载应用程序时,它一切正常,直到您进入 Airplay 模式,屏幕冻结,直到您再次退出 Airplay 模式。

如果您要将 mixComposition 更改为 videoAsset,这是完全不同的行为。现在一切正常,但你不会有外部字幕。

有没有其他人遇到过这个问题以及解决方法。我的最终目标是在 mp4 视频中包含外部字幕。

4

1 回答 1

0

我的应用程序中的代码几乎与您的相同,并且它在 Airplay 模式下工作,所以我认为您几乎就在那里。

我从网络服务器加载视频、音频和 vtt 字幕,遇到了两个主要挑战:

  1. 无论 plist 设置如何,除非它来自 https-host,否则音频无法播放(视频从 http-host 可以正常播放)
  2. 字幕只持续了 10-12 分钟的电影。解决方案是使用 FileManager 从 .documentDirectory 下载字幕和加载

与您的代码的唯一区别是我初始化了一个 AVPlayerViewController 并将播放器设置为 AVPlayer:

var moviePlayer = AVPlayerViewController()
moviePlayer.player = player

然后展示moviePlayer

self.view.window?.rootViewController?.present(self.moviePlayer, animated: true, completion : { self.moviePlayerFinishedLoading() } 
self.moviePlayer.player?.play()

希望这可以帮助

于 2017-05-18T10:51:32.187 回答