Je souhaite implémenter une fonctionnalité qui permet à l'utilisateur de rogner un fichier audio (.caf) qu'il a précédemment enregistré. La partie enregistrement fonctionne déjà, mais comment puis-je ajouter une fonction de recadrage similaire à celle de l'application Voicememos. Y a-t-il un api pour les utilisations d'Apple tondeuse audio? Toute aide serait formidable ...Ajuster l'audio avec iOS
Répondre
Comment utiliser l'AVFoundation? Importez le fichier audio dans un AVAsset (composition, etc), puis vous pouvez l'exporter - définir l'heure préférée + durée - dans un fichier.
J'ai écrit il y a quelque temps une fonction de stock qui exporte un actif dans un fichier, vous pouvez également spécifier un audiomix. Comme ci-dessous, il exporte tout le fichier, mais vous pouvez ajouter un NSTimeRange à exporter.timeRange et voilà. Je n'ai pas testé cela mais je devrais travailler (?). Une autre alternative pourrait être d'ajuster les plages de temps lors de la création des pistes AVAsset +. Bien sûr, l'exportateur ne gère que m4a (AAC). Désolé si ce n'était pas ce que vous vouliez.
-(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;
}
}];
}
La réponse ci-dessus de @Jonny est correcte. Voici que j'ajoute l'utilisation de AudioMixer pour ajouter l'effet de fondu pendant le découpage audio.
Sortie:. Support audio coupé à 20 secondes avec 10 secondes fondu en L'assiette étant mis en place dans l'extrait de code a lieu à 30 secondes marque de l'actif et donc la durée de la piste devrait être à moins 50 secondes.
- (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;}
Merci
Pour plus de détails:
https://developer.apple.com/library/ios/qa/qa1730/_index.html
Mais cette approche ne permet que le son à enregistrer dans le m4a format, ce si l'on aime couper un mp3 ou un fichier caf et garder le fo rmat? – tommys
Trim mp3 fonctionne aussi, ouput stocké au format m4a Après 2 ans, vous me sauvez encore la vie :) –