iOS Удалить определенный звук из видео

У меня есть приложение, которое воспроизводит аудио, а также записывает видео + аудио во время воспроизведения этого звука. Я хотел бы найти способ обработки видео, чтобы звук, который был уловлен микрофоном, был удален из результирующего видео.

Например, если я воспроизводю аудиоА, а затем записываю видеоВ с аудиоВ (с микрофона), я хочу каким-то образом нейтрализовать аудиоА из результирующего аудиоВ, чтобы аудиоВ был только окружающим шумом, а не шумом из динамиков устройства. .

Любая идея, если есть способ сделать это?

Бонусные баллы, если это можно сделать без какой-либо офлайн-обработки.


person Liron    schedule 22.04.2015    source источник


Ответы (1)


Вы должны иметь дело с частью воспроизведения. Но вот код для микширования выбранного аудио с записанным видео.

- (void)mixAudio:(AVAsset*)audioAsset startTime:(CMTime)startTime withVideo:(NSURL*)inputUrl affineTransform:(CGAffineTransform)affineTransform  toUrl:(NSURL*)outputUrl outputFileType:(NSString*)outputFileType withMaxDuration:(CMTime)maxDuration withCompletionBlock:(void(^)(NSError *))completionBlock {
    NSError * error = nil;
    AVMutableComposition * composition = [[AVMutableComposition alloc] init];

    AVMutableCompositionTrack * videoTrackComposition = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

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

    AVURLAsset * fileAsset = [AVURLAsset URLAssetWithURL:inputUrl options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]];

    NSArray * videoTracks = [fileAsset tracksWithMediaType:AVMediaTypeVideo];

    CMTime duration = ((AVAssetTrack*)[videoTracks objectAtIndex:0]).timeRange.duration;

    if (CMTIME_COMPARE_INLINE(duration, >, maxDuration)) {
        duration = maxDuration;
    }

    for (AVAssetTrack * track in [audioAsset tracksWithMediaType:AVMediaTypeAudio]) {
        [audioTrackComposition insertTimeRange:CMTimeRangeMake(startTime, duration) ofTrack:track atTime:kCMTimeZero error:&error];

        if (error != nil) {
            completionBlock(error);
            return;
        }
    }

    for (AVAssetTrack * track in videoTracks) {
        [videoTrackComposition insertTimeRange:CMTimeRangeMake(kCMTimeZero, duration) ofTrack:track atTime:kCMTimeZero error:&error];

        if (error != nil) {
            completionBlock(error);
            return;
        }
    }

    videoTrackComposition.preferredTransform = affineTransform;

    AVAssetExportSession * exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
    exportSession.outputFileType = outputFileType;
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.outputURL = outputUrl;

    [exportSession exportAsynchronouslyWithCompletionHandler:^ {
        NSError * error = nil;
        if (exportSession.error != nil) {
            NSMutableDictionary * userInfo = [NSMutableDictionary dictionaryWithDictionary:exportSession.error.userInfo];
            NSString * subLocalizedDescription = [userInfo objectForKey:NSLocalizedDescriptionKey];
            [userInfo removeObjectForKey:NSLocalizedDescriptionKey];
            [userInfo setObject:@"Failed to mix audio and video" forKey:NSLocalizedDescriptionKey];
            [userInfo setObject:exportSession.outputFileType forKey:@"OutputFileType"];
            [userInfo setObject:exportSession.outputURL forKey:@"OutputUrl"];
            [userInfo setObject:subLocalizedDescription forKey:@"CauseLocalizedDescription"];

            [userInfo setObject:[AVAssetExportSession allExportPresets] forKey:@"AllExportSessions"];

            error = [NSError errorWithDomain:@"Error" code:500 userInfo:userInfo];
        }

        completionBlock(error);
    }];
}
person Xcoder    schedule 22.04.2015
comment
Выглядит как классный проект, но я не вижу на первый взгляд, как сделать то, что я предлагаю. - person Liron; 23.04.2015
comment
Я не думаю, что вы понимаете мой вопрос. У меня видео и звук соединяются нормально. Проблема в том, что запись также включает в себя окружающий шум, исходящий из динамиков (это звук, который я проигрываю в приложении). Я хочу каким-то образом подавить этот звук из окончательной записи. - person Liron; 24.04.2015
comment
Так сказать другими словами. Представьте, что мое приложение воспроизводит Моцарта из динамиков и в то же время записывает, как пользователь что-то говорит. Я хочу, чтобы эта запись каким-то образом не включала Моцарта, хотя микрофон его улавливает. - person Liron; 24.04.2015
comment
Предположительно, для этого потребуется какая-то обработка сигналов или что-то в этом роде. - person Liron; 24.04.2015
comment
В порядке. Это сложнее, чем я думал. Посмотрите на эту ссылку здесь stackoverflow.com/questions/10903542/ Вы можете попробовать установить для категории аудиосеанса другие значения и просто попробовать, прежде чем идти по маршруту отмены звука (например, [AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback] ). - person Xcoder; 24.04.2015
comment
Для получения дополнительной информации об этом developer.apple.com /library/ios/documentation/Audio/Conceptual/ - person Xcoder; 24.04.2015
comment
Я уже пробовал это, но это не сработало. Мне было интересно, могу ли я как-то использовать AudioUnit для этого, но кажется, что developer.apple.com/library/ios/documentation/AudioUnit/ не совсем то, что мне нужно быть. - person Liron; 26.04.2015
comment
Эй, @Liron, ты случайно не нашел способ добиться этого? Я пытаюсь сделать примерно то же самое. - person OriginalAlchemist; 30.01.2017
comment
Нет простите. В автономном режиме, если вы знаете оба аудиопотока, вы, вероятно, могли бы запустить какой-нибудь dsp, чтобы удалить один из другого, но я не нашел способа сделать это сам. - person Liron; 30.01.2017