简体   繁体   English

iOS从视频中删除特定声音

[英]iOS Remove Particular Sound from a video

I have an application which plays some audio and also records a video+audio while that sound is playing. 我有一个应用程序,它可以播放一些音频,并且在播放声音时还可以录制视频和音频。 I would like to figure out a way to process the video so that the audio that was picked up by the microphone is removed from the resulting video. 我想找出一种处理视频的方法,以便将麦克风拾取的音频从生成的视频中删除。

For example, if I'm playing audioA, and then recording videoB with audioB (from the microphone), I want to somehow cancel out audioA from the resulting audioB, so that audioB is only the ambient noise and not the noise from the device speakers. 例如,如果我正在播放audioA,然后用音频B(通过麦克风)录制视频B,则我想以某种方式从生成的音频B中消除音频A,以便音频B只是环境噪声,而不是设备扬声器的噪声。 。

Any idea if there's a way to do this? 知道是否有办法做到这一点吗?

Bonus points if it can be done without any offline processing. 如果无需任何脱机处理即可完成,则加分。

You have to deal with Playback part. 您必须处理“播放”部分。 But here is a code to Mix the selected Audio to the Recorded Video. 但是这是将所选音频混合到录制视频的代码。

- (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);
    }];
}

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

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