AVMutableComposition - 连接的视频资产在第一个资产后停止
AVMutableComposition - concatenated video assets stops after first asset
我正在使用以下代码连接多个 AVURLAssets
:
AVMutableComposition * movie = [AVMutableComposition composition];
CMTime offset = kCMTimeZero;
for (AVURLAsset * asset in assets) {
AVMutableCompositionTrack *compositionVideoTrack = [movie addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [movie addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
AVAssetTrack *assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
NSError * error = nil;
if (![compositionVideoTrack insertTimeRange: timeRange ofTrack: assetVideoTrack atTime: offset error: &error]) {
NSLog(@"Error adding video track - %@", error);
}
if (![compositionAudioTrack insertTimeRange: timeRange ofTrack: assetAudioTrack atTime: offset error: &error]) {
NSLog(@"Error adding audio track - %@", error);
}
offset = CMTimeAdd(offset, asset.duration);
}
生成的合成一直播放到所有原始资产的组合持续时间,音频播放正确,但只有第一个资产的视频播放,然后在其最后一帧暂停。
对我做错了什么有什么想法吗?
原始资产的顺序无关紧要 - 第一个视频和所有音频播放。
您需要使用 AVVideoCompositionInstructions 的实例创建一个 AVVideoComposition。看看这个 sample code.
您可能感兴趣的代码具有以下性质:
AVMutableVideoCompositionLayerInstruction *videoCompositionLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:mutableVideoTrack];
[self.layerInstructions addObject:videoCompositionLayerInstruction];
AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
passThroughInstruction.timeRange = trackTimeRange;
passThroughInstruction.layerInstructions = @[videoCompositionLayerInstruction];
[self.compositionInstructions addObject:passThroughInstruction];
好吧,那是我的错误。我会把 addMutableTrackWithMediaType:
放在 里面 for
循环。傻我。固定如下,效果很好!
我会把它留在这里以防其他人遇到同样的问题。
AVMutableComposition * movie = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [movie addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [movie addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime offset = kCMTimeZero;
for (AVURLAsset * asset in assets) {
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
AVAssetTrack *assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
NSError * error = nil;
if (![compositionVideoTrack insertTimeRange: timeRange ofTrack: assetVideoTrack atTime: offset error: &error]) {
NSLog(@"Error adding video track - %@", error);
}
if (![compositionAudioTrack insertTimeRange: timeRange ofTrack: assetAudioTrack atTime: offset error: &error]) {
NSLog(@"Error adding audio track - %@", error);
}
offset = CMTimeAdd(offset, asset.duration);
}
我正在使用以下代码连接多个 AVURLAssets
:
AVMutableComposition * movie = [AVMutableComposition composition];
CMTime offset = kCMTimeZero;
for (AVURLAsset * asset in assets) {
AVMutableCompositionTrack *compositionVideoTrack = [movie addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [movie addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
AVAssetTrack *assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
NSError * error = nil;
if (![compositionVideoTrack insertTimeRange: timeRange ofTrack: assetVideoTrack atTime: offset error: &error]) {
NSLog(@"Error adding video track - %@", error);
}
if (![compositionAudioTrack insertTimeRange: timeRange ofTrack: assetAudioTrack atTime: offset error: &error]) {
NSLog(@"Error adding audio track - %@", error);
}
offset = CMTimeAdd(offset, asset.duration);
}
生成的合成一直播放到所有原始资产的组合持续时间,音频播放正确,但只有第一个资产的视频播放,然后在其最后一帧暂停。
对我做错了什么有什么想法吗?
原始资产的顺序无关紧要 - 第一个视频和所有音频播放。
您需要使用 AVVideoCompositionInstructions 的实例创建一个 AVVideoComposition。看看这个 sample code.
您可能感兴趣的代码具有以下性质:
AVMutableVideoCompositionLayerInstruction *videoCompositionLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:mutableVideoTrack];
[self.layerInstructions addObject:videoCompositionLayerInstruction];
AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
passThroughInstruction.timeRange = trackTimeRange;
passThroughInstruction.layerInstructions = @[videoCompositionLayerInstruction];
[self.compositionInstructions addObject:passThroughInstruction];
好吧,那是我的错误。我会把 addMutableTrackWithMediaType:
放在 里面 for
循环。傻我。固定如下,效果很好!
我会把它留在这里以防其他人遇到同样的问题。
AVMutableComposition * movie = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [movie addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [movie addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime offset = kCMTimeZero;
for (AVURLAsset * asset in assets) {
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
AVAssetTrack *assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
NSError * error = nil;
if (![compositionVideoTrack insertTimeRange: timeRange ofTrack: assetVideoTrack atTime: offset error: &error]) {
NSLog(@"Error adding video track - %@", error);
}
if (![compositionAudioTrack insertTimeRange: timeRange ofTrack: assetAudioTrack atTime: offset error: &error]) {
NSLog(@"Error adding audio track - %@", error);
}
offset = CMTimeAdd(offset, asset.duration);
}