iPhone 中的 AAC 标头和其他信息

发布于 2024-09-05 04:41:18 字数 1779 浏览 4 评论 0原文

我正在构建一个录制声音的 iPhone 应用程序。我使用音频队列服务,一切都非常适合录音。

问题是,我正在使用 AudioFileWritePackets 进行文件写入,并且我试图将相同的“AAC + ADTS”数据包放入网络套接字。

生成的文件有所不同,因为某些“标头”或“adts 标头”可能会丢失。我正在寻找有关如何编写 ADTS 标头和/或 AAC 标头的想法?社区可以帮助我解决这个问题,或者向我推荐一份演示如何执行此操作的指南吗?

我目前有我的缓冲区处理程序方法:

void Recorder::MyInputBufferHandler(void inUserData,
    AudioQueueRefinAQ, AudioQueueBufferRefinBuffer,
    const AudioTimeStamp*inStartTime,
    UInt32 inNumPackets, 
    const AudioStreamPacketDescription*inPacketDesc) {
        AQRecorder *aqr = (AQRecorder *)inUserData;

        try {
            if (inNumPackets > 0) {
                // write packets to file
            XThrowIfError(AudioFileWritePackets(aqr->mRecordFile,
                    FALSE,
                    inBuffer->mAudioDataByteSize,
                    inPacketDesc,
                    aqr->mRecordPacket,
                    &inNumPackets,
                    inBuffer->mAudioData),
                    "AudioFileWritePackets failed");

                    fprintf(stderr, "Writing.");    

                // We write the Net Buffer.
                [aqr->socket_if writeData :(void *)(inBuffer->mAudioData)
                    :inBuffer->mAudioDataByteSize];

                aqr->mRecordPacket += inNumPackets;
            }

            // if we're not stopping, re-enqueue the buffe so that it gets filled again
            if (aqr->IsRunning()) {
            XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL),
                    "AudioQueueEnqueueBuffer failed");
            }

        } 

        catch (CAXException e) {
            char buf[256];
            fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
        }
    }

I'm building an iPhone Application that records sound. I make use of Audio Queue Services, and everything works great for the recording.

The thing is, I'm using AudioFileWritePackets for file writing, and I'm trying to put the same "AAC + ADTS" packets to a network socket.

The resulting file is different since some "headers" or "adts header" might be missing. I am searching for ideas on how to write the ADTS header and/or AAC header? Could the community assist me with this or refer me to a guide that demonstrated how to do this?

I currently have my Buffer Handler method:

void Recorder::MyInputBufferHandler(void inUserData,
    AudioQueueRefinAQ, AudioQueueBufferRefinBuffer,
    const AudioTimeStamp*inStartTime,
    UInt32 inNumPackets, 
    const AudioStreamPacketDescription*inPacketDesc) {
        AQRecorder *aqr = (AQRecorder *)inUserData;

        try {
            if (inNumPackets > 0) {
                // write packets to file
            XThrowIfError(AudioFileWritePackets(aqr->mRecordFile,
                    FALSE,
                    inBuffer->mAudioDataByteSize,
                    inPacketDesc,
                    aqr->mRecordPacket,
                    &inNumPackets,
                    inBuffer->mAudioData),
                    "AudioFileWritePackets failed");

                    fprintf(stderr, "Writing.");    

                // We write the Net Buffer.
                [aqr->socket_if writeData :(void *)(inBuffer->mAudioData)
                    :inBuffer->mAudioDataByteSize];

                aqr->mRecordPacket += inNumPackets;
            }

            // if we're not stopping, re-enqueue the buffe so that it gets filled again
            if (aqr->IsRunning()) {
            XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL),
                    "AudioQueueEnqueueBuffer failed");
            }

        } 

        catch (CAXException e) {
            char buf[256];
            fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

草莓酥 2024-09-12 04:41:18

我找到了解决方案:

我实现了回调

  XThrowIfError(
                  AudioFileInitializeWithCallbacks(
                                                   this,
                                                   nil,
                                                   BufferFilled_callback,
                                                   nil,
                                                   nil,
                                                   //kAudioFileCAFType,
                                                   kAudioFileAAC_ADTSType,
                                                   &mRecordFormat,
                                                   kAudioFileFlags_EraseFile,
                                                   &mRecordFile),
                  "InitializeWithCallbacks failed");

......瞧!您必须实现的真正回调是 BufferFilled_callback。这是我的实现:

OSStatus AQRecorder::BufferFilled_callback(
                                           void *                               inUserData,
                                           SInt64                               inPosition,
                                           UInt32                               requestCount,
                                           const void *                         buffer,
                                           UInt32 *                             actualCount) {

    AQRecorder *aqr = (AQRecorder *)inUserData;

    // You can write these bytes to anywhere. 
    // You can build a streaming server 

    return 0;
}

如果您想了解更多有关音频队列服务的信息,您可以从 iPhone 版 Flipzu 获得一些想法(前直播音频应用程序 // 我们必须关闭它,因为我们无法筹集资金)。

https://github.com/lucaslain/Flipzu_iPhone

最好,

卢卡斯。

I've found the solution for this:

I implemented the callback

  XThrowIfError(
                  AudioFileInitializeWithCallbacks(
                                                   this,
                                                   nil,
                                                   BufferFilled_callback,
                                                   nil,
                                                   nil,
                                                   //kAudioFileCAFType,
                                                   kAudioFileAAC_ADTSType,
                                                   &mRecordFormat,
                                                   kAudioFileFlags_EraseFile,
                                                   &mRecordFile),
                  "InitializeWithCallbacks failed");

... And voilá! The real callback you have to implement is BufferFilled_callback. Here is my implementation:

OSStatus AQRecorder::BufferFilled_callback(
                                           void *                               inUserData,
                                           SInt64                               inPosition,
                                           UInt32                               requestCount,
                                           const void *                         buffer,
                                           UInt32 *                             actualCount) {

    AQRecorder *aqr = (AQRecorder *)inUserData;

    // You can write these bytes to anywhere. 
    // You can build a streaming server 

    return 0;
}

If you want to see more about audio queue services, you can get some ideas from Flipzu for iPhone (ex-app for live broadcasting audio // we have to shut it down because we could not raise money).

https://github.com/lucaslain/Flipzu_iPhone

Best,

Lucas.

过期情话 2024-09-12 04:41:18

我最近在 iLBC 编解码器上遇到了这个问题,并得出了如下解决方案:

录制所需的音频数据并将其写入文件。然后,获取该文件并对其进行八进制转储。您可以使用 -c 标志来查看 ascii 字符。

然后,创建一个您知道不包含标头的单独文件。这只是音频队列缓冲区中的数据。八进制转储,然后比较。

由此,您应该拥有标题和有关如何继续的足够信息。希望这有帮助。

I've recently encountered this issue with the iLBC codec, and arrived at the solution as follows:

Record the audio data you want and just write it to a file. Then, take that file and do an octal dump on it. You can use the -c flag to see ascii characters.

Then, create a separate file that you know doesn't contain the header. This is just your data from the buffers on the audio queue. Octal dump that, and compare.

From this, you should have the header and enough info on how to proceed. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文