Objective
Reading m4a
file bought from iTunes Store via AVAssetReader
.
Stream via HTTP
and consumed by MobileVLCKit
.
What I've tried
As far as I know, AVAssetReader
only generates audio raw data, so I guess I should add ADTS header in front of every sample.
NSError *error = nil;
AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
if (error != nil) {
NSLog(@"%@", [error localizedDescription]);
return -1;
}
AVAssetTrack* track = [asset.tracks objectAtIndex:0];
AVAssetReaderTrackOutput *readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track
outputSettings:nil];
[reader addOutput:readerOutput];
[reader startReading];
while (reader.status == AVAssetReaderStatusReading){
AVAssetReaderTrackOutput * trackOutput = (AVAssetReaderTrackOutput *)[reader.outputs objectAtIndex:0];
CMSampleBufferRef sampleBufferRef;
@synchronized(self) {
sampleBufferRef = [trackOutput copyNextSampleBuffer];
}
CMItemCount = CMSampleBufferGetNumSamples(sampleBufferRef);
...
}
So, my question is, how do I loop every sample and add ADTS header?
First, you don't need trackOutput
, it's the same as readerOutput
that you already have.
UPDATE
My mistake, you're absolutely right. I thought the usual 0xFFF
sync words were part of AAC, instead they're ADTS headers. So you must add an ADTS header to each of your AAC packets to stream them as ADTS or "aac". I think you have two choices:
Use AudioFileInitializeWithCallbacks
+ kAudioFileAAC_ADTSType
to get the AudioFile
API to add the headers for you. You write AAC packets to the AudioFileID
and it will call your write callback from where you can stream AAC in ADTS.
Add the headers to the packets yourself. They're only 7 fiddly bytes (9 with checksums, but who uses them?). Some readable implementations here and here
Either way you need to call either CMSampleBufferGetAudioStreamPacketDescriptions
or CMSampleBufferCallBlockForEachSample
to get the individual AAC packets from a CMSampleBufferRef
.