2013-10-24 16 views
1

上午使用AVCaptureSession捕獲視頻並將其保存到相機,一切工作正常,但問題如何導出它上面寫有文字,甚至導出時放置圖像?謝謝AVCaptureSession導出文本

+0

視頻是從WWDC10 「會話407 - 編輯媒體與AV」 –

回答

2

看看AVMutableVideoCompositionLayerInstruction你基本上需要添加圖層指令到你的視頻,我不記得鏈接,但有一個蘋果WWDC視頻。

0

我已經管理了一個方法來在視頻上寫一個圖像和一個包電影導出的catextlayer,一切都很好,但現在我怎麼能寫一個文本到特定的幀? (時間)

這是我的代碼工作,

- (IBAction)btn1:(id)sender { 

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"movie"  ofType:@"mov"]; 



    //NSURL * urlpath = [NSURL URLWithString:filePath]; 
    NSLog(@"%@",filePath); 
    AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:[NSURL  fileURLWithPath:filePath] 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]]; 








    AVMutableCompositionTrack *audioTrack1 = [mixComposition  addMutableTrackWithMediaType:AVMediaTypeAudio 
                     preferre dTrackID :kCMPers istentTr ackID_In valid]; 

    [audioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration ) 
         ofTrack:[[videoAsset  tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] 
          atTime:kCMTimeZero 
          error:nil]; 



    CGSize videoSize = [clipVideoTrack naturalSize]; 

    UIImage *myImage = [UIImage imageNamed:@"[email protected]"]; 
    CALayer *aLayer = [CALayer layer]; 
    aLayer.contents = (id)myImage.CGImage; 
    aLayer.frame = CGRectMake(videoSize.width - 65, videoSize.height - 75, 57, 57 ); 
    aLayer.opacity = 0.65; 
    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]; 

    CATextLayer *titleLayer = [CATextLayer layer]; 
    titleLayer.string = @"Text goes here"; 
    titleLayer.font = (__bridge CFTypeRef)(@"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 
    [parentLayer addSublayer:titleLayer]; 

    AVMutableVideoComposition* videoComp = [AVMutableVideoComposition  videoComposition]; 
    videoComp.renderSize = videoSize; 
    videoComp.frameDuration = CMTimeMake(1, 30); 
    videoComp.animationTool = [AVVideoCompositionCoreAnimationTool  videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer  inLayer:parentLayer]; 

    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]; 

    AVAssetExportSession *assetExport = [[AVAssetExportSession alloc]  initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality] ;//AVAssetExportPresetPassthrough 
    assetExport.videoComposition = videoComp; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString* VideoName = [NSString stringWithFormat:@"%@/mynewwatermarkedvideo. mp4",documentsDirectory]; 


    //NSString *exportPath = [NSTemporaryDirectory()  stringByAppendingPathComponent:VideoName]; 
    NSURL *exportUrl = [NSURL fileURLWithPath:VideoName]; 

    if ([[NSFileManager defaultManager] fileExistsAtPath:VideoName]) 
    { 
     [[NSFileManager defaultManager] removeItemAtPath:VideoName error:nil]; 
    } 

    assetExport.outputFileType = AVFileTypeQuickTimeMovie; 
    assetExport.outputURL = exportUrl; 
    assetExport.shouldOptimizeForNetworkUse = YES; 

    //[strRecordedFilename setString: exportPath]; 

    [assetExport exportAsynchronouslyWithCompletionHandler: 
    ^(void) { 
     //[assetExport release]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self exportDidFinish:assetExport]; 
     }); 
    } 
    ]; 


} 

-(void)exportDidFinish:(AVAssetExportSession*)session 
{ 
    NSURL *exportUrl = session.outputURL; 
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
    NSLog(@"%@",exportUrl); 
    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:exportUrl]) 
    { 
     [library writeVideoAtPathToSavedPhotosAlbum:exportUrl completionBlock:^( NSURL *assetURL, NSError *error) 
     { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       if (error) { 
        UIAlertView *alert = [[UIAlertView alloc]  initWithTitle:@"Error" message:@"Video Saving Failed" 
                    delegate:nil  cancelButtonT itle:@"OK" ot herButtonTitl es:nil]; 
        [alert show]; 
       } else { 
        UIAlertView *alert = [[UIAlertView alloc]  initWithTitle:@"Video Saved" message:@"Saved To Photo Album" 
                    delegate:self  cancelButton Title:@"OK" o therButtonTit les:nil]; 
        [alert show]; 
       } 
      }); 
     }]; 

    } 
    NSLog(@"Completed"); 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"AlertView"  message:@"Video is edited successfully." delegate:self  cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [alert show]; 

}