AVMutableComposition-仅播放第一首曲目(快速) [英] AVMutableComposition - Only Playing First Track (Swift)

查看:124
本文介绍了AVMutableComposition-仅播放第一首曲目(快速)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个[AVAsset]数组,我试图将所有这些资产合并到一个资产中,以便可以无缝地播放视频(我尝试使用AVQueuePlayer,但是不能播放资产无缝地).

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.

即使看起来所有曲目都在构图中,我也错过了一步吗?如果AVPlayerItem具有多个轨道,也许我需要以不同的方式处理AVPlayer?

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

推荐答案

我能够找出最重要的问题的答案.为了一起播放所有剪辑,它们需要在同一轨道上.为此,请将以下行移至for循环之前(

I was able to figure out an answer the most important question. In order to play all of the clips together, they need to be in the same track. To do this, move the following line outside (before) the for loop:

let videoCompositionTrack = videoComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

这是完整的,更正的代码:

Here is the full, corrected code:

let playerLayer: AVPlayerLayer = AVPlayerLayer()
lazy var videoPlayer: AVPlayer = AVPlayer()

var videoClips = [AVAsset]()

let videoComposition = AVMutableComposition()
var playerItem: AVPlayerItem!
var lastTime: CMTime = kCMTimeZero

let videoCompositionTrack = videoComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

for clipIndex in videoClips {

    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()  // Does play all clips sequentially

我之前提到过,我仍然想知道如何在一项资产中播放多个曲目.我现在明白了,这不是它的工作原理.很好的资源:

https://developer.apple. com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html

这篇关于AVMutableComposition-仅播放第一首曲目(快速)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆