如何使用背景音乐录制音频?

时间:2011-11-11 12:09:22

标签: iphone objective-c avaudiorecorder audiounit

从最近几天我正在开发一个iphone应用程序,它需要记录用户的音频并用背景音乐保存它,简单的话就是附加两个音频文件生成第三个音频文件,       我尝试使用AudioToolBox api但没有成功,可以任何人建议我正确的方向去哪里有任何建议,???

谢谢,

2 个答案:

答案 0 :(得分:2)

你可以通过

来做到这一点
- (BOOL) combineVoices1
{
    NSError *error = nil;
    BOOL ok = NO;


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,    NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];


    CMTime nextClipStartTime = kCMTimeZero;
    //Create AVMutableComposition Object.This object will hold our multiple AVMutableCompositionTrack.
    AVMutableComposition *composition = [[AVMutableComposition alloc] init];

    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack setPreferredVolume:0.8];
    NSString *soundOne  =[[NSBundle mainBundle]pathForResource:@"test1" ofType:@"caf"];
    NSURL *url = [NSURL fileURLWithPath:soundOne];
    AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
    NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *clipAudioTrack = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];

    AVMutableCompositionTrack *compositionAudioTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack setPreferredVolume:0.3];
    NSString *soundOne1  =[[NSBundle mainBundle]pathForResource:@"test" ofType:@"caf"];
    NSURL *url1 = [NSURL fileURLWithPath:soundOne1];
    AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:url1 options:nil];
    NSArray *tracks1 = [avAsset1 tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *clipAudioTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    [compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack1 atTime:kCMTimeZero error:nil];


    AVMutableCompositionTrack *compositionAudioTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack2 setPreferredVolume:1.0];
    NSString *soundOne2  =[[NSBundle mainBundle]pathForResource:@"song" ofType:@"caf"];
    NSURL *url2 = [NSURL fileURLWithPath:soundOne2];
    AVAsset *avAsset2 = [AVURLAsset URLAssetWithURL:url2 options:nil];
    NSArray *tracks2 = [avAsset2 tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *clipAudioTrack2 = [[avAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    [compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset2.duration) ofTrack:clipAudioTrack2 atTime:kCMTimeZero error:nil];



    AVAssetExportSession *exportSession = [AVAssetExportSession
                                           exportSessionWithAsset:composition
                                           presetName:AVAssetExportPresetAppleM4A];
    if (nil == exportSession) return NO;

    NSString *soundOneNew = [documentsDirectory stringByAppendingPathComponent:@"combined10.m4a"];
    //NSLog(@"Output file path - %@",soundOneNew);

    // configure export session  output with all our parameters
    exportSession.outputURL = [NSURL fileURLWithPath:soundOneNew]; // output path
    exportSession.outputFileType = AVFileTypeAppleM4A; // output file type

    // perform the export
    [exportSession exportAsynchronouslyWithCompletionHandler:^{

        if (AVAssetExportSessionStatusCompleted == exportSession.status) {
            NSLog(@"AVAssetExportSessionStatusCompleted");
        } else if (AVAssetExportSessionStatusFailed == exportSession.status) {
            // a failure may happen because of an event out of your control
            // for example, an interruption like a phone call comming in
            // make sure and handle this case appropriately
            NSLog(@"AVAssetExportSessionStatusFailed");
        } else {
            NSLog(@"Export Session Status: %d", exportSession.status);
        }
    }];


    return YES;


}

答案 1 :(得分:1)

你不会找到任何预先滚动的工具来做这件事,但是一旦你把记录位缩小就不会太难了。之后,您需要将文件与背景音乐混合,这可以通过简单地将原始样本添加到一起来完成。

要使该部分正常工作,您需要将背景音乐从您使用的任何压缩格式解码为原始PCM,以便您可以直接操作样本。自从我进行任何iOS开发以来已经很长时间了,所以我不知道iOS SDK能否直接执行此操作,或者您是否需要将libffmpeg与您的代码捆绑(或类似的东西)。但是IIRC,iPhone确实支持将压缩音频解码为PCM,但不支持对其进行编码(在一秒钟内更多)。

否则,您可以使用您的应用分发压缩(如zip,而不是mp3 / aac / ogg /无论)原始PCM文件并解压缩它们以直接获取样本数据。

一旦你得到最后的混音,你可以直接将它作为原始PCM流回播放设备。如果您需要保存或导出它,则需要再次查看解码/编码库。

根据有关此问题的经验,您可能希望在混合背景音乐之前对人声进行一些基本处理。首先,您需要将背景音轨标准化为-3dB(左右),以便用户的声音可以听到音乐。其次,您应该对人声应用高通滤波器以消除60Hz以下的所有频率,因为iPhone的麦克风可以拾取风或其他背景噪音。最后,您可能希望将压缩+限制器应用于人声样本,以便在安静的时间段内更容易听到人声。

不幸的是,你问的问题并不像“只使用函数mixdownTracksTogether()”那么简单,但你可以通过将其他工具和函数链接在一起来实现这一点。希望这能让你走上正轨!