ffmpeg 学习 流转发及本地保存

#include
#include
using namespace std;
extern "C"
{
    #include "SDL2/SDL.h"
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavutil/time.h"
};


AVFormatContext *inputContext;
AVFormatContext *outputContext;
int64_t lastreadtime;

static int interrupt_cb(void *ctx)
{
int timeout = 10;
if(av_gettime() -lastreadtime >  timeout *1000*1000)
{
return -1;
}
return 0;

}
int  readPacketFromSoursce(AVPacket *packet )
{
lastreadtime = av_gettime();
return av_read_frame(inputContext,packet);
}
int writePacket(AVPacket* packet)
{
AVStream *inputstream = inputContext->streams[packet->stream_index];
AVStream  *outputstream = outputContext->streams[packet->stream_index];
//转换时间戳
av_packet_rescale_ts(packet,inputstream->time_base,outputstream->time_base);
return av_interleaved_write_frame(outputContext,packet);
}
int openInput(string url)
{
inputContext = avformat_alloc_context();
lastreadtime = av_gettime();
inputContext->interrupt_callback.callback = interrupt_cb;
int ret = avformat_open_input(&inputContext,url.c_str(),NULL,NULL);
if(ret < 0)
{
printf(" %s %d %s\n",__FUNCTION__,__LINE__,"avformat_open_input error\n");
return ret;
}
ret = avformat_find_stream_info(inputContext,NULL);
if(ret < 0)
{
printf(" %s %d %s\n",__FUNCTION__,__LINE__,"avformat_find_stream_info error\n");
}
else
{
printf(" %s %d open url %s  sucess\n",__FUNCTION__,__LINE__,url.c_str());
}
return ret;
}


int openOutput(string url)
{
int ret = avformat_alloc_output_context2(&outputContext,NULL,"mpegts",url.c_str());
if(ret < 0)
{
printf(" %s %d %s\n",__FUNCTION__,__LINE__,"avformat_alloc_output_context2 error\n");
goto Error;
}
ret = avio_open2(&outputContext->pb,url.c_str(),AVIO_FLAG_WRITE,NULL,NULL);
if(ret < 0)
{
printf(" %s %d %s\n",__FUNCTION__,__LINE__,"avio_open2 error\n");
goto Error;
}
for(int i = 0; i < inputContext->nb_streams; i++)
{
AVStream * avstream = avformat_new_stream(outputContext,inputContext->streams[i]->codec->codec);
ret = avcodec_copy_context(avstream->codec,inputContext->streams[i]->codec);
if(ret < 0)
{
printf(" %s %d %s\n",__FUNCTION__,__LINE__,"avcodec_copy_context error\n");
goto Error;
}
}
ret = avformat_write_header(outputContext,NULL);
{
if(ret < 0)
{
printf(" %s %d %s\n",__FUNCTION__,__LINE__,"avformat_write_header error\n");
goto Error;
}
}
printf(" %s %d open outURL %s suess\n",__FUNCTION__,__LINE__,url.c_str());
return ret;
Error :
if(outputContext)
{
for(int i = 0; i < outputContext->nb_streams; i++)
{
avcodec_close(outputContext->streams[i]->codec);
}
avformat_close_input(&outputContext);
}
return ret;
}
void init()
{
av_register_all();
avformat_network_init();
}
int main(int argc,char *argv[])
{
init();
int ret  = openInput("http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8");
if(ret >= 0)
{
ret = openOutput("udp://127.0.0.1:3444");
}
if( ret< 0)
return -1;
AVPacket pkt;
av_init_packet(&pkt);
while(true)
{
ret =  readPacketFromSoursce(&pkt);
if(ret >= 0)
{
ret = writePacket(&pkt);
if(ret >= 0)
{
//cout << "writePacket  suess\n"; 
}
else
{
cout << "writePacket error\n";
}
}
}

}

1. 本案列可以存储本地的包

你可能感兴趣的