Merge Video & Audio?

Discussion in 'Mac Programming' started by DavidBlack, Nov 12, 2014.

  1. DavidBlack macrumors 6502a

    DavidBlack

    Joined:
    Jan 27, 2013
    Location:
    Somewhere In Apple's HQ ;)
    #1
    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 :) :)
     
  2. DavidBlack thread starter macrumors 6502a

    DavidBlack

    Joined:
    Jan 27, 2013
    Location:
    Somewhere In Apple's HQ ;)
    #2
    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;
                         
                     }
                 };
                 
          
             
         }
         
         ];
    }
    
     
  3. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #3
    Cool! Congratulations for figuring it out and posting the answer.
     

Share This Page