Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

DavidBlack

macrumors 6502a
Original poster
Jan 27, 2013
606
239
Somewhere In Apple's HQ ;)
Does anyone know of any API which I can use to merge a video (which contains no audio) and merge it with a audio track? I don't need to manipulate the time range or anything just to combine/merge them into one video file.

Thanks for any reply in advance.
P:S: I will also be very grateful if anyone includes a code a snippet with their reply :) :)
 

DavidBlack

macrumors 6502a
Original poster
Jan 27, 2013
606
239
Somewhere In Apple's HQ ;)
Wrote a Class

Since no one replied I did some research and wrote a class for this:
If anyone wants to accomplish this task you can use this:

Code:
-(void) mergeAudio:(NSURL *) audioURL withVideo:(NSURL *) videoURL andSaveToPathUrl:(NSString *) savePath{

    SJPowerAssertions *assertion = [[SJPowerAssertions alloc]init];
    
    [assertion createPowerAssertion:@"Merging Audio & Video Track" assertionType:SJPowerAssertionsPreventIdleSleep];
    
     AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioURL options:nil];
     AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoURL options:nil];
         
         if (![[NSFileManager defaultManager] fileExistsAtPath:[audioURL path]]){
             NSLog(@"Cannot find audio url");
             
             if (self.delegate && [self.delegate respondsToSelector:@selector(mergeFailed:)]) {
                 [self.delegate performSelectorOnMainThread:@selector(mergeFailed:) withObject:self waitUntilDone:NO];
             }
             
             return;
         }
         
         if (![[NSFileManager defaultManager] fileExistsAtPath:[videoURL path]]){
             NSLog(@"Cannot find video url");
             
             if (self.delegate && [self.delegate respondsToSelector:@selector(mergeFailed:)]) {
                 [self.delegate performSelectorOnMainThread:@selector(mergeFailed:) withObject:self waitUntilDone:NO];
             }
             
             return;
         }

         
         
    AVMutableComposition* mixComposition = [AVMutableComposition composition];
    
    AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
                                        ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                                         atTime:kCMTimeZero error:nil];
    
   AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                                   preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
                                   ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                                    atTime:kCMTimeZero error:nil];
    
   AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                          presetName:AVAssetExportPresetPassthrough];
    
    NSURL    *savetUrl = [NSURL fileURLWithPath:savePath];
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:savePath])
    {
        [[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
    }
    
         _assetExport.outputFileType = AVFileTypeMPEG4;
    
    
    _assetExport.outputURL = savetUrl;
    _assetExport.shouldOptimizeForNetworkUse = YES;
    
    [_assetExport exportAsynchronouslyWithCompletionHandler:
     ^(void ) {
     
         
             NSLog(@"Merge did start");
             
             if (self.delegate && [self.delegate respondsToSelector:@selector(mergeDidStart:)]) {
                 [self.delegate performSelectorOnMainThread:@selector(mergeDidStart:) withObject:self waitUntilDone:NO];
             }
             
             
             switch (_assetExport.status)
             {
                 case AVAssetExportSessionStatusFailed:
                 {
                     NSLog (@"FAIL");
                     
                     if (self.delegate && [self.delegate respondsToSelector:@selector(mergeFailed:)]) {
                         [self.delegate performSelectorOnMainThread:@selector(mergeFailed:) withObject:self waitUntilDone:NO];
                         [assertion stopHoldingAssertion];
                         
                     }

                     break;
                 }
                 case AVAssetExportSessionStatusCompleted:
                 {
                     NSLog (@"SUCCESS");
                     if (self.delegate && [self.delegate respondsToSelector:@selector(mergeDone:)]) {
                         [self.delegate performSelectorOnMainThread:@selector(mergeDone:) withObject:self waitUntilDone:NO];
                         
                         //Delete audio track
                         [[NSFileManager defaultManager] removeItemAtPath:[audioURL path] error:nil];

                         [assertion stopHoldingAssertion];
                         
                                             }
                     
                     break;
                 }
                 case AVAssetExportSessionStatusCancelled:
                 {
                     NSLog (@"CANCELED");
                     
                     break;
                 } case AVAssetExportSessionStatusExporting:{
                     
                     break;
                     
                 } case AVAssetExportSessionStatusUnknown:{
                     if (self.delegate && [self.delegate respondsToSelector:@selector(mergeFailed:)]) {
                         [self.delegate performSelectorOnMainThread:@selector(mergeFailed:) withObject:self waitUntilDone:NO];
                         [assertion stopHoldingAssertion];

                     }
                     
                     break;
                     
                     
                 }case AVAssetExportSessionStatusWaiting:{
                     
                     break;
                     
                 }
             };
             
      
         
     }
     
     ];
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.