ffmpeg提问1

江苏-左飞飞 2017-09-17 04:36:04
av_interleaved_write_frame()函数之后出现下面的错误,求帮助



int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//注册所有的编码器
avcodec_register_all();
av_register_all();
avformat_network_init();
int sampleRate = 44100;
int channels = 1;
int sampleByte = 2;
AVSampleFormat inSampleFmt = AV_SAMPLE_FMT_S16;
AVSampleFormat outSampleFmt = AV_SAMPLE_FMT_FLTP;
AVFormatContext *ic = NULL;
char *outUrl = "rtmp://120.27.229.54/live";
//Qt音频开始录制
QAudioFormat fmt;
fmt.setSampleRate(sampleRate);//样本率
fmt.setChannelCount(channels); //双通道
fmt.setSampleSize(sampleByte *8);//样本大小 16位
fmt.setCodec("audio/pcm");
fmt.setByteOrder(QAudioFormat::LittleEndian);
fmt.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(fmt))
{
std::cout << "Audio format not support..." << std::endl;
fmt = info.nearestFormat(fmt);
}
QAudioInput *input = new QAudioInput(fmt); //启动
//开始录制音频
QIODevice *io = input->start();

//音频重采样
SwrContext *asc = NULL;
asc = swr_alloc_set_opts(asc, av_get_default_channel_layout(channels), outSampleFmt,sampleRate, av_get_default_channel_layout(channels), inSampleFmt,sampleRate,0,0);
if (!asc)
{
std::cout << "swr_alloc_set_opts failed!" << std::endl;
getchar();
}
int ret = swr_init(asc);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret,err,sizeof(err)-1);
std::cout << err << std::endl;
getchar();
return -1;
}
std::cout << "音频重采样上下文初始化成功..." << std::endl;
//音频重采样输出空间分配
AVFrame *pcm = av_frame_alloc();
pcm->format = outSampleFmt;
pcm->channels = channels;
pcm->channel_layout = av_get_default_channel_layout(channels);
pcm->nb_samples = 1024;
ret = av_frame_get_buffer(pcm,0);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}

//初始化音频编码器
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (!codec)
{
std::cout << "avcodec_find_encoder AV_CODEC_ID_AAC failed" << std::endl;
getchar();
return -1;
}
//音频编码器上下文
AVCodecContext *ac = avcodec_alloc_context3(codec);
if (!ac)
{
std::cout << "avcodec_alloc_context3 AV_CODEC_ID_AAC failed..." << std::endl;
getchar();
return -1;
}
std::cout << "avcodec_alloc_context3 AV_CODEC_ID_AAC success..." << std::endl;
//设置编码器的参数
ac->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
ac->thread_count = 8;
ac->bit_rate = 40000;
ac->sample_rate = sampleRate;
ac->sample_fmt = outSampleFmt;
ac->channels = channels;
ac->channel_layout = av_get_default_channel_layout(channels);
//打开音频编码器
ret = avcodec_open2(ac, 0, 0);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}
std::cout << "打开音频编码器成功..." << std::endl;

///开始发送数据
//创建封装器
ret = avformat_alloc_output_context2(&ic,0,"flv",outUrl);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}
//添加音频流
AVStream *as = avformat_new_stream(ic, NULL);
if (!as)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}
std::cout << "添加音频流成功" << std::endl;
as->codecpar->codec_tag = 0;
//从编码器复制参数
avcodec_parameters_from_context(as->codecpar,ac);
av_dump_format(ic,0,outUrl,1);
//打开rtmp的网络输出IO
ret = avio_open(&ic->pb,outUrl,AVIO_FLAG_WRITE);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}
//写入封装头
ret = avformat_write_header(ic,NULL);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}
//一次读取一帧音频的字节数
int readSize = pcm->nb_samples*channels*sampleByte;
char *buf = new char[readSize];
int apts = 0;
AVPacket pkt = {0};
for (;;)
{
if (input->bytesReady() < 4096)
{
QThread::msleep(1);
continue;
}
int size = 0;
while (size != readSize)
{
int len = io->read(buf + size,readSize - size);
if (len < 0) break;
size += len;
}
if (size != readSize) continue;

//重采样源数据
const uint8_t *indata[AV_NUM_DATA_POINTERS] = { 0 };
indata[0] = (uint8_t*)buf;
if(pcm != NULL)
int len = swr_convert(asc,pcm->data,pcm->nb_samples,
indata,pcm->nb_samples);
//pts运算
//nb_sample/sample_rate = 一帧音频的秒数sec
//timebase pts = sec*timebase.den
pcm->pts = apts;
apts += av_rescale_q(pcm->nb_samples, { 1,sampleRate }, ac->time_base);
int ret = avcodec_send_frame(ac, pcm);
if (ret != 0) continue;
//av_packet_unref(&pkt);
avcodec_receive_packet(ac,&pkt);
if (ret != 0) continue;
//std::cout << pkt.size << " " << std::flush;
//推流
pkt.pts = av_rescale_q(pkt.pts,ac->time_base,as->time_base);
pkt.dts = av_rescale_q(pkt.dts,ac->time_base,as->time_base);
pkt.duration = av_rescale_q(pkt.duration,ac->time_base,as->time_base);
ret = av_interleaved_write_frame(ic,&pkt);
if (ret != 0)
{
char err[1024] = { 0 };
av_strerror(ret, err, sizeof(err) - 1);
std::cout << err << std::endl;
getchar();
return -1;
}
std::cout << "#" << std::flush;

}
delete buf;
getchar();
return a.exec();
}
...全文
574 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
引出人家话匣的能力 A君:关键词:趣闻。此君记忆力很强,经常把自己周围同学或自己听到的好笑的趣事,笑话记在脑里,然后每次聚会时就信手拈来,引得大家哄堂大笑,一下子就暖场了。 B君:关键词:分享自己无关痛痒的隐私。B君和姐妹聊天时,就喜欢讲自己无足轻重无关痛痒的私事,分享自己最近的喜怒哀乐,比如最近和bf发生的一点很细小矛盾但最终和平解决了。既让人觉得很交心,又无大后果。 C君:关键词:提问。没什么话时,打破僵局的永远是几个爱提问问题的朋友,尤其提问对方的家庭,家人的近况,给自己制造话题,也表达自己的关心——至少证明你还记得人家的某某家人。 D君:关键词:掌控谈话走向。有一次聚会遇到一个话很多可是说的大家都不感兴趣的人,我们都很厌烦,但此君却和人家谈得不亦乐乎。 后来此君告诉我们,因为我们总是不挑别的话题,无奈只能顺着他的方向谈,而她是从一开始就巧妙地把话题转换为自己感兴趣且拿手的,从而控制话题走向。 E君:关键词:通俗(localized)。E君很会和长辈沟通,和他们有很多共同语言,因为此君本身就是一个很地道很本土的人,通晓本土习俗,也因常和长辈在一起耳濡目染所得。 F君:关键词:平时常电联。F君以前是个很内向的人,但后来话变得很多,理由在于此君每周必抽时间和同学、朋友打电话,手机里储存了大量旧同学朋友的电话,也因为平时多聊多练手,也就不至于见面时尴尬了。

2,275

社区成员

发帖
与我相关
我的任务
社区描述
多媒体/设计/Flash/Silverlight 开发 Flash流媒体开发
社区管理员
  • Flash流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧