Audio 使用ffmpeg将音频数据包写入文件

Audio 使用ffmpeg将音频数据包写入文件,audio,ffmpeg,libavcodec,libavformat,Audio,Ffmpeg,Libavcodec,Libavformat,我正在尝试使用ffmpeg将音频数据包写入文件。在一段时间间隔后发送数据包的源设备。e、 g First packet has a time stamp 00:00:00 Second packet has a time stamp 00:00:00.5000000 Third packet has a time stamp 00:00:01 And so on... 表示每秒两个数据包 我想对这些数据包进行编码并写入文件 我指的是链接中的Ffmpeg示例 编码和写入时没有错误。但输出文件只

我正在尝试使用ffmpeg将音频数据包写入文件。在一段时间间隔后发送数据包的源设备。e、 g

First packet has a time stamp 00:00:00 
Second packet has a time stamp 00:00:00.5000000
Third packet has a time stamp 00:00:01
And so on...
表示每秒两个数据包

我想对这些数据包进行编码并写入文件

我指的是链接中的Ffmpeg示例

编码和写入时没有错误。但输出文件只有2秒的音频持续时间,速度也非常快

根据设置,视频帧是正确的

我认为问题与pts、dts和数据包持续时间的计算有关

我应该如何计算pts、dts和持续时间的适当值。或者这个问题与其他事情有关

代码:

void AudioWriter::WriteAudioChunk(IntPtr chunk、int lenght、TimeSpan时间戳)
{
int buffer_size=av_samples_get_buffer_size(NULL,输出流->tmp_帧->通道,输出流->tmp_帧->nb_samples,输出流->音频流->编解码器->样本_fmt,0);
uint8_t*audioData=重新解释转换(静态转换(块));
int-ret=avcodec\u fill\u audio\u frame(outputStream->tmp\u frame,outputStream->Channels,outputStream->AudioStream->codec->sample\u fmt,audioData,buffer\u size,1);
如果(!ret)
抛出gcnew System::IO::IOException(“尚未打开音频文件”);
写入音频帧(outputStream->FormatContext、outputStream、audioData);
}
静态整数写入音频帧(AVFormatContext*oc、AudioWriterData^ost、uint8\u t*audioData)
{
avc*c;
AVPacket pkt={0};
int ret;
int-got_包;
int dst_nb_样本;
av_初始_数据包(&pkt);
c=ost->音频流->编解码器;
AVFrame*frame=ost->tmp\U帧;
如果(帧)
{
dst_nbu_samples=av_rescale(swr_get_delay(ost->swr_ctx,c->sample_rate)+帧->nbu samples,c->sample_rate,c->sample_rate,av_ROUND UP);
如果(dst_nb_样本!=帧->nb_样本)
抛出gcnew异常(“dst_nb_samples!=frame->nb_samples”);
ret=av\U帧\U使其可写(ost->AudioFrame);
如果(ret<0)
抛出新异常(“无法使其可写”);
ret=swr_转换(ost->swr_ctx,ost->AudioFrame->data,dst_nb_样本,(const uint8_t**)frame->data,frame->nb_样本);
如果(ret<0)
抛出新异常(“无法转换为目标格式”);
frame=ost->AudioFrame;
AVRational timebase={1,c->sample_rate};
帧->pts=av\u rescale\u q(ost->samples\u count,timebase,c->timebase);
ost->samples_count+=dst_nb_samples;
}
ret=avcodec\U encode\U AUDIO 2(c、pkt、帧和got\U数据包);
如果(ret<0)
抛出新异常(“错误编码音频帧”);
如果(得到_数据包)
{
ret=写入帧(oc,&c->时基、ost->音频流和pkt);
如果(ret<0)
抛出新异常(“未写入音频”);
}
其他的
抛出新异常(“音频数据包编码失败”);
返回(ost->AudioFrame | | got|u数据包)?0:1;
}
静态整数写入帧(AVFormatContext*fmt\u ctx,const AVRational*time\u base,AVStream*st,AVPacket*pkt)
{
av_数据包重新缩放(pkt,*时基,st->时基);
pkt->stream_index=st->index;
返回av_交织_写入_帧(fmt_ctx,pkt);
}

pts/dts计算不正确或某个时基错误。我建议在
avcodec\u encode\u audio2
之后添加一些调试日志以查看pts和编码数据包的时基,然后在av\u交错\u write\u帧之前再次添加(在该示例中已经有该位置的日志)。@AndreyTurkin No sir pts和dts是相同的。而时基也和AVStream和AVCodecContext相同,即{144100}。pts/dts每帧增加22050,对吗?另外,我正在查看示例代码,其中有swresample。可能是配置不正确,这样做。。。你能分享你的源代码吗?@AndreyTurkin No sir的pts和dts增加了1152。添加了有问题的代码示例。很抱歉,rply太晚了。
lenght
参数没有在任何地方使用-这是这里的大问题。您必须使用所有输入数据。但您还需要将重新采样的音频分成块,每个块的长度与编解码器要求的长度完全相同。理想情况下,您还应该使用
timestamp
参数作为
pts
的源(这有时允许处理音频数据中的间隙),但随后您需要估计每个输出块的时间戳,考虑重采样延迟,通过像现在一样计数样本来修复小的抖动,etc-这有点像PITA。不是pts/dts计算错误,就是其中一个时基错误。我建议在
avcodec\u encode\u audio2
之后添加一些调试日志以查看pts和编码数据包的时基,然后在av\u交错\u write\u帧之前再次添加(在该示例中已经有该位置的日志)。@AndreyTurkin No sir pts和dts是相同的。而时基也和AVStream和AVCodecContext相同,即{144100}。pts/dts每帧增加22050,对吗?另外,我正在查看示例代码,其中有swresample。可能是配置不正确,这样做。。。你能分享你的源代码吗?@AndreyTurkin No sir的pts和dts增加了1152。添加了有问题的代码示例。很抱歉,rply太晚了。
lenght
参数没有在任何地方使用-这是这里的大问题。您必须使用所有输入数据。但您还需要将重新采样的音频分成块,每个块的长度与编解码器要求的长度完全相同。理想情况下,您还应该使用
timestamp
参数作为
pts
的源(这有时允许处理音频数据中的间隙),但随后您需要估计每个输出块的时间戳,考虑重采样延迟,通过像现在这样计数样本来修复小的抖动,等等-这有点像PITA。