Search code examples
iosobjective-caudiovideocomposition

why no sound when I merge Audio and video using AVMutableCompositionTrack?


why no sound when I merge Audio and video using AVMutableCompositionTrack?

    NSArray * breakArr = [[[[_dic objectForKey:@"url"] lastObject] objectForKey:@"url"]componentsSeparatedByString:@"/"];
    NSString *pathAudio = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:[breakArr lastObject]];

    AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:pathAudio] options:nil];

    NSString *pathVideo = self.pathToMovie;
    AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:pathVideo] options:nil];

    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, videoAsset.duration)
                                   ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                                    atTime:kCMTimeZero error:nil];

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

    NSString* videoName = @"export.mov";

    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";
    _assetExport.outputFileType = AVFileTypeMPEG4;
    _assetExport.outputURL = exportUrl;

    _assetExport.shouldOptimizeForNetworkUse = YES;

    [_assetExport exportAsynchronouslyWithCompletionHandler:
         ^(void ) {
             // your completion code here
             [[ModelessAlertView instance]closeAlert];
             UISaveVideoAtPathToSavedPhotosAlbum(exportPath, self, @selector(videoWithPatch:didFinishSavingWithError:contextInfo:), nil);
         }

     ];

here is the code. when I review the video. I only hear the audio track sound. and I can not hear the video sound.how can I set the volume?

is anyone know? thank you very much.!


Solution

  • Your code works. assure if your audio exist on the path. I have try to load sound and video from bundle and merge using your code. it works as i expected. my load from bundle looks like this.

    NSString *pathAudio = [[NSBundle mainBundle] pathForResource:@"sound" ofType:@"mp3"];
    AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:pathAudio] options:nil];
    
    NSString *pathVideo = [[NSBundle mainBundle] pathForResource:@"Clip1" ofType:@"mp4"];
    AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:pathVideo] options:nil];
    

    UPDATED

    In order to merge video sound and another sound same time add another AVMutableCompositionTrack to your AVMutableComposition.

    // add another track for video sound
    AVMutableCompositionTrack *videoSoundTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                         preferredTrackID:kCMPersistentTrackID_Invalid];
    
    //insert video sound to the track
    [videoSoundTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                             ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                              atTime:kCMTimeZero error:nil];