Concatenate Two Audio Files in Swift and Play Them

Concatenate two audio files in Swift and play them

I got your code working by changing two things:

  • the preset name: from AVAssetExportPresetPassthrough to AVAssetExportPresetAppleM4A

  • the output file type: from AVFileTypeWAVE to AVFileTypeAppleM4A

Modify your assetExport declaration like this:

var assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)
assetExport.outputFileType = AVFileTypeAppleM4A

then it will properly merge the files.

It looks like AVAssetExportSession only exports M4A format and ignores other presets. There may be a way to make it export other formats (by subclassing it?), though I haven't explored this possibility yet.

append or concatenate audio files in swift

If you are looking to simply pause your recording and continue it later you can use AVAudioRecorder's pause() function rather than stop() and it will continue the recording when you use play() again.

However, if you are looking to actually concatenate audio files, you can do it like this:

func concatenateFiles(audioFiles: [NSURL], completion: (concatenatedFile: NSURL?) -> ()) {
guard audioFiles.count > 0 else {
completion(concatenatedFile: nil)
return
}

if audioFiles.count == 1 {
completion(concatenatedFile: audioFiles.first)
return
}

// Concatenate audio files into one file
var nextClipStartTime = kCMTimeZero
let composition = AVMutableComposition()
let track = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)

// Add each track
for recording in audioFiles {
let asset = AVURLAsset(URL: NSURL(fileURLWithPath: recording.path!), options: nil)
if let assetTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first {
let timeRange = CMTimeRange(start: kCMTimeZero, duration: asset.duration)
do {
try track.insertTimeRange(timeRange, ofTrack: assetTrack, atTime: nextClipStartTime)
nextClipStartTime = CMTimeAdd(nextClipStartTime, timeRange.duration)
} catch {
print("Error concatenating file - \(error)")
completion(concatenatedFile: nil)
return
}
}
}

// Export the new file
if let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough) {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documents = NSURL(string: paths.first!)

if let fileURL = documents?.URLByAppendingPathComponent("file_name.caf") {
// Remove existing file
do {
try NSFileManager.defaultManager().removeItemAtPath(fileURL.path!)
print("Removed \(fileURL)")
} catch {
print("Could not remove file - \(error)")
}

// Configure export session output
exportSession.outputURL = NSURL.fileURLWithPath(fileURL.path!)
exportSession.outputFileType = AVFileTypeCoreAudioFormat

// Perform the export
exportSession.exportAsynchronouslyWithCompletionHandler() { handler -> Void in
if exportSession.status == .Completed {
print("Export complete")
dispatch_async(dispatch_get_main_queue(), {
completion(file: fileURL)
})
return
} else if exportSession.status == .Failed {
print("Export failed - \(exportSession.error)")
}

completion(concatenatedFile: nil)
return
}
}
}
}

Concat two audio files (one after another) in iOS

After doing much research I found answer.. It works..

- (void)mergeTwoAudioFiles{
AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test1" ofType:@"m4a"]] options:nil];
AVAsset *avAsset2 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test2" ofType:@"m4a"]] options:nil];

AVMutableComposition *composition = [[AVMutableComposition alloc] init];
[composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *assetTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVAssetTrack *assetTrack2 = [[avAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

CMTime insertionPoint = kCMTimeZero;
[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset1.duration) ofTrack:assetTrack1 atTime:insertionPoint error:nil];
insertionPoint = CMTimeAdd(insertionPoint, avAsset1.duration);
[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset2.duration) ofTrack:assetTrack2 atTime:insertionPoint error:nil];

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetAppleM4A];
exportSession.outputURL = [NSURL fileURLWithPath:[@"test3.m4a" documentDirectory]];
exportSession.outputFileType = AVFileTypeAppleM4A;

[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (AVAssetExportSessionStatusCompleted == exportSession.status) {
NSLog(@"AVAssetExportSessionStatusCompleted");
} else if (AVAssetExportSessionStatusFailed == exportSession.status) {
NSLog(@"AVAssetExportSessionStatusFailed");
} else {
NSLog(@"Export Session Status: %ld", (long)exportSession.status);
}
}];
}

How to merge two audio files using iPhone SDK?

OPTION-1:

Refer to this link:

Join multiple audio files into one

Answer of invalidname in that post says:

MP3 is a stream format, meaning it doesn't have a bunch of metadata at
the front or end of the file. While this has a lot of downsides, one
of the upsides is that you can concatenate MP3 files together into a
single file and it'll play.

This is pretty much what you're doing by concatenating into an
NSMutableData, the downside of which is that you might run out of
memory. Another option would be to build up the file on disk with
NSFileHandle.

This doesn't work for most file formats (aac/m4a, aif, caf, etc.). MP3
is literally just a stream dumped to disk, with metadata in frame
headers (or, in ID3, tucked between frames), so that's why it works.

OPTION-2:

combine two .caf audio files into a single audio file in iphone

Answer by Midhere in this post:

You can do it using ExtAudioFileService. In ios developer library they
had provided two examples to convert one audio file to another format.
In these they are opening one audio file for reading and another file
for writing (converted audio). You can change or updated code to read
from two files and write them to one out put file in same format(caf)
or compressed format. First you have open first audio file and read
every packets from it and write it to a new audio file. After
finishing first audio file, close the file and open second audio file
for reading. Now read every packets from second audio file and write
to newly created audio file and close second audio file and new audio
file.

Please find the links(1,2) for these sample codes ....
Hope this helps you...and good luck. :)

So try and convert it to another format and then try combining it.

OPTION-3:

Refer to:

Joining two CAF files together

Answer by dineth in this post:

If anyone is keen to know the answer, there is a way to do it. You
have to use the AudioFiles API calls. Basically, you'd:

create a new audio file using AudioFileCreate with the correct
parameters (bitrate etc). open your first file, read the packets and
write them to the newly created file. open your second file and do the
same. make sure your counters are not zero-ed out after writing the
first file. AudioFileClose -- and you're done! Things to note: for
local files, you have to run a method to escape spaces

That's about it!

OPTION-4:

Slightly in a different note.

I think you are recording files in CAF and trying to combine them.So in that case you can finally try recording your files in some other format than caf.

Try out this link for that:

iOS: Record audio in other format than caf

Hope this helps.

Merge two videos with audio and video together in iOS

The problem is that you are adding a second video track to the composition. You need to insert both videos into the same video track. Just delete your let videoTrack2 and go from there.



Related Topics



Leave a reply



Submit