Can I use AVCaptureSession to encode an AAC stream to memory?

只谈情不闲聊 提交于 2019-12-02 17:21:31
Avner

I ended up asking Apple for advice (it turns out you can do that if you have a paid developer account).

It seems that AVCaptureSession grabs a hold of the AAC hardware encoder but only lets you use it to write directly to file.

You can use the software encoder but you have to ask for it specifically instead of using AudioConverterNew:

AudioClassDescription *description = [self
        getAudioClassDescriptionWithType:kAudioFormatMPEG4AAC
                        fromManufacturer:kAppleSoftwareAudioCodecManufacturer];
if (!description) {
    return false;
}
// see the question as for setting up pcmASBD and arc ASBD
OSStatus st = AudioConverterNewSpecific(&pcmASBD, &aacASBD, 1, description, &_converter);
if (st) {
    NSLog(@"error creating audio converter: %s", OSSTATUS(st));
    return false;
}

with

- (AudioClassDescription *)getAudioClassDescriptionWithType:(UInt32)type
                                           fromManufacturer:(UInt32)manufacturer
{
    static AudioClassDescription desc;

    UInt32 encoderSpecifier = type;
    OSStatus st;

    UInt32 size;
    st = AudioFormatGetPropertyInfo(kAudioFormatProperty_Encoders,
                                    sizeof(encoderSpecifier),
                                    &encoderSpecifier,
                                    &size);
    if (st) {
        NSLog(@"error getting audio format propery info: %s", OSSTATUS(st));
        return nil;
    }

    unsigned int count = size / sizeof(AudioClassDescription);
    AudioClassDescription descriptions[count];
    st = AudioFormatGetProperty(kAudioFormatProperty_Encoders,
                                sizeof(encoderSpecifier),
                                &encoderSpecifier,
                                &size,
                                descriptions);
    if (st) {
        NSLog(@"error getting audio format propery: %s", OSSTATUS(st));
        return nil;
    }

    for (unsigned int i = 0; i < count; i++) {
        if ((type == descriptions[i].mSubType) &&
            (manufacturer == descriptions[i].mManufacturer)) {
            memcpy(&desc, &(descriptions[i]), sizeof(desc));
            return &desc;
        }
    }

    return nil;
}

The software encoder will take up CPU resources, of course, but will get the job done.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!