I have an array of [AVAsset], and I am trying to combine all of those Assets into a single Asset so that I can play back the video seamlessly (I tried using an AVQueuePlayer, but that does not play back the assets seamlessly).
Below is what I have so far, but when I try to play the final composition, it only plays the first track, even though it shows that it has all tracks and the total duration equals all of the tracks together.
Am I missing a step, even though it appears that all the tracks are in the composition? Perhaps I need to handle the AVPlayer differently if the AVPlayerItem has multiple tracks?
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
, and set opacity of track to 0 (on track end) in layerInstruction of that track. – Rhaetian