Iphone Потоковая передача и воспроизведение аудио Проблема - PullRequest
1 голос
/ 09 августа 2011

Я пытаюсь создать приложение, которое воспроизводит аудиопоток, используя ffmpeg, libmms.
Я могу открыть сервер mms, получить поток и декодировать аудиофрейм в необработанный кадр, используя подходящий кодек.
Однако я неЯ знаю, что делать дальше.
Я думаю, что я должен использовать AudioToolbox/AudioToolbox.h и сделать аудио-очередь.
, но, тем не менее, когда я даю память буфера декодирования аудио-буфера-декодера и играю, только воспроизводит белый шум.
Вот мой код.

Что мне не хватает?
Любые комментарии и подсказки очень ценятся.
Большое спасибо.

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);
}

1 Ответ

1 голос
/ 20 августа 2011

Вы неправильно вызвали AQOutputCallback. Вам не нужно обязательно вызывать этот метод.
Этот метод будет вызываться автоматически, когда аудио-буферы используются аудио-очередью. И прототип AQOutputCallback был неверным.
В соответствии с вашим кодом, я думаю, этот метод не будет вызываться автоматически.
Вы можете переопределить

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

как это

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

И вы должны установить Audio Session, когда ваше приложение запускается.
Важные ссылки здесь .

Однако, Какое расширение аудио вы хотите декодировать?
AudioStreamPacketDescription важно, если аудио представляет собой переменный кадр на пакет.
В противном случае, если один кадр на один пакет, AudioStreamPacketDescription не имеет значения.

Что вы делаете дальше
Чтобы установить аудио сеанс, Чтобы получить необработанный аудио кадр с помощью декодера, Чтобы поместить кадр в аудио буфер.
Вместо вас, заставьте систему заполнять пустой буфер.

...