2011-01-10 11 views
7

C'è un modo per registrare alla fine di un file audio? Non possiamo semplicemente sospendere la registrazione invece di fermarla, perché l'utente deve essere in grado di tornare in seguito all'app e aggiungere altro audio alla propria registrazione. Attualmente, l'audio è memorizzato in CoreData come NSData. L'AppendData di NSData non funziona perché il file audio risultante riporta ancora che è lungo solo quanto i dati originali.AVAudioRecorder/AVAudioPlayer - aggiungi registrazione al file

Un'altra possibilità sarebbe quella di prendere il file audio originale, insieme a quello nuovo, e concatenarli in un unico file audio, se c'è un modo per farlo.

+0

Dai un'occhiata al mio codice qui sotto. Questo è quello che sto usando in un'app di produzione. – memmons

+0

È possibile trovare il mio codice completo per mearging: https://stackoverflow.com/a/49136633/2244094 –

risposta

1

Non ho un esempio di codice completo ma i servizi di file audio estesi possono aiutarti a concatenare due file audio. Cerca Extended Audio File Services in Xcode o visita il link sottostante.

Apple documentation

+0

Nulla in quella documentazione fa riferimento all'aggiunta di file audio. – memmons

+0

per essere onesti questo è un ref interessante, e funziona anche se non vuoi concatenare file pronti, ma vuoi scrivere su file esistenti, ed è fantastico (come nel registratore di mele!) – KostiaZzz

4

È possibile aggiungere due file audio con la creazione di un AVMutableCompositionTrack dopo aver aggiunto i due file ed esportare la composizione utilizzando exportAsynchronouslyWithCompletionHandler metodo AVAssetExportSession.

Fare riferimento ai collegamenti seguenti per ulteriori dettagli.

AVAssetExportSession Class Reference

Creating New Assets

Spero che questo aiuti a risolvere il problema.

+0

Questa risposta, sebbene non completamente completa, sicuramente mi ha messo sulla strada giusta quando mi è venuta in mente questo stesso problema. – kermitology

+0

Ho aggiunto il codice completo di seguito, ma è stata questa risposta che mi ha indirizzato nella giusta direzione. – memmons

+0

@siddharth Dove hai ricevuto la documentazione @ disanji.net? Sembra una copia dei documenti Apple, ma non vedo quella sezione nei documenti ufficiali Apple. – memmons

6

Questo può essere fatto abbastanza facilmente utilizzando AVMutableComposionTrack insertTimeRange:ofTrack:atTime:error. Il codice è piuttosto lungo, ma in realtà è solo come 4 passaggi:

// Create a new audio track we can append to 
AVMutableComposition* composition = [AVMutableComposition composition]; 
AVMutableCompositionTrack* appendedAudioTrack = 
    [composition addMutableTrackWithMediaType:AVMediaTypeAudio 
          preferredTrackID:kCMPersistentTrackID_Invalid]; 

// Grab the two audio tracks that need to be appended 
AVURLAsset* originalAsset = [[AVURLAsset alloc] 
    initWithURL:[NSURL fileURLWithPath:originalAudioPath] options:nil]; 
AVURLAsset* newAsset = [[AVURLAsset alloc] 
    initWithURL:[NSURL fileURLWithPath:newAudioPath] options:nil]; 

NSError* error = nil; 

// Grab the first audio track and insert it into our appendedAudioTrack 
AVAssetTrack *originalTrack = [originalAsset tracksWithMediaType:AVMediaTypeAudio]; 
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, originalAsset.duration); 
[appendedAudioTrack insertTimeRange:timeRange 
          ofTrack:[originalTrack objectAtIndex:0] 
          atTime:kCMTimeZero 
           error:&error]; 
if (error) 
{ 
    // do something 
    return; 
} 

// Grab the second audio track and insert it at the end of the first one 
AVAssetTrack *newTrack = [newAsset tracksWithMediaType:AVMediaTypeAudio]; 
timeRange = CMTimeRangeMake(kCMTimeZero, newAsset.duration); 
[appendedAudioTrack insertTimeRange:timeRange 
          ofTrack:[newTrack objectAtIndex:0] 
          atTime:originalAsset.duration 
           error:&error]; 

if (error) 
{ 
    // do something 
    return; 
} 

// Create a new audio file using the appendedAudioTrack  
AVAssetExportSession* exportSession = [AVAssetExportSession 
             exportSessionWithAsset:composition 
             presetName:AVAssetExportPresetAppleM4A]; 
if (!exportSession) 
{ 
    // do something 
    return; 
} 


NSString* appendedAudioPath= @""; // make sure to fill this value in  
exportSession.outputURL = [NSURL fileURLWithPath:appendedAudioPath]; 
exportSession.outputFileType = AVFileTypeAppleM4A; 
[exportSession exportAsynchronouslyWithCompletionHandler:^{ 

    // exported successfully? 
    switch (exportSession.status) 
    { 
     case AVAssetExportSessionStatusFailed: 
      break; 
     case AVAssetExportSessionStatusCompleted: 
      // you should now have the appended audio file 
      break; 
     case AVAssetExportSessionStatusWaiting: 
      break; 
     default: 
      break; 
    } 
    NSError* error = nil; 

}];