2010-11-21 48 views
8

Tôi muốn thực hiện một tính năng cho phép người dùng cắt một tệp âm thanh (.caf) mà anh ta đã ghi lại một cách dữ dội. Phần ghi âm đã hoạt động, nhưng làm thế nào tôi có thể thêm một tính năng cắt tỉa tương tự như một trong ứng dụng Voicememos. Có một api cho âm thanh tông đơ táo sử dụng? Mọi trợ giúp sẽ tuyệt vời ...Cắt âm thanh với iOS

Trả lời

20

Làm thế nào để sử dụng AVFoundation? Nhập tệp âm thanh vào một AVAsset (thành phần vv), sau đó bạn có thể xuất nó - thiết lập thời gian + thời gian ưu tiên - thành một tệp.

Tôi đã viết một hàm cổ phiếu một thời gian trước đây để xuất một nội dung vào một tệp, bạn cũng có thể chỉ định một audiomix. Như dưới đây nó xuất khẩu tất cả các tập tin, nhưng bạn có thể thêm một NSTimeRange để exports.timeRange và có bạn đi. Tôi đã không thử nghiệm mà mặc dù, nhưng nên làm việc (?). Một lựa chọn khác có thể là điều chỉnh phạm vi thời gian khi tạo các bản nhạc AVAsset +. Tất nhiên nhà xuất khẩu chỉ xử lý m4a (AAC). Xin lỗi nếu đây không phải là những gì bạn muốn.

-(void)exportAsset:(AVAsset*)asset toFile:(NSString*)filename overwrite:(BOOL)overwrite withMix:(AVAudioMix*)mix { 
//NSArray* availablePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset]; 

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

if (exporter == nil) { 
    DLog(@"Failed creating exporter!"); 
    return; 
} 

DLog(@"Created exporter! %@", exporter); 

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

// Set outputURL 
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString* parentDir = [NSString stringWithFormat:@"%@/", [paths objectAtIndex:0]]; 

NSString* outPath = [NSString stringWithFormat:@"%@%@", parentDir, filename]; 

NSFileManager* manager = [NSFileManager defaultManager]; 
if ([manager fileExistsAtPath:outPath]) { 
    DLog(@"%@ already exists!", outPath); 
    if (!overwrite) { 
     DLog(@"Not overwriting, uh oh!"); 
     return; 
    } 
    else { 
     // Overwrite 
     DLog(@"Overwrite! (delete first)"); 
     NSError* error = nil; 
     if (![manager removeItemAtPath:outPath error:&error]) { 
      DLog(@"Failed removing %@, error: %@", outPath, error.description); 
      return; 
     } 
     else { 
      DLog(@"Removed %@", outPath); 
     } 
    } 
} 

NSURL* const outUrl = [NSURL fileURLWithPath:outPath]; 
exporter.outputURL = outUrl; 
// Specify a time range in case only part of file should be exported 
//exporter.timeRange = 

if (mix != nil) 
    exporter.audioMix = mix; // important 

DLog(@"Starting export! (%@)", exporter.outputURL); 
[exporter exportAsynchronouslyWithCompletionHandler:^(void) { 
    // Export ended for some reason. Check in status 
    NSString* message; 
    switch (exporter.status) { 
     case AVAssetExportSessionStatusFailed: 
      message = [NSString stringWithFormat:@"Export failed. Error: %@", exporter.error.description]; 
      DLog(@"%@", message); 
      [self showAlert:message]; 
      break; 
     case AVAssetExportSessionStatusCompleted: { 
      /*if (playfileWhenExportFinished) { 
      DLog(@"playfileWhenExportFinished!"); 
      [self playfileAfterExport:exporter.outputURL]; 
      playfileWhenExportFinished = NO; 
      }*/ 
      message = [NSString stringWithFormat:@"Export completed: %@", filename]; 
      DLog(@"%@", message); 
      [self showAlert:message]; 
      break; 
     } 
     case AVAssetExportSessionStatusCancelled: 
      message = [NSString stringWithFormat:@"Export cancelled!"]; 
      DLog(@"%@", message); 
      [self showAlert:message]; 
      break; 
     default: 
      DLog(@"Export unhandled status: %d", exporter.status); 
      break; 
    }  
}]; 
} 
+3

Nhưng phương pháp này chỉ cho phép âm thanh được lưu trong m4a định dạng, những gì nếu người ta muốn cắt một tập tin mp3 hoặc một quán cà phê và giữ cho rmat? – tommys

+1

Cắt mp3 cũng hoạt động, ouput được lưu trữ ở định dạng m4a Sau 2 năm, bạn vẫn tiết kiệm được cuộc sống của mình :) –

1

Câu trả lời ở trên của @Jonny là chính xác. Đây là tôi đang thêm việc sử dụng AudioMixer để thêm hiệu ứng Fade-in trong khi âm thanh cắt tỉa.

Output:. Tài sản âm thanh tỉa đến 20 giây với một phai 10 giây trong Các trang trí được thiết lập trong đoạn mã diễn ra tại 30 giây dấu ấn của tài sản và do đó thời gian theo dõi nên có ít nhất 50 giây.

- (BOOL)exportAssettoFilePath:(NSString *)filePath { 


NSString *inputFilePath = <inputFilePath>; 

NSURL *videoToTrimURL = [NSURL fileURLWithPath:inputFilePath]; 
AVAsset *avAsset = [AVAsset assetWithURL:videoToTrimURL]; 

// we need the audio asset to be at least 50 seconds long for this snippet 
CMTime assetTime = [avAsset duration]; 
Float64 duration = CMTimeGetSeconds(assetTime); 
if (duration < 50.0) return NO; 

// get the first audio track 
NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeAudio]; 
if ([tracks count] == 0) return NO; 

AVAssetTrack *track = [tracks objectAtIndex:0]; 

// create the export session 
// no need for a retain here, the session will be retained by the 
// completion handler since it is referenced there 
AVAssetExportSession *exportSession = [AVAssetExportSession 
             exportSessionWithAsset:avAsset 
             presetName:AVAssetExportPresetAppleM4A]; 
if (nil == exportSession) return NO; 

// create trim time range - 20 seconds starting from 30 seconds into the asset 
CMTime startTime = CMTimeMake(30, 1); 
CMTime stopTime = CMTimeMake(50, 1); 
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime); 

// create fade in time range - 10 seconds starting at the beginning of trimmed asset 
CMTime startFadeInTime = startTime; 
CMTime endFadeInTime = CMTimeMake(40, 1); 
CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(startFadeInTime, 
                 endFadeInTime); 

// setup audio mix 
AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix]; 
AVMutableAudioMixInputParameters *exportAudioMixInputParameters = 
[AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track]; 

[exportAudioMixInputParameters setVolumeRampFromStartVolume:0.0 toEndVolume:1.0 
                timeRange:fadeInTimeRange]; 
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 range 
//exportSession.audioMix = exportAudioMix; // fade in audio mix 

// 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: %ld", (long)exportSession.status); 
    } 
}]; 

return YES;} 

Cảm ơn

Để biết thêm chi tiết:

https://developer.apple.com/library/ios/qa/qa1730/_index.html

Các vấn đề liên quan