Прерывистый звук при использовании ffmpeg - PullRequest
0 голосов
/ 21 ноября 2011

Я пострадала от прерывистого звука, когда пыталась захватить звук из прямой трансляции.Другая существенная проблема, которая может объяснить проблему, состоит в том, что созданный файл Wav в два раза длиннее, чем время захвата.

Звук идеально подходит, когда я воспроизводю входной файл AVS с помощью ffplay, поэтому с AVS все в порядке, проблемапосле или в записи или в записи WAV.

Для захвата:

av_read_frame(pFormatCtx, &packet)

if(packet.stream_index == mAudioStream)
{
    int buff_size = sizeof(mAudioBuffer);
    std::cout << "Buff_size " << buff_size << std::endl;
    len = avcodec_decode_audio3(pAudioCodecCtx,(int16_t*)mAudioBuffer, &buff_size,&packet);
    if(len < 0){
        qDebug("Extractor - Audio isEnd = -1;");
        mAudioBufferSize = 0;
        isEnd = ERROR_;
        return isEnd;
    }

    // Set packet result type
    mFrameType = AUDIO_PKT;
    mAudioBufferSize = buff_size;
    //store audio synchronization informations:
    if(packet.pts != AV_NOPTS_VALUE) {
         mAudioPts_ = av_q2d(pFormatCtx->streams[mAudioStream]->time_base);
         mAudioPts_ *= packet.pts;
    }
}

        // store a copy of current audio frame in _frame
        _frame.audioFrame = new decoded_frame_t::audio_frame_t();
        _frame.audioFrame->sampleRate = mediaInfos.audioSampleRate;
        _frame.audioFrame->sampleSize = mediaInfos.audioSampleSize;
        _frame.audioFrame->nbChannels = mediaInfos.audioNbChannels;
        _frame.audioFrame->nbSamples = mAudioBufferSize / ((mediaInfos.audioSampleSize/8) * mediaInfos.audioNbChannels);
        _frame.audioFrame->buf.resize(mAudioBufferSize);
        memcpy(&_frame.audioFrame->buf[0],mAudioBuffer,mAudioBufferSize);

Затем я сохраняю в файле Wav, используя libsndfile:

SNDFILE*            fd;
SF_INFO             sfInf;

sfInf.frames = 0;
sfInf.channels = p_capt->ui_nbChannels;
sfInf.samplerate = p_capt->ui_sampleRate;
sfInf.format = SF_FORMAT_WAV | SF_FORMAT_PCM_U8;
sfInf.sections = 0;
sfInf.seekable = 0;

if (sf_format_check(&sfInf) == FALSE)
    std::cout << "Format parameter are uncorrect ! Exit saving !" << std::endl;
else
{
    fd = sf_open(fileName.toStdString().c_str(), SFM_WRITE, &sfInf);
    if (fd == NULL)
    {
        std::cout << "Unable to open the file " << fileName.toStdString() << std::endl;
        return GRAB_ST_NOK;
    }

    //little trick because v_buf is a uint8_t vector
    sf_count_t l = sf_write_short(fd, (const short *)(&(p_capt->v_buf[0])), p_capt->v_buf.size()/2);

    if (l != p_capt->v_buf.size()/2)
    {
       std::cout << "sf_write didn't write the right amoung of bits " << l << " != " << p_capt->v_buf.size()/2 << std::endl;
       ret = GRAB_ST_NOK;
    }
    else
    {
        sf_write_sync(fd);
        sf_close(fd);
        ret = GRAB_ST_OK;
    }
}

Iнадеюсь, это понятно.Жду замечаний.

Курт

1 Ответ

0 голосов
/ 24 ноября 2011

Хорошо, проблема решена.

Были две основные проблемы:

  • изменить размер DO добавить n элемент, а не просто подготовить вектор для дальнейшего нажатия и т. Д.
  • значение buff_size для avcodec_decode_audio3 возвращает длину в байтах, но копирует в массив int16_t, поэтому это может вызывать помехи.
...