我有一个 [AVAsset] 数组,我想将这些 Asset 合并成一个单独的 Asset,以便我可以无缝地播放视频(我尝试使用 AVQueuePlayer,但是它不能无缝地播放 assets)。
下面是我目前的代码,但当我尝试播放最终合成时,它只播放第一条轨道,即使它显示已经拥有所有轨道,总持续时间等于所有轨道的持续时间之和。
我是否缺少一步操作,即使看起来所有轨道都在合成中?也许如果 AVPlayerItem 有多个轨道,我需要以不同的方式处理 AVPlayer?
下面是我目前的代码,但当我尝试播放最终合成时,它只播放第一条轨道,即使它显示已经拥有所有轨道,总持续时间等于所有轨道的持续时间之和。
我是否缺少一步操作,即使看起来所有轨道都在合成中?也许如果 AVPlayerItem 有多个轨道,我需要以不同的方式处理 AVPlayer?
let playerLayer: AVPlayerLayer = AVPlayerLayer()
lazy var videoPlayer: AVPlayer = AVPlayer()
var videoClips = [AVAsset]()
let videoComposition = AVMutableComposition()
var playerItem: AVPlayerItem!
var lastTime: CMTime = kCMTimeZero
for clipIndex in videoClips {
let videoCompositionTrack = videoComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
do {
try videoCompositionTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, clipIndex.duration),
ofTrack: clipIndex.tracksWithMediaType(AVMediaTypeVideo)[0] ,
atTime: lastTime)
lastTime = CMTimeAdd(lastTime, clipIndex.duration)
} catch {
print("Failed to insert track")
}
}
print("VideoComposition Tracks: \(videoComposition.tracks.count)") // Shows multiple tracks
playerItem = AVPlayerItem(asset: videoComposition)
print("PlayerItem Duration: \(playerItem.duration.seconds)") // Shows the duration of all tracks together
print("PlayerItem Tracks: \(playerItem.tracks.count)") // Shows same number of tracks as the VideoComposition Track count
videoPlayer = AVPlayer(playerItem: playerItem)
playerLayer.player = videoPlayer
videoPlayer.volume = 0.0
videoPlayer.play() // Only plays the first track
AVMutableVideoComposition
并在该轨道的layerInstruction
中将轨道的不透明度设置为0(在轨道结束时),则可以播放多个轨道。 - Tiko