私のアプリでは、ビデオ クリップを動的にマージしようとしています。前の録音を保持し、次に次の録音を最後に追加する 2 つのプロパティがあります。これは基本的に一時停止機能として機能し、ユーザーはその場で再生できます。
docs ディレクトリの「video.mp4」に最初のクリップを書き込むようにします。これが前回の記録として設定されます。次に、次のクリップを「video2.mp4」に書き込み、次のレコーディングに設定し、AVMutableComposition を使用してそれらをマージします。
AVMutableComposition *mashVideosTogether = [AVMutableComposition composition];
NSError *error;
if([mashVideosTogether insertTimeRange:
CMTimeRangeMake(kCMTimeZero, [self.previousRecording duration])
ofAsset:self.previousRecording
atTime:kCMTimeZero
error:&error]) NSLog(@"Successfully added one");
else NSLog(@"error: %@", error.description);
if([mashVideosTogether insertTimeRange:
CMTimeRangeMake(kCMTimeZero, [self.nextRecording duration])
ofAsset:self.nextRecording
atTime:CMTimeAdd(kCMTimeZero, [self.previousRecording duration])
error:&error]) NSLog(@"Success on 2");
else NSLog(@"error: %@", error.description);
これにより、1 番目と 2 番目のビデオが追加されます。次に、ビデオを「combined.mp4」にエクスポートします。これが正常に終了したら、「video.mp4」のファイルを削除し、結合されたビデオを「video.mp4」にエクスポートします (したがって、この時点で結合されたビデオが存在します)。 2か所にあります)。これは私のプレーヤーでうまくいきます。ユーザーがもう一度録画をクリックすると、「video.mp4」に新しく結合されたビデオが前の録画として設定され、新しく録画されたクリップが次の録画として設定され、プロセス全体が繰り返されます。それらは追加されてエクスポートされ、プロセスが繰り返されます。
ただし、3 つ目 (またはそれ以上) のクリップを追加すると、作成されたコンポジションの最初のクリップが再生時に黒くなります。それらの継続時間は引き続き保持されますが、ビデオやサウンドはありません。基本的に、古いコンポジションから新しいコンポジションを作成するときはいつでも、最初のコンポジションは空白で表示され、保存されるのはそれらの長さと新しいレコーディングだけです。このデータは、構成を別の構成にすると失われますか? それらをトラックとして手動で追加する必要がありますか? どんな助けでも大歓迎です!
解決した
Apple の AVEditDemo を読んだところ、元の仮定が正しかったようです。AVMutableComposition のみを使用してビデオを一緒に追加していたとき (AKA 個々のトラック ファイルを作成してマージしていない)、これらのトラックのデータは別のトラックに追加されたときに失われました。構成。
そのため、すべてのクリップのオーディオとビデオ用に個別のトラックを作成してそれらをマージし、ビデオを動的に撮影し、停止してから再び撮影を開始すると、その場で連結される作業セットアップができました。
if(self.previousRecording && self.nextRecording) {
NSArray *assetArray = [NSArray arrayWithObjects:
self.previousRecording, self.nextRecording, nil];
NSURL *fileURL = [self getURLWithPathComponent:@"combined.mp4"];
AVMutableComposition *mashVideosTogether = [AVMutableComposition composition];
NSError *error;
CMTime nextClipStartTime = kCMTimeZero;
AVMutableCompositionTrack *compositionVideoTrack =
[mashVideosTogether addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack =
[mashVideosTogether addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
for(int i=0; i<[assetArray count]; i++) {
AVURLAsset *asset = [assetArray objectAtIndex:i];
CMTimeRange timeRangeInAsset = CMTimeRangeMake(kCMTimeZero, [asset duration]);
AVAssetTrack *clipVideoTrack =
[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:timeRangeInAsset
ofTrack:clipVideoTrack atTime:nextClipStartTime error:nil];
AVAssetTrack *clipAudioTrack =
[[asset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0];
[compositionAudioTrack insertTimeRange:timeRangeInAsset
ofTrack:clipAudioTrack atTime:nextClipStartTime error:nil];
nextClipStartTime = CMTimeAdd(nextClipStartTime, timeRangeInAsset.duration);
}
//do exports down here and then reset previous recording, etc.
}