Video : insérer une image dans une vidéo
Fred20
Membre
Bonjour à tous
Je cherche par le biais d'AVAsset d'insérer une image dans une séquence vidéo. J'ai bien trouvé quelque chose sur le net mais ... qui ne fonctionne pas : l'image n'est pas insérée. Pourtant tout m'a l'air correcte, sachant que la vidéo et l'image ne sont pas nul après déboggage ... mais mon niveau sous objectiveC n'est pas extraordinaire !!
Si quelqu'un peut me dire ce qui cloche, voici le code
Merci d'avance
-(IBAction)addImage:(id)sender
{
//create the AVURLAsset first:
NSURL *monUrl = [NSURL URLWithString:@file:////Developer/xCode%20Divers/xCode4/EssaiVideoAV/Sequence3.mov];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:monUrl options:nil];
AVMutableComposition* mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:clipVideoTrack
atTime:kCMTimeZero error:nil];
[compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]];
//create the layer with the watermark image:
NSImage *myImage = [[NSImage alloc]initByReferencingFile:@file:////Developer/xCode%20Divers/xCode4/EssaiVideoAV/Punk.jpg];
myImage.size = NSMakeSize(20, 20);
CALayer *aLayer = [CALayer layer];
aLayer.contents = (id)myImage;
aLayer.frame = CGRectMake(5, 25, 57, 57); //Needed for proper display. We are using the app icon (57x57). If you use 0,0 you will not see it
aLayer.opacity = 0.65; //Feel free to alter the alpha here
CGSize videoSize = [clipVideoTrack naturalSize];
//want text instead:
CATextLayer *titleLayer = [CATextLayer layer];
titleLayer.string = @Text goes here;
titleLayer.font = @Helvetica;
titleLayer.fontSize = videoSize.height / 6;
//?? titleLayer.shadowOpacity = 0.5;
titleLayer.alignmentMode = kCAAlignmentCenter;
titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height / 6); //You may need to adjust this for proper display
// sorts the layer in proper order:
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:aLayer];
[parentLayer addSublayer:titleLayer]; //ONLY IF WE ADDED TEXT
//creating the composition and add the instructions to insert the layer:
AVMutableVideoComposition* videoComp = [[AVMutableVideoComposition videoComposition] retain];
videoComp.renderSize = videoSize;
videoComp.frameDuration = CMTimeMake(1, 30);
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
/// instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]);
AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
videoComp.instructions = [NSArray arrayWithObject: instruction];
//export
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
NSString *tempPath = [docPaths objectAtIndex:0];
NSLog(@Temp Path: %@",tempPath);
NSString *fileName = [NSString stringWithFormat:@%@/output-anot.MOV",tempPath];
NSFileManager *fileManager = [NSFileManager defaultManager] ;
if([fileManager fileExistsAtPath:fileName ]){
//NSError *ferror = nil ;
//BOOL success = [fileManager removeItemAtPath:fileName error:&ferror];
}
NSURL *exportURL = [NSURL fileURLWithPath:fileName];
AVAssetExportSession *assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality];//AVAssetExportPresetPassthrough
assetExport.videoComposition = videoComp;
assetExport.outputFileType = AVFileTypeQuickTimeMovie;
assetExport.outputURL = exportURL;
assetExport.shouldOptimizeForNetworkUse = YES;
[assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
[assetExport release];
//YOUR FINALIZATION CODE HERE
}
];
[videoAsset release];
}
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Tu dis que ça ne fonctionne pas... c'est vague. As-tu une vidéo en sortie ?
Bonjour Céroce
Oui j'ai une vidéo en sortie mais uniquement de la vidéo importée sans l'incrustation
Parce que si ce n'est pas le cas, ça met juste le contents des CALayer à nil, ce qui est permis, et tu n'auras pas de plantage.
Alors le NSImage n'est pas à nil (je n'ai pas vu comment le débogguer affiche l'image) et la CALAyer n'est pas à nil non plus
Cliques droit sur l'objet l'UIImage dans la colonne gauche de ton debugger, puis t'as une popup ou tu peux dire que tu veux voir l'image.
OK merci pour l'info...bien pratique
Donc en effet, l'image n'était pas chargée : rien au preview et du coup j'ai voulu l'afficher directement dans mon appli et rien non plus. Comprends pas puisque la NSImage n'est pas nul. Bref donc j'ai procédé autrement en incorporant l'image directement dans mon appli et j'ai utilisé NSImage *myImage = [NSImage imageNamed:@Punk.jpg];
J'aimerais savoir, cherches-tu à faire de l'image subliminal ou souhaites-tu donner de l'information au spectateur ?
Le chemin de ton fichier a la forme d'une URL, c'est le problème. ça devrait plutôt être du genre "Developer/xCode Divers/xCode4/EssaiVideoAV/Punk.jpg".
En réponse à tablier, je cherche surtout à essayer de maitriser tant bien que mal AVFoundation !!!
Et merci à Céroce pour ton aide