Qt+FFmpeg用代码实现
ffmpeg -i "rtsp://username:password@example.com/stream" -vn -acodec aac -ar 44100 -b:a 128k output.mp4
Qt+FFmpeg用代码实现
ffmpeg -i "rtsp://username:password@example.com/stream" -vn -acodec aac -ar 44100 -b:a 128k output.mp4
Qt+FFmpeg用代码实现
ffmpeg -i "rtsp://username:password@example.com/stream" -vn -acodec aac -ar 44100 -b:a 128k output.mp4
以下代码报错:[aac @ 0000014f803ab640] Input contains (near) NaN/+-Inf
EncodeFrame = av_frame_alloc();
EncodePacket = av_packet_alloc();
InputFrame = av_frame_alloc();
OutputPacket = av_packet_alloc();
//初始化转码结构体AVFrame
av_channel_layout_default(&EncodeFrame->ch_layout,OutAudioCodecContext->ch_layout.nb_channels);
EncodeFrame->nb_samples = OutAudioCodecContext->frame_size;
EncodeFrame->sample_rate = OutAudioCodecContext->sample_rate;
//EncodeFrame->ch_layout = OutAudioCodecContext->ch_layout;
EncodeFrame->format = OutAudioCodecContext->sample_fmt;
EncodeFrame->nb_samples = 1024;
if(av_frame_get_buffer(EncodeFrame,0)<0){
qDebug()<<"实例化转码结构体EncodeFrame失败";
}
//初始化AVAudioFifo
EncodeAudioFifo = av_audio_fifo_alloc(OutAudioCodecContext->sample_fmt,OutAudioCodecContext->ch_layout.nb_channels,OutAudioCodecContext->frame_size);
if(!EncodeAudioFifo){
qDebug()<<"初始化AVAudioFifo失败";
return false;
}
//循环编解码
while (m_statue) {
//读取帧
if(av_read_frame(InputFormatContext,EncodePacket)<0){
qDebug()<<"读取帧失败";
m_statue = false;
break;
}
//音频从PCM_ALAW转为AAC格式
if(EncodePacket->stream_index == AudioIndex){
//发送音频解析包
ret = avcodec_send_packet(InputAudioCodecContext,EncodePacket);
if(ret < 0){
qDebug()<<"发送音频解析包失败";
m_statue = false;
break;
}
while (ret >= 0) {
ret = avcodec_receive_frame(InputAudioCodecContext,InputFrame);
if(ret == AVERROR_EOF || ret == AVERROR(EAGAIN)){
break;
}else if(ret < 0){
m_statue = false;
break;
}else {
//获取AVAudioFifo的大小
int FifoSize = av_audio_fifo_size(EncodeAudioFifo);
qDebug()<<"当前FIFO大小"<<FifoSize;
//重新分配AVAudioFifo的大小
av_audio_fifo_realloc(EncodeAudioFifo,FifoSize + InputFrame->nb_samples);
//判断AVAudioFifo的空间是否充足
int space = av_audio_fifo_space(EncodeAudioFifo);
if(space < InputFrame->nb_samples){
qDebug()<<"空间不足"<<space<<InputFrame->nb_samples;
}
//将其写入到AVAudioFifo
ret = av_audio_fifo_write(EncodeAudioFifo,reinterpret_cast<void **>(InputFrame->data) ,InputFrame->nb_samples);
if(ret < 0){
qDebug()<<"写入缓冲区失败";
}
//设置变量EncodeFrame可以被写入
av_frame_make_writable(EncodeFrame);
while (av_audio_fifo_size(EncodeAudioFifo) > OutAudioCodecContext->frame_size) {
qDebug()<<"FIFO缓存数据大小"<<av_audio_fifo_size(EncodeAudioFifo)<<"解码器大小"<<OutAudioCodecContext->frame_size;
ret = av_audio_fifo_read(EncodeAudioFifo,reinterpret_cast<void**>(EncodeFrame->data),OutAudioCodecContext->frame_size);
if(ret < OutAudioCodecContext->frame_size){
qDebug()<<"读取帧失败";
m_statue = false;
break;
}
//重新定义时间戳
EncodeDts += EncodeFrame->nb_samples;
EncodeFrame->pts = EncodeDts;
ret = avcodec_send_frame(OutAudioCodecContext,EncodeFrame);
if(ret<0){
char errstr[1024];
av_strerror(ret, errstr, sizeof(errstr));
qDebug()<<"错误信息"<<errstr;
qDebug()<<"发送解码音频包失败";
m_statue = false;
break;
}
while (ret >= 0 ) {
//接收解析后的音频包
ret = avcodec_receive_packet(OutAudioCodecContext,OutputPacket);
if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
break;
}else if(ret < 0){
m_statue = false;
break;
}else {
OutputPacket->stream_index = AudioIndex;
//写入输出文件
qDebug()<<"写入到输出文件";
if(av_interleaved_write_frame(OutFormatContext,OutputPacket)<0){
m_statue = false;
qDebug()<<"写入数据失败";
break;
}
}
}
}
}
}
}
}