简体   繁体   English

如何在iphone SDK上将音频添加到视频文件

[英]How to add audio to video file on iphone SDK

I have a video file and an audio file.我有一个视频文件和一个音频文件。 Is it possible to merge it to one video with with sound file.是否可以将它合并到一个带有声音文件的视频中。 I think AVMutableComposition should help me, but I still dont understand how.我认为 AVMutableComposition 应该帮助我,但我仍然不明白如何。 any advices?有什么建议吗?

Thanks Daniel.谢谢丹尼尔。 I figured it out, its easy.我想通了,这很容易。

AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl 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:AVAssetExportPresetPassthrough];   

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";
DLog(@"file type %@",_assetExport.outputFileType);
_assetExport.outputURL = exportUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;

[_assetExport exportAsynchronouslyWithCompletionHandler:
 ^(void ) {      
            // your completion code here
     }       
 }
 ];

Yes it is possible, here is a snippet of code that is used to add audio to an existing composition, i grabbed this from apples sample code, you should probably view the whole project, youll find it very useful, the project is AVEditDemo and you can find it in the WWDC 2010 material that they posted here developer.apple.com/videos/wwdc/2010.是的,这是可能的,这里有一段代码用于将音频添加到现有的组合中,我从苹果示例代码中抓取了这个,你可能应该查看整个项目,你会发现它非常有用,该项目是 AVEditDemo 并且你可以在他们在此处发布的 WWDC 2010 材料中找到它 developer.apple.com/videos/wwdc/2010。 Hope that helps希望有帮助

 - (void)addCommentaryTrackToComposition:(AVMutableComposition *)composition withAudioMix:(AVMutableAudioMix *)audioMix

{

NSInteger i;

NSArray *tracksToDuck = [composition tracksWithMediaType:AVMediaTypeAudio]; // before we add the commentary



// Clip commentary duration to composition duration.

CMTimeRange commentaryTimeRange = CMTimeRangeMake(self.commentaryStartTime, self.commentary.duration);

if (CMTIME_COMPARE_INLINE(CMTimeRangeGetEnd(commentaryTimeRange), >, [composition duration]))

    commentaryTimeRange.duration = CMTimeSubtract([composition duration], commentaryTimeRange.start);



// Add the commentary track.

AVMutableCompositionTrack *compositionCommentaryTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, commentaryTimeRange.duration) ofTrack:[[self.commentary tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:commentaryTimeRange.start error:nil];





NSMutableArray *trackMixArray = [NSMutableArray array];

CMTime rampDuration = CMTimeMake(1, 2); // half-second ramps

for (i = 0; i < [tracksToDuck count]; i++) {

    AVMutableAudioMixInputParameters *trackMix = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:[tracksToDuck objectAtIndex:i]];

    [trackMix setVolumeRampFromStartVolume:1.0 toEndVolume:0.2 timeRange:CMTimeRangeMake(CMTimeSubtract(commentaryTimeRange.start, rampDuration), rampDuration)];

    [trackMix setVolumeRampFromStartVolume:0.2 toEndVolume:1.0 timeRange:CMTimeRangeMake(CMTimeRangeGetEnd(commentaryTimeRange), rampDuration)];

    [trackMixArray addObject:trackMix];

}

audioMix.inputParameters = trackMixArray;

} }

Here is the swift version:这是快速版本:

    func mixAudio(audioURL audioURL: NSURL, videoURL: NSURL) {
    let audioAsset = AVURLAsset(URL: audioURL)
    let videoAsset = AVURLAsset(URL: videoURL)

    let mixComposition = AVMutableComposition()

    let compositionCommentaryTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)

    // add audio
    let timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
    let track = audioAsset.tracksWithMediaType(AVMediaTypeAudio)[0]
    do {
        try compositionCommentaryTrack.insertTimeRange(timeRange, ofTrack: track, atTime: kCMTimeZero)
    }
    catch {
        print("Error insertTimeRange for audio track \(error)")
    }

    // add video
    let compositionVideoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)

    let timeRangeVideo = CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
    let trackVideo = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
    do {
        try compositionVideoTrack.insertTimeRange(timeRangeVideo, ofTrack: trackVideo, atTime: kCMTimeZero)
    }
    catch {
        print("Error insertTimeRange for video track \(error)")
    }

    // export
    let assetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetPassthrough)
    let videoName = "export.mov"
    exportPath = "\(NSTemporaryDirectory())/\(videoName)"
    let exportURL = NSURL(fileURLWithPath: exportPath!)

    if NSFileManager.defaultManager().fileExistsAtPath(exportPath!) {
        do {
            try NSFileManager.defaultManager().removeItemAtPath(exportPath!)
        }
        catch {
            print("Error deleting export.mov: \(error)")
        }
    }

    assetExportSession?.outputFileType = "com.apple.quicktime-movie"
    assetExportSession?.outputURL = exportURL
    assetExportSession?.shouldOptimizeForNetworkUse = true
    assetExportSession?.exportAsynchronouslyWithCompletionHandler({ 
        print("Mixed audio and video!")
        dispatch_async(dispatch_get_main_queue(), {
            print(self.exportPath!)

        })
    })

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM