ffmpeg从网上保存视频流到本地文件

DTS
解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据
PTS
显示时间戳这个时间戳用来告诉播放器该在什么时候显示这一帧的数据
dts 解码参考时间,pts是预览参考时间,
在没有B帧的情况下,pts=dts
在有B帧的情况下 同一帧才可能带有不同的dts 和pts
要等到下一帧才能解码,但是显示时间在前面

//记一些重要函数
//转换时间基
AVFormatContext *inputContext=nullptr;
AVFormatContext *outputContext;
void av_packet_ts(AVPacket *pkt,AVRational src_tb,AVRational dst_tb)
{
  if(pkt->pts!=AV_NOPTS_VALUE)
      pkt->pts=av_rescale_q(pkt->pts,src_tb,dst_tb);
  if(pkt->dts!=AV_NOPTS_VALUE)
      pkt->dts=av_rescale_q(pkt->dts,src_tb,dst_tb);
   if(pkt->duration>0)
      pkt->duration=av_rescale_q(pkt->duration,src_tb,dst_tb);
} 
int WritePacket(AVPacket *packet)
{
    auto inputStream=inputContext->stream[packet->stream_index];
    auto outputStream=outputContext->stream[packet->stream_index];
    avpacket_rescale_ts(packet.get(),inputStream->time_base,outputStream->time_base);
av_interleaved_write_frame(outputContext,packet.get());
}
//packet 就是裸流PES  有时间戳
av_init_packet(packet.get());
int ret=av_read_frame(inputContext,packet.get());
if(ret>=0)
{
return packet;
}
int Openinput(string inputUrl)
{
 inputContext=avformat_alloc_context();
 int ret=avformat_open_input(&inputContext,inputUrl.c_str,nullptr,nullptr);
 if(ret<0)
 {
 av_log(NULL,AV_LOG_ERROR,"Input file open input failed\n");
 }
 ret=avformat_find_stream_info(inputContext,nullptr);
 if(ret<0)
 {
 av_log(NULL,AV_LOG_ERROR,"Find input file stream inform failed\n");
 }
 else
 {
 av_log(NULL,AV_LOG_FATAL,"open input file%s success\n",inputUrl.c_str());
 }
 retrun ret;
}
int OpenOutput(string outUrl)
{
int ret=avformat_alloc_output_context2(&outputContext,nullptr,"mpegts",outUrl.c_str());
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"open output context failed\n");
goto Error;
}
ret=avio_open2(&outputContext->pb,outUrl.c_str(),AVIO_FLAG_READ_WRITE,nullptr,nullptr);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"open avio failed");
goto Error;
}
for(int i=0;i<inputContext->nb_streams;i++)
{
AVStream *stream=avformat_naw_stream(outputContext->stream[i]->codec->codec);
ret=avcodec_copy_context(stream->codec,inputContext->stream[i]->codec);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"copy codec context failed\n");
goto Error;
}
ret=avformat_write_header(outputContext,nullptr);
if(ret<0)
{
av_log(NULL,AV_LOG_ERROR,"format write head failed");
goto Error;
}
av_log(NULL,AV_LOG_FATAL,"open output file success%s\n",outYrl.c_ctr);
return ret;
Error:
if(outputContext)
{
    for(int i=0;i<outputContext->nb_streams;i++)
    {
    avcodec_close(outputContext->stream[i]->codec);
    }
    avformat_close_input(&outputContext);
}
return ret;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值