Comment combiner des clips vidéo avec une orientation différente à l'aide de AVFoundation
Je suis en train d'essayer de combiner plusieurs clips vidéo en un seul à l'aide de AVFoundation.
Je peux créer une seule vidéo à l'aide de AVMutableComposition à l'aide du code ci-dessous
AVMutableComposition *composition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime startTime = kCMTimeZero;
/*videoClipPaths is a array of paths of the video clips recorded*/
//for loop to combine clips into a single video
for (NSInteger i=0; i < [videoClipPaths count]; i++) {
NSString *path = (NSString*)[videoClipPaths objectAtIndex:i];
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
[url release];
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *audioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
//set the orientation
if(i == 0)
{
[compositionVideoTrack setPreferredTransform:videoTrack.preferredTransform];
}
ok = [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:videoTrack atTime:startTime error:nil];
ok = [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:audioTrack atTime:startTime error:nil];
startTime = CMTimeAdd(startTime, [asset duration]);
}
//export the combined video
NSString *combinedPath = /* path of the combined video*/;
NSURL *url = [[NSURL alloc] initFileURLWithPath: combinedPath];
AVAssetExportSession *exporter = [[[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPreset640x480] autorelease];
exporter.outputURL = url;
[url release];
exporter.outputFileType = [[exporter supportedFileTypes] objectAtIndex:0];
[exporter exportAsynchronouslyWithCompletionHandler:^(void){[self combineVideoFinished:exporter.outputURL status:exporter.status error:exporter.error];}];
Le code ci-dessus fonctionne très bien si tous les clips vidéo ont été enregistrées dans la même orientation (portrait ou paysage). Cependant, si j'ai un mélange des orientations dans les clips, la vidéo finale sera en partie tourné de 90 degrés vers la droite (ou la gauche).
Je me demandais est-il un moyen de transformer tous les clips de la même orientation (par exemple, l'orientation de la première vidéo) lors de la composition d'eux. De ce que j'ai lu à partir de XCode document AVMutableVideoCompositionLayerInstruction
semble peut être utilisé pour transformer AVAsset
, mais je ne suis pas sûr de savoir comment créer et appliquer plusieurs couche d'instruction de clips correspondants et de les utiliser ensuite dans la composition (AVMutableComposition*
)
Toute aide serait appréciée!
Vous devez vous connecter pour publier un commentaire.
C'est ce que je fais. J'utilise ensuite un AVAssetExportSession pour créer le fichier réel. mais je vous préviens, le CGAffineTransforms sont parfois effectués à la fin, vous verrez une ou deux de l'original avant que la vidéo se transforme. Je n'ai aucune idée de pourquoi cela se produit, une combinaison différente de vidéos donnera le résultat escompté, mais parfois de son.
C'est ce que je fais. J'utilise ensuite un AVAssetExportSession pour créer le fichier réel. mais je vous préviens, le CGAffineTransforms sont parfois effectués à la fin, vous verrez une ou deux de l'original avant que la vidéo se transforme. Je n'ai aucune idée de pourquoi cela se produit, une combinaison différente de vidéos donnera le résultat escompté, mais parfois de son.
[compositionVideoTrack setPreferredTransform:transform]
mais ça ne fonctionne pas. À l'aide de votre méthode ne fonctionne pas pour moi non plus. Mais à l'aide de deux n'a fonctionné. Sonne comme un cadre de bug. Je suis aussi à l'aide de l'exportation paramètre de sessionAVAssetExportPresetPassthrough
.Ici est @bogardon's réponse rapide 4+