AVVideoCompositionCoreAnimationTool при экспорте отправляет только изображение и аудио, но не видео - PullRequest
1 голос
/ 09 августа 2011

Мне трудно определить, почему я получаю только изображение и аудио, но не видео при экспорте.Любая помощь приветствуется.Как видите, я также пытался использовать videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer, но при экспорте получал ошибку.У меня нет никакого предпочтения, какой метод я использую (videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer или videoCompositionCoreAnimationToolWithAdditionalLayer), мне просто нужно, чтобы он работал.ЛОЛ.Заранее всем спасибо за помощь.

#import "ThirdView.h"


@implementation ThirdView




- (void)viewDidLoad {
imagePicker = [[UIImagePickerController alloc] init];
[super viewDidLoad];
}

- (NSString *) filePath: (NSString *) fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
                                                     NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:fileName];
}



- (IBAction) btnClicked: (id) sender{
imagePicker.delegate = self;    

imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

NSArray *mediaTypes = 
[NSArray arrayWithObjects: (NSString *) kUTTypeMovie, nil];
imagePicker.mediaTypes = mediaTypes;



//---show the Image Picker--    
[self presentModalViewController: imagePicker animated: YES] ;


}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

/// incoming video
NSURL *videoURL = [info valueForKey:UIImagePickerControllerMediaURL];

/// UIImage into CALayer
CALayer *aLayer = [CALayer layer];
aLayer.contents = (id) [UIImage imageNamed:@"test.png"].CGImage;
aLayer.frame = CGRectMake(0, 0, 480, 320);    

/* only use with videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, 480, 320);
videoLayer.frame = CGRectMake(0, 0, 480, 320);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:aLayer];
 */



AVURLAsset* url = [AVURLAsset URLAssetWithURL:videoURL options:nil];
AVMutableComposition *videoComposition = [AVMutableComposition composition];
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];

AVMutableCompositionTrack *compositionVideoTrack = [videoComposition  addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

AVMutableCompositionTrack *compositionAudioTrack = [videoComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];


AVAssetTrack *clipVideoTrack = [[url tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [url duration])  ofTrack:clipVideoTrack atTime:kCMTimeZero error:&error];

AVAssetTrack *clipAudioTrack = [[url tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [url duration])  ofTrack:clipAudioTrack atTime:kCMTimeZero error:&error];        

AVMutableVideoComposition* videoComp = [[AVMutableVideoComposition videoComposition] retain] ;

videoComp.renderSize = CGSizeMake(480, 320);
videoComp.frameDuration = CMTimeMake(1, 30);
//videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:aLayer inLayer:parentLayer];

videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithAdditionalLayer:aLayer asTrackID:2];




/// instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30) );
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
[layerInstruction setTrackID:2];
[layerInstruction setOpacity:1.0 atTime:kCMTimeZero ];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
videoComp.instructions = [NSArray arrayWithObject: instruction];



/// outputs
NSString *filePath = nil;
filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
filePath = [filePath stringByAppendingPathComponent:@"temp.mov"]; 
NSLog(@"exporting to: %@", filePath);
if ([fileManager fileExistsAtPath:filePath]) 
{
    BOOL success = [fileManager removeItemAtPath:filePath error:&error];
    if (!success) NSLog(@"FM error: %@", [error localizedDescription]);
}

/// exporting
AVAssetExportSession *exporter;
exporter = [[AVAssetExportSession alloc] initWithAsset:videoComposition presetName:AVAssetExportPresetHighestQuality] ;
exporter.videoComposition = videoComp;
exporter.outputURL=[NSURL fileURLWithPath:filePath];
exporter.outputFileType=AVFileTypeQuickTimeMovie;





[statusLabel setText:@"processing..."];

[exporter exportAsynchronouslyWithCompletionHandler:^(void){
    switch (exporter.status) {
        case AVAssetExportSessionStatusFailed:
            NSLog(@"exporting failed");
            break;
        case AVAssetExportSessionStatusCompleted:
            NSLog(@"exporting completed");
            UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, @selector  (video:didFinishSavingWithError:contextInfo:), NULL);
            break;
        case AVAssetExportSessionStatusCancelled:
            NSLog(@"export cancelled");
            break;
    }



}];



//---hide the Image Picker---

[picker dismissModalViewControllerAnimated:YES];

[exporter autorelease];

}


- (void) video:(NSString *)videoPath
didFinishSavingWithError: (NSError *) error
contextInfo: (void *) contextInfo {
NSLog(@"Finished saving video with error: %@", error);
}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
//---user did not select image/video; hide the Image Picker---
[picker dismissModalViewControllerAnimated:YES];
}

- (void)dealloc {

[imagePicker release];
[super dealloc];
}

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


@end

Ответы [ 2 ]

3 голосов
/ 10 декабря 2012

вы также должны предоставить экспортеру аудио композицию, установив
exporter.audioMix;

0 голосов
/ 04 февраля 2019

Проблема с этим кодом заключается в том, что изображение и видео имеют одинаковый размер, т.е. 480x320.Следовательно, вы можете увидеть видео или изображение.В прокомментированном коде aLayer добавляется после videoLayer, поэтому видео не видно, а картинка есть.Если вы решили это по-другому и помните, пожалуйста, поделитесь тем же.Спасибо.

...