Nishant Mahajan
Nishant Mahajan

Reputation: 264

m4a audio bit rate increases after concatenate using AVAssetExportSession

I am trying to concatenate two m4a audio files from ios device library and I got success in that, here is the code I am using -

 AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
 AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
                                      initWithAsset: songAsset
                                      presetName: AVAssetExportPresetAppleM4A];
NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);
exporter.outputFileType = @"com.apple.m4a-audio";
[exporter exportAsynchronouslyWithCompletionHandler:^{}.....

When I examined these files, bit rate for original files was 16 kbps only but after AVAssetExportSession files were at 192 kbps…so it seems that the AVAssetExportSession increases the bit rate for the resultant file. Does anyone have the solution for the problem like these or is there any way to specify bit rate for the resultant file???

Upvotes: 0

Views: 1021

Answers (2)

oɹɐʎuɐſ
oɹɐʎuɐſ

Reputation: 1

Try using mp4box in the command line.

Command:

mp4box -cat 1st.m4a -cat 2nd.m4a -new D:\Joined.m4a

I haven't tried this with two m4a files having different bitrates, but with same bitrate it works.

Upvotes: 0

Gordon Childs
Gordon Childs

Reputation: 36169

Update

If you're sure the format of your AAC/m4a files is the same you could do what you want by extracting the raw AAC (aka adts) stream from the files, concatenating the raw packets, then wrapping the results back in an m4a container. This should get rid of the bitrate blowout you're seeing and still be playable.

The following file played back fine for me.

cat file1.aac file2.aac > catted.aac

Try it yourself:

afconvert -d aac file1.m4a file1.aac
afconvert -d aac file2.m4a file2.aac
cat file1.aac file2.aac > concatenated.aac
afconvert -f m4af concatenated.aac concatenated.m4a

To translate this shell script into AudioToolbox code you would do something like this

AudioFileReadPackets(/*from file1.m4a*/);  // all of the packets
AudioFileWritePackets( /* to concatenated.m4a */);
AudioFileReadPackets(/*from file2.m4a*/);  // all of the packets
AudioFileWritePackets( /* to concatenated.m4a */);

This should be fast as there is no decoding/encoding (only packet parsing) and the resulting file's bitrate will not change significantly.

Older

I think it’s odd that AVAssetExportPresetAppleM4A is changing your bit rate - my experiments left the bit rate unchanged. However I was using using a single AAC/m4a file.

If you’re using AVAssetExportSession to concatenate multiple files and export them as AAC/m4a, I don’t think you can avoid bit rate changes (what happens when the bit rates in the multiple files differ?), however choosing the resulting bit rate is another story.

As you’ve noticed AVAssetExportSession’s control over export parameters is limited to a handful of presets. For more control, I would use an AVAssetWriter. When you create your AVAssetWriterInput you have a dizzying array of options, including AVEncoderBitRateKey.

If you wanted to stay with AVAssetExportSession and only wanted a lower bit rate version of your audio you could export as AVFileTypeQuickTimeMovie with either the AVAssetExportPresetLowQuality or AVAssetExportPresetMediumQuality. Of course then you’d have a .mov file instead of m4a, but another run through AVAssetExportSession as AVFileTypeAppleM4A/AVAssetExportPresetAppleM4A would fix that. These two presets lower your bit rate by converting to mono 22 & 44.1 kHz audio, respectively. It doesn’t sound great.

Upvotes: 1

Related Questions