2012-01-28 158 views
4

我想剪切iPhone项目的音频文件。我可以将其剪下并保存,但是我尝试应用的任何淡入/淡出都不起作用,音频文件仅保存为已切割但不褪色。保存音频淡入淡出与setVolumeRampFromStartVolume不工作在iOS

我使用下面的代码:

// 
// NO PROBLEMS TO SEE HERE, MOVE ON 
// 
    NSArray *documentsFolders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    int currentFileNum = 10; 
    NSURL *url = [NSURL fileURLWithPath: [[documentsFolders objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d.%@", AUDIO_SOURCE_FILE_NAME ,currentFileNum, AUDIO_SOURCE_FILE_EXTENSION ]]]; 
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] 
                 forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; 
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:options]; 
    AVAssetExportSession* exporter = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A]; 

    for (NSString* filetype in exporter.supportedFileTypes) { 
     if ([filetype isEqualToString:AVFileTypeAppleM4A]) { 
      exporter.outputFileType = AVFileTypeAppleM4A; 
      break; 
     } 
    } 
    if (exporter.outputFileType == nil) { 
     NSLog(@"Needed output file type not found? (%@)", AVFileTypeAppleM4A); 
     //return; 
    } 

    NSString* outPath = [[documentsFolders objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d.%@", AUDIO_CUTTED_FILE_NAME ,currentFileNum, AUDIO_SOURCE_FILE_EXTENSION ]]; 

    NSURL* const outUrl = [NSURL fileURLWithPath:outPath]; 
    exporter.outputURL = outUrl; 

    float endTrimTime = CMTimeGetSeconds(asset.duration); 
    float startTrimTime = fminf(AUDIO_DURATION, endTrimTime); 
    CMTime startTrimCMTime=CMTimeSubtract(asset.duration, CMTimeMake(startTrimTime, 1)); 
    exporter.timeRange = CMTimeRangeMake(startTrimCMTime, asset.duration); 

// 
// TRYING TO APPLY FADEIN FADEOUT, NOT WORKING, NO RESULTS, "CODE IGNORED" 
// 
    AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix]; 

    NSMutableArray* inputParameters = [NSMutableArray arrayWithCapacity:1]; 

    CMTime startFadeInTime = startTrimCMTime; 
    CMTime endFadeInTime = CMTimeMake(startTrimTime+1, 1); 
    CMTime startFadeOutTime = CMTimeMake(endTrimTime-1, 1); 
    CMTime endFadeOutTime = CMTimeMake(endTrimTime, 1); 

    CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(startFadeInTime, endFadeInTime); 

    CMTimeRange fadeOutTimeRange = CMTimeRangeFromTimeToTime(startFadeOutTime, endFadeOutTime); 

    AVMutableAudioMixInputParameters *exportAudioMixInputParameters = [AVMutableAudioMixInputParameters audioMixInputParameters]; 
    [exportAudioMixInputParameters setVolume:0.0 atTime:CMTimeMakeWithSeconds(startTrimTime-0.01, 1)]; 
    [exportAudioMixInputParameters setVolumeRampFromStartVolume:0.0 toEndVolume:1.0 timeRange:fadeInTimeRange]; 
    [exportAudioMixInputParameters setVolumeRampFromStartVolume:1.0 toEndVolume:0.0 timeRange:fadeOutTimeRange]; 

    [inputParameters insertObject:exportAudioMixInputParameters atIndex:0]; 

    exportAudioMix.inputParameters = inputParameters; 
    exporter.audioMix = exportAudioMix; 

    [exporter exportAsynchronouslyWithCompletionHandler:^(void) { 
     NSString* message; 
     switch (exporter.status) { 
      case AVAssetExportSessionStatusFailed: 
       message = [NSString stringWithFormat:@"Export failed. Error: %@", exporter.error.description]; 
       [asset release]; 
       break; 
      case AVAssetExportSessionStatusCompleted: { 
       [asset release]; 
       [self reallyConvert:currentFileNum]; 
       message = [NSString stringWithFormat:@"Export completed: %@", outPath]; 
       break; 
      } 
      case AVAssetExportSessionStatusCancelled: 
       message = [NSString stringWithFormat:@"Export cancelled!"]; 
       [asset release]; 
       break; 
      default: 
       NSLog(@"Export 4 unhandled status: %d", exporter.status); 
       [asset release]; 
       break; 
     }  
    }]; 
+0

你有没有找到解决办法?请帮忙。 – iPhoneDv 2012-06-16 16:11:43

回答

1

您需要选择曲目。而不是调用的:

AVMutableAudioMixInputParameters *exportAudioMixInputParameters = [AVMutableAudioMixInputParameters audioMixInputParameters]; 

电话:

AVAssetTrack *assetTrack = [[asset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0]; 

AVMutableAudioMixInputParameters *exportAudioMixInputParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:assetTrack]; 

在现有的代码,你也可以指定轨道是这样的:

exportAudioMixInputParameters.trackID = [[[asset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0] trackID]; 

祝你好运!

1

这是解决方案。

setVolumeRampFromStartVolume不起作用。

AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix]; 
AVMutableAudioMixInputParameters *exportAudioMixInputParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track]; 

//淡入

[exportAudioMixInputParameters setVolume:0.0 atTime:CMTimeMakeWithSeconds(start-1, 1)]; 
[exportAudioMixInputParameters setVolume:0.1 atTime:CMTimeMakeWithSeconds(start, 1)]; 
[exportAudioMixInputParameters setVolume:0.5 atTime:CMTimeMakeWithSeconds(start+1, 1)]; 
[exportAudioMixInputParameters setVolume:1.0 atTime:CMTimeMakeWithSeconds(start+2, 1)]; 

//淡出

[exportAudioMixInputParameters setVolume:1.0 atTime:CMTimeMakeWithSeconds((start+length-2), 1)]; 
[exportAudioMixInputParameters setVolume:0.5 atTime:CMTimeMakeWithSeconds((start+length-1), 1)]; 
[exportAudioMixInputParameters setVolume:0.1 atTime:CMTimeMakeWithSeconds((start+length), 1)]; 

exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters]; 


// configure export session output with all our parameters 
exportSession.outputURL = [NSURL fileURLWithPath:filePath]; // output path 
exportSession.outputFileType = AVFileTypeAppleM4A; // output file type 
exportSession.timeRange = exportTimeRange; // trim time ranges 
exportSession.audioMix = exportAudioMix; // fade in audio mix 
// perform the export 
[exportSession exportAsynchronouslyWithCompletionHandler:^{ 

    if (AVAssetExportSessionStatusCompleted == exportSession.status) { 
     NSLog(@"AVAssetExportSessionStatusCompleted"); 

    } else if (AVAssetExportSessionStatusFailed == exportSession.status) { 
     NSLog(@"AVAssetExportSessionStatusFailed"); 

    } else { 
     NSLog(@"Export Session Status: %d", exportSession.status); 
    } 
}]; 
+1

这是大多数人犯的错误,因此看不到setVolumeRampFromStartVolume的工作。 (这是我迄今为止所经历的)。 不要做:CMTimeRangeMake(开始时间,结束时间) 但是:CMTimeRangeMake(开始时间,范围持续时间) 我犯了这个错误几十次,因为如果你的持续时间从0开始,范围持续时间=结束时间 但在淡出的情况下,它不是! – Taiko 2015-04-19 11:38:56

0

这是我工作的代码,只是把它和有一个愉快的一天!

+(void)makeAudioFadeOutWithSourceURL:(NSURL*)sourceURL destinationURL:(NSURL*)destinationURL fadeOutBeginSecond:(NSInteger)beginTime fadeOutEndSecond:(NSInteger)endTime fadeOutBeginVolume:(CGFloat)beginVolume fadeOutEndVolume:(CGFloat)endVolume callback:(void(^)(BOOL))callback 
{ 
    NSAssert(callback, @"need callback"); 
    NSParameterAssert(beginVolume >= 0 && beginVolume <=1); 
    NSParameterAssert(endVolume >= 0 && endVolume <= 1); 

    BOOL sourceExist = [[NSFileManager defaultManager] fileExistsAtPath:sourceURL.path]; 
    NSAssert(sourceExist, @"source not exist"); 

    AVURLAsset *asset = [AVAsset assetWithURL:sourceURL];; 

    AVAssetExportSession* exporter = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A]; 

    exporter.outputURL = destinationURL; 
    exporter.outputFileType = AVFileTypeAppleM4A; 

    AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix]; 

    AVMutableAudioMixInputParameters *exportAudioMixInputParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:asset.tracks.lastObject]; 
    [exportAudioMixInputParameters setVolumeRampFromStartVolume:beginVolume toEndVolume:endVolume timeRange:CMTimeRangeMake(CMTimeMakeWithSeconds(beginTime, 1), CMTimeSubtract(CMTimeMakeWithSeconds(endTime, 1), CMTimeMakeWithSeconds(beginTime, 1)))]; 
    NSArray *audioMixParameters = @[exportAudioMixInputParameters]; 
    exportAudioMix.inputParameters = audioMixParameters; 

    exporter.audioMix = exportAudioMix; 

    [exporter exportAsynchronouslyWithCompletionHandler:^(void){ 
     AVAssetExportSessionStatus status = exporter.status; 
     if (status != AVAssetExportSessionStatusCompleted) { 
      if (callback) { 
       callback(NO); 
      } 
     } 
     else { 
      if (callback) { 
       callback(YES); 
      } 
     } 
     NSError *error = exporter.error; 
     NSLog(@"export done,error %@,status %d",error,status); 
    }]; 
} 
1

我犯了同样的错误,你几十次! 苹果的API是对这个很奇怪:

CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(startFadeInTime, endFadeInTime); 

CMTimeRange fadeOutTimeRange = CMTimeRangeFromTimeToTime(startFadeOutTime, endFadeOutTime); 

应该是:

CMTimeRangeFromTimeToTime(startFadeInTime, fadeInDURATION); 

CMTimeRangeFromTimeToTime(startFadeOutTime, fadeOutDURATION); 

CMTimeRange从开始和持续时间,而不是从开始创建和结束!

但大多数时候,结束时间也是持续时间(如果开始时间为0),这就是为什么很多人(包括我)犯错的原因。

而且没有苹果,这根本不直观!