Github

https://github.com/gongluck/FFmpeg4.0-study.git

#include <iostream>
using namespace std; extern "C"
{
#include "libavformat/avformat.h"
#include "libavutil/time.h"
}
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avcodec.lib") char av_error[AV_ERROR_MAX_STRING_SIZE] = { 0 };
#define av_err2str(errnum) \
av_make_error_string(av_error, AV_ERROR_MAX_STRING_SIZE, errnum) #define INFILE "in.flv"
#define RTMP "rtmp://192.168.140.128/live/test"
#define RTSP "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" int file2rtmp()
{
int ret = 0;
//封装上下文
AVFormatContext* ictx = nullptr;
AVFormatContext* octx = nullptr;
const char* iurl = INFILE;
const char* ourl = RTMP;
int64_t starttime; ret = avformat_network_init();
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //打开文件,解封文件头
ret = avformat_open_input(&ictx, iurl, nullptr, nullptr);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
cerr << "open file " << iurl << " success." << endl; //获取音视频流信息,h264 flv
ret = avformat_find_stream_info(ictx, nullptr);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //打印媒体信息
av_dump_format(ictx, 0, iurl, 0); ////////////////////////////// //输出流
ret = avformat_alloc_output_context2(&octx, av_guess_format(nullptr, INFILE, nullptr), nullptr, ourl);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
cout << "octx create success." << endl; //配置输出流
for (int i = 0; i < ictx->nb_streams; ++i)
{
//创建流
AVStream* ostream = avformat_new_stream(octx, avcodec_find_encoder(ictx->streams[i]->codecpar->codec_id));
if (ostream == nullptr)
goto END;
//复制配置信息
ret = avcodec_parameters_copy(ostream->codecpar, ictx->streams[i]->codecpar);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
ostream->codecpar->codec_tag = 0;//标记不需要重新编解码
}
av_dump_format(octx, 0, ourl, 1); ////////////////////////////// //推流
ret = avio_open2(&octx->pb, ourl, AVIO_FLAG_WRITE, nullptr, nullptr);
if (ret < 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //写入头信息
ret = avformat_write_header(octx, nullptr);
if (ret < 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //推流每一帧数据
AVPacket pkt;
starttime = av_gettime();
while (av_read_frame(ictx, &pkt) == 0)
{
//计算转换pts dts
AVRational itime = ictx->streams[pkt.stream_index]->time_base;
AVRational otime = octx->streams[pkt.stream_index]->time_base;
pkt.pts = av_rescale_q_rnd(pkt.pts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q_rnd(pkt.duration, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.pos = -1; if (ictx->streams[pkt.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
int64_t nowtime = av_gettime() - starttime;
int64_t dts = pkt.dts * av_q2d(octx->streams[pkt.stream_index]->time_base) * 1000 * 1000;
if(dts > nowtime)
/*av_usleep(dts- nowtime)*/;
} ret = av_interleaved_write_frame(octx, &pkt);
av_packet_unref(&pkt);
if (ret < 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
}
ret = av_write_trailer(octx);//写文件尾
if (ret < 0)
{
cout << av_err2str(ret) << endl;
goto END;
} END:
if (ictx != nullptr)
avformat_close_input(&ictx);
if (octx != nullptr)
{
avio_close(octx->pb);
avformat_free_context(octx);
}
ret = avformat_network_deinit();
if (ret != 0)
cout << av_err2str(ret) << endl;
return 0;
} int rtsp2rtmp()
{
int ret = 0;
//封装上下文
AVFormatContext* ictx = nullptr;
AVFormatContext* octx = nullptr;
const char* iurl = RTSP;
const char* ourl = RTMP;
int64_t starttime; ret = avformat_network_init();
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //打开文件,解封文件头
ret = avformat_open_input(&ictx, iurl, nullptr, nullptr);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
cerr << "open file " << iurl << " success." << endl; //获取音视频流信息,h264 flv
ret = avformat_find_stream_info(ictx, nullptr);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //打印媒体信息
av_dump_format(ictx, 0, iurl, 0); ////////////////////////////// //输出流
ret = avformat_alloc_output_context2(&octx, av_guess_format(nullptr, INFILE, nullptr), nullptr, ourl);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
cerr << "octx create success." << endl; //配置输出流
for (int i = 0; i < ictx->nb_streams; ++i)
{
//创建流
AVStream* ostream = avformat_new_stream(octx, avcodec_find_encoder(ictx->streams[i]->codecpar->codec_id));
if (ostream == nullptr)
return -1;
//复制配置信息
ret = avcodec_parameters_copy(ostream->codecpar, ictx->streams[i]->codecpar);
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
}
ostream->codecpar->codec_tag = 0;//标记不需要重新编解码
}
av_dump_format(octx, 0, ourl, 1); ////////////////////////////// //推流
if (ret != 0)
{
cout << av_err2str(ret) << endl;
goto END;
} ret = avio_open(&octx->pb, ourl, AVIO_FLAG_WRITE);
if (ret < 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //写入头信息
ret = avformat_write_header(octx, nullptr);
if (ret < 0)
{
cout << av_err2str(ret) << endl;
goto END;
} //推流每一帧数据
AVPacket pkt;
starttime = av_gettime();
while (av_read_frame(ictx, &pkt) == 0)
{
//计算转换pts dts
AVRational itime = ictx->streams[pkt.stream_index]->time_base;
AVRational otime = octx->streams[pkt.stream_index]->time_base;
pkt.pts = av_rescale_q_rnd(pkt.pts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q_rnd(pkt.duration, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.pos = -1; ret = av_interleaved_write_frame(octx, &pkt);
av_packet_unref(&pkt);
if (ret < 0)
cout << av_err2str(ret) << endl;//不用退出
} END:
if (ictx != nullptr)
avformat_close_input(&ictx);
if (octx != nullptr)
{
avio_close(octx->pb);
avformat_free_context(octx);
}
ret = avformat_network_deinit();
if (ret != 0)
cout << av_err2str(ret) << endl;
return 0;
} int main()
{
//file2rtmp();
rtsp2rtmp();
system("pause");
return 0;
}

FFmpeg4.0笔记:rtsp2rtmp的更多相关文章

  1. FFmpeg4.0笔记:file2rtmp

    Github: https://github.com/gongluck/FFmpeg4.0-study.git #include <iostream> using namespace st ...

  2. FFmpeg4.0笔记:封装ffmpeg的解封装功能类CDemux

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CDemux.h /*********************** ...

  3. FFmpeg4.0笔记:封装ffmpeg的视频帧转换功能类CSws

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CSws.h /************************* ...

  4. FFmpeg4.0笔记:封装ffmpeg的音频重采样功能类CSwr

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CSwr.h /************************* ...

  5. FFmpeg4.0笔记:封装ffmpeg的解码功能类CDecode

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CDecode.h /********************** ...

  6. FFmpeg4.0笔记:本地媒体文件解码、帧格式转换、重采样、编码、封装、转封装、avio、硬解码等例子

    Github https://github.com/gongluck/FFmpeg4.0-study/blob/master/official%20example/my_example.cpp #in ...

  7. FFmpeg4.0笔记:采集系统声音

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff // 采集系统声音 void test_systemsound() ...

  8. FFmpeg4.0笔记:采集桌面

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff // 采集桌面 void test_desktop() { boo ...

  9. FFmpeg4.0笔记:VS2019编译FFmpeg4.0源码

    0.下载TDM.msys和yasm 1.安装TDM-GCC-64 2.安装msys到TDM-GCC的安装目录中 3.将call "C:\Program Files (x86)\Microso ...

随机推荐

  1. UI设计初学者必看,这款设计神器教你快速入门

    网络时代,网页和手机App已经深入到人们生活的方方面面.这也使得App界面设计越来越受青年求职者们的青睐,并纷纷投入这个行业.但是,作为UI设计初学者,究竟如何才能快速的入门?当今市场上,是否有那么一 ...

  2. jmeter使用HTTP代理服务器

    浏览器>web服务器 浏览器>HTTP代理服务器>web服务器 jmeter>HTTP代理服务器>web服务器 浏览器>jmeter HTTP服务器>web服 ...

  3. android 使用UDP发送数据 DatagramSocket 创建对象为null

    DatagramSocket socket=null; try { socket = new DatagramSocket();  //这里创建对象为空 } catch (SocketExceptio ...

  4. Tomcat优化详细1

    在Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题,我们这里只讲Tomcat的调整.由于Tomcat的运行依赖于J ...

  5. 旅行家的预算(NOIP1999&水题测试2017082301)

    题目链接:旅行家的预算 这题还可以,不算太水. 这题贪心即可. 我们采取如下动作: 如果在装满油的情况下能到达的范围内,没有加油站,则无解. 如果在装满油的情况下能到达的范围内,油价最低的加油站的油价 ...

  6. hdu-6058 Kanade's sum

    题意:略 思路:要我们求每个区间第K大数之和,其实可以转换为求多少个区间的第K大数是X,然后我们在求和就好了. 那么我们可以从小到大枚举所有可能成为第K大的数.为什么从小到大呢? 因为从小到大我们就略 ...

  7. python早期看书笔记

  8. ORA-38301:can not perform DDL/DML over objects in Recycle Bin

    一个智障操作,drop一个用户,下面的东西比较多,删得比较慢,然后shell突然关了. 就导致了,删不掉,又不能创建新的用户.出版本要得比较急,就先创建新的用户测试去了. 今天要弄个东西,又想起这个事 ...

  9. 2019.01.14 bzoj5343: [Ctsc2018]混合果汁(整体二分+权值线段树)

    传送门 整体二分好题. 题意简述:nnn种果汁,每种有三个属性:美味度,单位体积价格,购买体积上限. 现在有mmm个询问,每次问能否混合出总体积大于某个值,总价格小于某个值的果汁,如果能,求所有方案中 ...

  10. 2019.01.13 loj#6515. 贪玩蓝月(线段树分治+01背包)

    传送门 题意简述:有一个初始为空的双端队列,每次可以在队首和队尾插入或弹出一个二元组(wi,vi)(w_i,v_i)(wi​,vi​),支持询问从当前队列中选取若干个元素是的他们的和对 MODMODM ...