1

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?

vampirewalk
  • 809
  • 8
  • 18

1 Answers1

1

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:

  1. 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.

  2. 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.

Community
  • 1
  • 1
Rhythmic Fistman
  • 30,464
  • 5
  • 74
  • 138
  • I have tried streaming raw aac data to VLC, but it doesn't work. According to http://wiki.multimedia.cx/?title=Understanding_AAC , it seems I have to use ADTS or ADIF header to package AAC data. – vampirewalk Apr 23 '15 at 11:04
  • Thank you for your help. Although I achieved my goal yesterday in another way(http://stackoverflow.com/a/11600811/1060971), but the api you post here make me write cleaner code. – vampirewalk Apr 24 '15 at 06:48