Is there any way to record onto the end of an audio file? We can't just pause the recording instead of stopping it, because the user needs to be able to come back to the app later and add more audio to their recording. Currently, the audio is stored in CoreData as NSData. NSData's AppendData
does not work because the resulting audio file still reports that it is only as long as the original data.
Another possibility would be taking the original audio file, along with the new one, and concatenate them into one audio file, if there's any way to do that.
This can be done fairly easily using
AVMutableComposionTrack insertTimeRange:ofTrack:atTime:error
. The code is somewhat lengthy, but it's really just like 4 steps:You can append two audio files by creating a
AVMutableCompositionTrack
after adding the two files and exporting the composition usingexportAsynchronouslyWithCompletionHandler
method ofAVAssetExportSession
.Please refer below links for more details.
AVAssetExportSession Class Reference
Creating New Assets
Hope this helps to solve your issue.
We had the same requirements for our app as the OP described, and ran into the same issues (i.e., the recording has to be stopped, instead of paused, if the user wants to listen to what she has recorded up to that point). Our app (project's Github repo) uses
AVQueuePlayer
for playback and a method similar to kermitology's answer to concatenate the partial recordings, with some notable differences:The rationale behind the last item is that simple recordings with
AVAudioRecorder
will have one track, and the main reason for this whole workaround is to concatenate those single tracks in the assets (see Addendum 3). So why not useAVMutableComposition
'sinsertTimeRange
method instead, that takes anAVAsset
instead of anAVAssetTrack
?Relevant parts: (full code)
This diagram helped me to get around what expects what and inherited from where. (
NSObject
is implicitly implied as superclass where there is no inheritance arrow.)Addendum 1: I had my reservations regarding the
switch
part instead of using KVO onAVAssetExportSessionStatus
, but the docs are clear thatexportAsynchronously
's callback block "is invoked when writing is complete or in the event of writing failure".Addendum 2: Just in case if someone has issues with
AVQueuePlayer
: 'An AVPlayerItem cannot be associated with more than one instance of AVPlayer'Addendum 3: Unless you are recording in stereo, but mobile devices have one input as far as I know. Also, using fancy audio mixing would also require the use of
AVCompositionTrack
. A good SO thread: Proper AVAudioRecorder Settings for Recording Voice?I don't have a complete code example but the Extended Audio File Services can help you concatenate two audio files. Search for Extended Audio File Services in Xcode or visit the link below.
Apple documentation