使用ffmpeg时声音起伏

Choppy sound when using ffmpeg

本文关键字:声音 ffmpeg 使用      更新时间:2023-10-16

当我尝试从直播流中捕获音频时,我遇到了一些断断续续的音频。另一个可以解释这个问题的基本问题是,创建的Wav文件比捕获时间长两倍。

当我用ffplay播放avs输入文件时,音频是完美的,所以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);

然后使用libsndfile保存在Wav文件中:

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;
    }
}
我希望这是可以理解的。等待备注

Kurt

问题解决了。

有两个主要问题:

  • 重新调整DO添加n元素,而不仅仅是为进一步推等准备向量…
  • avcodec_decode_audio3的buff_size返回以字节为单位的长度,但在int16_t数组中复制,因此它可能会令人不安。