1

我正在尝试制作一个使用 ffmpeg、libmms 播放音频流的应用程序。
我可以使用合适的编解码器打开 mms 服务器、获取流和将音频帧解码为原始帧。
但是我不知道下一步该怎么做。
我想我必须使用AudioToolbox/AudioToolbox.h和制作音频队列。
但是当我给audioqueuebuffer解码缓冲区的内存和播放时,只播放白噪声。
这是我的代码。

我错过了什么?
非常感谢任何评论和提示。
非常感谢。

while(av_read_frame(pFormatCtx, &pkt)>=0)
{
    int pkt_decoded_len = 0;
    int frame_decoded_len;
    int decode_buff_remain=AVCODEC_MAX_AUDIO_FRAME_SIZE * 5;
    if(pkt.stream_index==audiostream)
    {
        frame_decoded_len=decode_buff_remain;
        int16_t *decode_buff_ptr = decode_buffer;
        int decoded_tot_len=0;
        pkt_decoded_len = avcodec_decode_audio2(pCodecCtx, decode_buff_ptr, &frame_decoded_len,
                                                pkt.data, pkt.size);
        if (pkt_decoded_len <0) break;
        AudioQueueAllocateBuffer(audioQueue, kBufferSize, &buffers[i]);
        AQOutputCallback(self, audioQueue, buffers[i], pkt_decoded_len);

        if(i == 1){
            AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 1.0);
            AudioQueueStart(audioQueue, NULL);
        }
        i++;
    }
}


void AQOutputCallback(void *inData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, int copySize)
{
    mmsDemoViewController *staticApp = (mmsDemoViewController *)inData;
    [staticApp handleBufferCompleteForQueue:inAQ buffer:inBuffer size:copySize];
}

- (void)handleBufferCompleteForQueue:(AudioQueueRef)inAQ
                          buffer:(AudioQueueBufferRef)inBuffer
                            size:(int)copySize
{
    inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
    memcpy((char*)inBuffer->mAudioData, (const char*)decode_buffer, copySize);

    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
4

1 回答 1

1

您错误地调用了 AQOutputCallback。您不必调用该方法。
当音频队列使用音频缓冲区时,将自动调用该方法。而且 AQOutputCallback 的原型是错误的。
根据您的代码,我认为不会自动调用该方法。
你可以覆盖

typedef void (*AudioQueueOutputCallback) (
   void                 *inUserData,
   AudioQueueRef        inAQ,
   AudioQueueBufferRef  inBuffer
);

像这样

void AudioQueueCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef 
                       inBuffer);

您应该在应用启动时设置音频会话。
重要的参考资料在这里。

但是,您愿意解码的音频扩展是什么?
AudioStreamPacketDescription如果音频是每个数据包的可变帧,则这一点很重要。
否则,如果每包一帧,AudioStreamPacketDescription则不重要。

你接下来要做的是
设置音频会话,使用解码器获取原始音频帧,将帧放入音频缓冲区。
而不是你,让系统填充空缓冲区。

于 2011-08-20T06:30:53.167 回答