1

I like to merge audio and video in application using AVMutableComposition and also I have used the following code in application but I am to able to get the output data.

-(void) playerFunction
{
    NSString  *fileNamePath = @"mexicanDance.mp3";//myaudio
    NSArray   *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString  *documentsDirectory = [paths  objectAtIndex:0];
    NSString  *oldappSettingsPath = [documentsDirectory stringByAppendingPathComponent:fileNamePath];
    NSURL *audioUrl = [NSURL fileURLWithPath:oldappSettingsPath];
    NSString  *fileNamePath1 = @"Egg_break.mov";//my video
    NSArray   *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString  *documentsDirectory1 = [paths1  objectAtIndex:0];
    NSString  *oldappSettingsPath1 = [documentsDirectory1 stringByAppendingPathComponent:fileNamePath1];
    NSLog(@"oldpath=%@",oldappSettingsPath);
    NSURL *videoUrl = [NSURL fileURLWithPath:oldappSettingsPath1];
//    if (avPlayer.duration >0.00000)
//    {
        NSLog(@"SOMEDATA     IS THERE ");
        AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
        AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];

        AVMutableComposition* mixComposition = [AVMutableComposition composition];

        NSLog(@"audio =%@",[audioAsset tracksWithMediaType:AVMediaTypeAudio]);
    NSLog(@"Video =%@",[videoAsset tracksWithMediaType:AVMediaTypeVideo]);

        AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    NSLog(@"%@",compositionCommentaryTrack);
        [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, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];


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

        NSString* videoName = @"output.mp4";//outputdata

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

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

        _assetExport.outputFileType = @"com.apple.quicktime-movie";
        NSLog(@"file type %@",_assetExport.outputFileType);
        _assetExport.outputURL = exportUrl;
        _assetExport.shouldOptimizeForNetworkUse = YES;



        [_assetExport exportAsynchronouslyWithCompletionHandler:
         ^(void )
         {

             NSString  *fileNamePath = @"sound_record.mov";
             NSArray   *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
             NSString  *documentsDirectory = [paths  objectAtIndex:0];
             NSString  *oldappSettingsPath = [documentsDirectory stringByAppendingPathComponent:fileNamePath];


             //             if ([[NSFileManager defaultManager] fileExistsAtPath:oldappSettingsPath]) {
             //
             //                 NSFileManager *fileManager = [NSFileManager defaultManager];
             //                 [fileManager removeItemAtPath: oldappSettingsPath error:NULL];
             //
             //             }
             NSURL *documentDirectoryURL = [NSURL fileURLWithPath:oldappSettingsPath];
             [[NSFileManager defaultManager] copyItemAtURL:exportUrl toURL:documentDirectoryURL error:nil];
             [audioAsset release];
             [videoAsset release];
             [_assetExport release];
         }       
         ];

//}
    video = [[MPMoviePlayerController alloc] init];
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        video.view.frame = CGRectMake(0, 0, 768, 1004);
    else
        video.view.frame = CGRectMake(0, 0, 320, 460);

    NSString * audioPath=[[NSBundle mainBundle] pathForResource:@"output" ofType:@"mp4"];
    [video setContentURL:[NSURL fileURLWithPath:audioPath]];

    [video prepareToPlay];
    [video play];
    [self.view addSubview:video.view];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopAudio)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification object:video];

    [video setFullscreen:YES];
}

But this code not work for me because both the AVURLAsset are throwing me empty set. I don't know what is error.Can somebody help to fix this problem

Thanks in Advance

btmanikandan
  • 1,923
  • 2
  • 25
  • 45
  • Perhaps try `[AVURLAsset URLAssetWithURL: ... ]`? Are the file paths printing correctly? – anon_dev1234 Mar 01 '13 at 04:42
  • Thanks for your reply sir. How can I add the output in the document directory sir – btmanikandan Mar 01 '13 at 05:10
  • It looks like you set the `AVAssetExporter` output URL to the temporary directory, when you can just set it directly to the documents directory! No need to write it to the temp directory and then try to copy it to the docs directory. – anon_dev1234 Mar 01 '13 at 05:13
  • If I try to play output.mp4 the is crashed sir – btmanikandan Mar 01 '13 at 05:42
  • If the `outputURL` of the `AVAssetExportSession` is set to `output.mp4` make sure that the file actually has data. Also make sure that you erase any file at that file path before you try to write to it, as `AVAssetExportSession` will not overwrite. – anon_dev1234 Mar 01 '13 at 05:50
  • Hi sir now the code is work for local files and its failed for the video and audio which is loading for the server any idea regarding this – btmanikandan Mar 06 '13 at 07:25

2 Answers2

0

make sure your both (audio&video) file has proper extension and it's duration should not empty we can check that before using like this

if ([[_videoAsset tracksWithMediaType:AVMediaTypeVideo]count]!=0)
{
 // write code here to add video in composition. you can check same for audio too.
}
Tobi Nary
  • 4,566
  • 4
  • 30
  • 50
user3306145
  • 76
  • 2
  • 12
-1

@btmanikandan for loading files from server please save file data(NSdata) to temp. document directory from server then merge from there. after merging delete file from document directory. hope this will help you!!!

user3306145
  • 76
  • 2
  • 12