2010-11-21 13 views
8

Quiero implementar una característica que le permita al usuario recortar un archivo de audio (.caf) que grabó perceptivamente. La parte de grabación ya funciona, pero ¿cómo puedo agregar una función de recorte similar a la de la aplicación Voicememos? ¿Hay una API para la recortadora de audio que Apple usa? Cualquier ayuda sería genial ...Recortar audio con iOS

Respuesta

20

¿Qué le parece usar la AVFoundation? Importe el archivo de audio en un AVAsset (composición, etc.), luego puede exportarlo (estableciendo el tiempo preferido + duración) a un archivo.

Escribí hace un tiempo una función que exporta un activo a un archivo, también puede especificar un audiomix. Como a continuación, exporta todo el archivo, pero puede agregar un NSTimeRange a exporter.timeRange y listo. Aunque no lo he probado, pero debería funcionar (?). Otra alternativa podría ser ajustar los intervalos de tiempo al crear las pistas AVAsset +. Por supuesto, el exportador solo maneja m4a (AAC). Lo siento si esto no era lo que querías.

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

Pero este método sólo permite que el sonido se pueden guardar en el M4A formato, lo si a uno le gusta recortar un mp3 o un archivo caf y mantener el fo ¿rmat? – tommys

+1

Trim mp3 también funciona, salida almacenada en formato m4a Después de 2 años, todavía me salvaste la vida :) –

1

La respuesta anterior de @Jonny es correcta. Aquí estoy agregando el uso de AudioMixer para agregar el efecto Fade-In mientras se recorta el audio.

de salida:. Activos audio recortado a 20 segundos, con 10 segundos de desvanecimiento en El ajuste se creó en el fragmento de código se lleva a cabo en la marca de 30 segundos del activo y por lo tanto la duración de pista debería estar en menos 50 segundos.

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

Gracias

para más detalles:

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

Cuestiones relacionadas