Как записать звук с фоновой музыкой?

#iphone #objective-c #avaudiorecorder #audiounit

#iPhone #objective-c #avaudiorecorder #audiounit

Вопрос:

последние несколько дней я работаю над приложением для iphone, которому необходимо записывать аудио пользователей и сохранять его с фоновой музыкой в нем, простыми словами, путем добавления двух аудиофайлов генерируется третий аудиофайл, я пытаюсь сделать это с помощью AudioToolbox api, но безуспешно, может ли кто-нибудь подсказать мне правильное направление, куда идти для этого любое предложение,???

Спасибо,

Ответ №1:

Вы можете сделать это с помощью

 - (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;


}
  

Ответ №2:

Вы не найдете никаких готовых инструментов для этого, но это не так уж сложно, как только вы немного снизите скорость записи. После этого вам нужно будет смешать файл с фоновой музыкой, что можно сделать, просто добавив необработанные сэмплы вместе.

Для работы этой части вам необходимо либо декодировать фоновую музыку из любого используемого вами сжатого формата в raw PCM, чтобы вы могли напрямую манипулировать сэмплами. Прошло много времени с тех пор, как я занимался какой-либо разработкой для iOS, поэтому я не знаю, способен ли iOS SDK сделать это напрямую или вам нужно будет связать libffmpeg с вашим кодом (или что-то подобное этому). Но, IIRC, iPhone поддерживает декодирование сжатого звука в PCM, но не кодирование его (подробнее об этом через секунду).

В противном случае вы можете распространять сжатые (в формате zip, а не mp3 / aac / ogg / что угодно) необработанные файлы PCM с вашим приложением и разархивировать их, чтобы получить образцы данных напрямую.

Как только вы получите окончательный микшированный файл, вы можете транслировать его обратно через устройство воспроизведения в виде необработанного PCM. Если вам нужно сохранить или экспортировать его, вам нужно будет снова обратиться к библиотеке декодирования / encoding library.

Исходя из опыта в этом вопросе, вы, вероятно, захотите выполнить небольшую базовую обработку вокала, прежде чем микшировать его с фоновой музыкой. Во-первых, вы захотите, чтобы ваши фоновые дорожки были нормализованы до -3 дБ (или около того), чтобы голос пользователя был слышен поверх музыки. Во-вторых, вы должны применить фильтр высоких частот к вокалу, чтобы удалить все частоты ниже 60 Гц, поскольку микрофон iPhone может улавливать ветер или другие фоновые шумы. Наконец, вы, вероятно, захотите применить сжатие ограничитель к вокальному сэмплу, чтобы вокал было немного легче слышать во время тихих отрезков.

К сожалению, вопрос, который вы задали, не так прост, как «просто используйте функцию mixdownTracksTogether()», но вы определенно можете заставить это работать, объединив другие инструменты и функции вместе. Надеюсь, это поможет вам встать на правильный путь!