2011-05-24 53 views

回答

2

終於成功整合選定的音樂文件轉換成視頻

使用AVAssetExportSession我們可以使用AVMutableComposition合併視頻和音頻在一起。

感謝您的更新!

//此方法合併音頻和視頻。

- (void)mergeAudioAtUrl:(NSURL *)audioUrl withVideoAtUrl:(NSURL *)videoUrl toUrl:(NSURL *)outputUrl 
    { 

//_imageCaptureCount = [_imagesArray count]*100; 

AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil]; 
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil]; 

AVMutableComposition* mixComposition = [AVMutableComposition composition]; 


if([[audioAsset tracksWithMediaType:AVMediaTypeAudio] count]) 
{ 
    AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio 
                         preferredTrackID:kCMPersistentTrackID_Invalid]; 

    [compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) 
             ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] 
             atTime:kCMTimeZero error:nil]; 
} 
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo 
                       preferredTrackID:kCMPersistentTrackID_Invalid]; 
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) 
           ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] 
           atTime:kCMTimeZero error:nil]; 

[audioAsset release]; 
[videoAsset release]; 

AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition 
                     presetName:AVAssetExportPresetPassthrough]; 

NSURL *exportUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/Documents/%@Video.mp4", NSHomeDirectory(),pcNameString]]; 

if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/Documents/%@Video.mp4", NSHomeDirectory(),pcNameString]]) 
{ 
    [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/Documents/%@Video.mp4", NSHomeDirectory(),pcNameString] error:nil]; 
} 

_assetExport.outputFileType = @"com.apple.quicktime-movie"; //com.apple.m4v-video 
_assetExport.outputURL = exportUrl; 
_assetExport.shouldOptimizeForNetworkUse = YES; 

[_assetExport exportAsynchronouslyWithCompletionHandler: 
^(void) {  
    // your completion code here 
    // NSLog(@"completed"); 

    removeProgresBarFlag = YES; 


    /* NSString* savedVideoFilePath = [NSString stringWithFormat:@"%@/Documents/PC%d.mp4", NSHomeDirectory(),[videosListArray count]]; 

    if(UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(savedVideoFilePath)) 
    { 
     [[UIApplication sharedApplication]beginIgnoringInteractionEvents]; 
     UISaveVideoAtPathToSavedPhotosAlbum(savedVideoFilePath, self, nil, nil); 
     [[UIApplication sharedApplication]endIgnoringInteractionEvents]; 

    } */ 


    NSMutableDictionary* videoDetailDict = [[NSMutableDictionary alloc] initWithCapacity:0]; 

    NSStringEncoding encoding; 
    NSError* error; 

    NSString * persistentID; 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 

    if([fileManager fileExistsAtPath:PRESENTSONGS_FILE_PATH]) 
     persistentID = [NSString stringWithContentsOfFile:PRESENTSONGS_FILE_PATH usedEncoding:&encoding error:&error]; 
    else 
     persistentID = @""; 

    [videoDetailDict setObject:persistentID forKey:KSong]; 

    if([fileManager fileExistsAtPath:PRESENTIMAGES_FILE]) 
    { 

     NSMutableArray* currentImagesArray = [[NSMutableArray alloc] initWithContentsOfFile:IMAGESDATA_FILE_PATH]; 
     NSMutableArray* durationArray = [[NSMutableArray alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/videoduration.plist", [[NSBundle mainBundle] resourcePath]]]; 
     [videoDetailDict setObject:[durationArray objectAtIndex:[currentImagesArray count]-1] forKey:KfileSize]; 
     [durationArray release]; 


     [videoDetailDict setObject:currentImagesArray forKey:KImagesList]; 
     if([fileManager fileExistsAtPath:TEMPVIDEO_FILE_PATH]) 
     [fileManager removeItemAtPath:TEMPVIDEO_FILE_PATH error:nil]; 

     NSString* mainPath; 

      mainPath = [NSString stringWithFormat:@"%@/Documents/%@File",NSHomeDirectory(),pcNameString]; 

     if([fileManager fileExistsAtPath:mainPath]) 
      [fileManager removeItemAtPath:mainPath error:nil]; 

     [fileManager createDirectoryAtPath:mainPath withIntermediateDirectories:NO attributes:nil error:nil]; 


     for(int i=0;i<[currentImagesArray count];i++) 
     { 
      [fileManager copyItemAtPath:[NSString stringWithFormat:@"%@%@",PRESENTIMAGES_FILE,[currentImagesArray objectAtIndex:i]] toPath:[NSString stringWithFormat:@"%@/%@",mainPath,[currentImagesArray objectAtIndex:i]] error:nil]; 
     } 
     [currentImagesArray release]; 

    } 

    if([fileManager fileExistsAtPath:KMESSAGE_FILEPATH]) 
    { 
     NSMutableDictionary* currentMessageDictioanry = [[NSMutableDictionary alloc] initWithContentsOfFile:KMESSAGE_FILEPATH]; 
     [videoDetailDict setObject:currentMessageDictioanry forKey:Kmessage]; 
     [currentMessageDictioanry release]; 
    } 

    [videoDetailDict setObject:pcNameString forKey:KPostCardName]; //[NSString stringWithFormat:@"PostCard Video%d",[videosListArray count]] 
    //[videosListArray insertObject:videoDetailDict atIndex:0]; 
    [videosListArray addObject:videoDetailDict]; 
    [videoDetailDict release]; 
    [videosListArray writeToFile:VIDEOS_FILE_PATH atomically:YES]; 

}  
]; 
} 
+0

嗨,你能幫我嗎?我正在處理相同的用例,但無法在合併文件中獲取視頻。我能夠爲assetSession獲取AVAssetExportSessionStatusCompleted狀態,但無法看到視頻。我檢查了我的視頻文件,它是正確的..也是我的音頻文件是適當的...但合併兩個視頻沒有得到顯示....你能告訴我什麼可能是問題? – DShah 2013-02-20 09:28:27

+0

更新了我的答案,檢查它! – Madhu 2013-02-20 09:58:05

+0

非常感謝Madhu ....它的工作.. +1 – DShah 2013-02-20 11:01:25

相關問題