1

ffmpeg、libmms を使用してオーディオ ストリームを再生するアプリを作成しようとしています。
mms サーバーを開き、ストリームを取得し、適切なコーデックを使用してオーディオ フレームを生のフレームにデコードできます。
ただし、次にどうすればよいかわかりません。
私はAudioToolbox/AudioToolbox.haudioqueue を使用して作成する必要があると思います。
ただし、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オーディオがパケットごとの可変フレームである場合、これは重要です。
それ以外の場合、1 フレームあたり 1 パケットは重要でAudioStreamPacketDescriptionはありません。

次に行うことは
、オーディオ セッションを設定すること、デコーダを使用して生のオーディオ フレームを取得すること、フレームをオーディオ バッファに入れることです。
あなたの代わりに、空のバッファを埋めるシステムを作ってください。

于 2011-08-20T06:30:53.167 に答える