我已经参考
AVMutableComposition – Only Playing First Track (Swift)
但它并没有提供我正在寻找的答案.
我有一个AVMutableComposition().我试图在单个组合中应用单个类型的AVMediaTypeVideo的MULTIPLE AVCompositionTrack.这是因为我使用两个不同的AVMediaTypeVideo源,它们具有不同的CGSize和它们来自的AVAsset的preferredTransform.
因此,应用其指定的preferredTransform的唯一方法是将它们提供在两个不同的轨道中.但是,无论什么原因,只有第一个轨道实际上会提供任何视频,就好像第二个轨道从来没有.
所以,我试过
1)使用AVMutableVideoCompositionLayerInstruction并应用AVVideoComposition以及AVAssetExportSession,这可以正常工作,但我仍然在进行转换,但是是可以做的.但视频的处理时间是1分钟,这在我的情况下是不适用的.
2)使用多个轨道,不使用AVAssetExportSession,而不会出现相同类型的第二个轨道.现在,我可以把它全部放在1个轨道上,但是所有的视频都将与第一个视频相同,因此它将不会像第一个视频一样延伸.
所以我的问题是,是否可能
1)在不使用AVAssetExportSession的情况下将指令应用于轨道? //首选方式BY FAR.
2)减少出口时间? (我已经尝试使用PresetPassthrough,但是如果您有一个exporter.videoComposition,我的指示是我不能使用的,这是唯一的地方,我知道我可以放置说明,不知道我是否可以将它们放在别的地方.
这里是我的一些代码(没有出口商,因为我不需要导出任何地方,只是在AVMutableComposition组合项目后做的事情.
func merge() { if let firstAsset = controller.firstAsset,secondAsset = self.asset { let mixComposition = AVMutableComposition() let firstTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo,preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) do { //Don't need now according to not being able to edit first 14seconds. if(CMTimeGetSeconds(startTime) == 0) { self.startTime = CMTime(seconds: 1/600,preferredTimescale: Int32(600)) } try firstTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero,CMTime(seconds: CMTimeGetSeconds(startTime),preferredTimescale: 600)),ofTrack: firstAsset.tracksWithMediaType(AVMediaTypeVideo)[0],atTime: kCMTimeZero) } catch _ { print("Failed to load first track") } //This secondTrack never appears,doesn't matter what is inside of here,like it is blank space in the video from startTime to endTime (rangeTime of secondTrack) let secondTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo,preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) // secondTrack.preferredTransform = self.asset.preferredTransform do { try secondTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero,secondAsset.duration),ofTrack: secondAsset.tracksWithMediaType(AVMediaTypeVideo)[0],atTime: CMTime(seconds: CMTimeGetSeconds(startTime),preferredTimescale: 600)) } catch _ { print("Failed to load second track") } //This part appears again,at endTime which is right after the 2nd track is suppose to end. do { try firstTrack.insertTimeRange(CMTimeRangeMake(CMTime(seconds: CMTimeGetSeconds(endTime),preferredTimescale: 600),firstAsset.duration-endTime),atTime: CMTime(seconds: CMTimeGetSeconds(endTime),preferredTimescale: 600)) } catch _ { print("Failed") } if let loadedAudioAsset = controller.audioAsset { let audioTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio,preferredTrackID: 0) do { try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero,firstAsset.duration),ofTrack: loadedAudioAsset.tracksWithMediaType(AVMediaTypeAudio)[0],atTime: kCMTimeZero) } catch _ { print("Failed to load Audio track") } } } }
编辑
Apple表示“表示通过实现AVVideoCompositionInstruction协议的类的实例的NSArray进行视频合成的指令.
对于阵列中的第一条指令,timeRange.start必须小于或等于将尝试播放或其他处理的最早时间
(注意,这通常是kCMTimeZero).对于后续指令,timeRange.start必须等于先前指令的结束时间.结束时间
最后的指令必须大于或等于播放或其他处理尝试的最新时间(请注意,这通常是这样
与AVVideoComposition实例相关联的资产的持续时间).
这只是指出,如果您决定使用任何指令(这是我正在理解的),整个构图必须在指令中分层.为什么是这样?在这个例子中,如何应用指令来说明轨道2,而不应用改变轨迹1或3:
轨道1从0 – 10秒,轨道2从10 – 20秒,轨道3从20 – 30秒.
任何解释可能会回答我的问题(如果它是可行的).
这是一个过程的概述 – 我已经在Objective-C中完成了这个任务,所以我不能给你准确的swift代码,但是我知道这些相同的功能在Swift中是一样的.
>创建AVMutableComposition.
>创建AVMutableVideoComposition.
>设置视频构图的渲染大小和帧持续时间.
>现在对于每个AVAsset:
>创建AVAssetTrack和AVAudioTrack.
>为每一个创建一个AVMutableCompositionTrack(一个用于视频,一个用于音频),将每个添加到mutableComposition.
在这里它变得更复杂..(对不起AVFoundation不容易!)
>从引用每个视频的AVAssetTrack创建AVMutableCompositionLayerInstruction.对于每个AVMutableCompositionLayerInstruction,可以对其进行转换.你也可以做一些设置裁剪矩形的东西.
>将每个AVMutableCompositionLayerInstruction添加到一个图层指示数组.当创建所有AVMutableCompositionLayerInstructions时,数组将在AVMutableVideoComposition上设置.
最后..
>最后,您将有一个AVPlayerItem,您将用它来播放(在AVPlayer上).您使用AVMutableComposition创建AVPlayerItem,然后在AVPlayerItem本身(setVideoComposition ..)上设置AVMutableVideoComposition.
容易呃
花了我几个星期才能使这些东西工作得很好.它完全不原谅,正如你所提到的,如果你做错了,它不告诉你你做错了什么 – 它只是没有出现.
但是,当你破解它,它的工作速度很快.
最后,我已经概述的所有东西都可以在AVFoundation文档中找到.它是一个漫长的tome,但你需要知道它来实现你想要做的事情.
祝你好运!