#ifndef PCH_H #define PCH_H extern "C" { #include "libavutil/opt.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/mathematics.h" #include "libavutil/samplefmt.h" #include "libavutil/time.h" #include "libavutil/fifo.h" #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavformat/avio.h" //#include "libavfilter/avfiltergraph.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersink.h" #include "libavfilter/buffersrc.h" #include "libswscale/swscale.h" #include "libswresample/swresample.h" } #endifpch.h
// CGPushStream.cpp : 定义控制台应用程序的入口点。 /* Copyright [c] 2018-2028 By www.chungen90.com Allrights Reserved This file give a simple example of how to push stream to rtmp server. Any questions, you can join QQ group for help, QQ Group number:127903734 or 766718184. */ #include "pch.h" #include <string> #include <memory> #include <thread> #include <iostream> using namespace std; AVFormatContext *inputContext = nullptr; AVFormatContext *inputContext2 = nullptr; AVFormatContext * outputContext; int OpenInput(string inputUrl) { inputContext = avformat_alloc_context(); AVDictionary* options = nullptr; av_dict_set(&options, "rtsp_transport", "tcp", 0); int ret = avformat_open_input(&inputContext, inputUrl.c_str(), nullptr,&options); if(ret < 0) { //av_strerror(); av_log(NULL, AV_LOG_ERROR, "Input file open input failed\n"); return ret; } 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()); } return ret; } int OpenInput2(string inputUrl) { inputContext2 = avformat_alloc_context(); AVDictionary* options = nullptr; av_dict_set(&options, "rtsp_transport", "udp", 0); int ret = avformat_open_input(&inputContext2, inputUrl.c_str(), nullptr,&options); if(ret < 0) { //av_strerror(); av_log(NULL, AV_LOG_ERROR, "Input file open input failed\n"); return ret; } ret = avformat_find_stream_info(inputContext2,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()); } return ret; } shared_ptr<AVPacket> ReadPacketFromSource() { shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p);}); av_init_packet(packet.get()); int ret = av_read_frame(inputContext, packet.get()); if(ret >= 0) { return packet; } else { return nullptr; } } shared_ptr<AVPacket> ReadPacketFromSource2() { shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p);}); av_init_packet(packet.get()); int ret = av_read_frame(inputContext2, packet.get()); if(ret >= 0) { return packet; } else { return nullptr; } } void av_packet_rescale_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(shared_ptr<AVPacket> packet) { auto inputStream = inputContext->streams[packet->stream_index]; auto outputStream = outputContext->streams[packet->stream_index]; av_packet_rescale_ts(packet.get(),inputStream->time_base,outputStream->time_base); return av_interleaved_write_frame(outputContext, packet.get()); } int OpenOutput(string outUrl) { int ret = avformat_alloc_output_context2(&outputContext, nullptr, "flv", 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; } //AVCodec * picCodec; for(int i = 0; i < inputContext->nb_streams; i++) { AVStream * stream = avformat_new_stream(outputContext, inputContext->streams[i]->codec->codec); /*picCodec = avcodec_find_encoder(inputContext->streams[i]->codec->codec_id); AVStream * stream = avformat_new_stream(outputContext, picCodec);*/ ret = avcodec_copy_context(stream->codec, inputContext->streams[i]->codec); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "copy coddec context failed"); goto Error; } } ret = avformat_write_header(outputContext, nullptr); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "format write header failed"); goto Error; } av_log(NULL, AV_LOG_FATAL, " Open output file success %s\n",outUrl.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(); avfilter_register_all(); avformat_network_init(); av_log_set_level(AV_LOG_ERROR); } int main(int argc, char* argv[]) { Init(); string input = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"; string output = "rtmp://192.168.169.139:1935/live/stream10"; /*cout <<"输入 Input url "<<endl5 cin >> input; std::cout << std::endl; cout <<"输入 Output url "<<endl; cin >> output; std::cout << std::endl;*/ //input += " live=1"; //input2 += " live=1"; int ret = OpenInput(input); //ret = OpenInput2(input2); if(ret >= 0) { ret = OpenOutput(output); } if(ret <0) goto Error; int64_t count = 0; bool flag = false; while(true) { shared_ptr<AVPacket> packet = nullptr; packet = ReadPacketFromSource(); flag = false; if(packet) { //packet->pts = packet->dts = 40 * count++; //packet->data = nullptr; //packet->buf->data = nullptr; ret = WritePacket(packet); // this_thread::sleep_for(std::chrono::seconds(5000)); if(ret >= 0 ) { //count++; cout<<"WritePacket Success!"<<endl; } else if(ret < 0) { cout<<"WritePacket failed! ret = " << ret<<endl; } } } Error: while(true) { this_thread::sleep_for(chrono::seconds(100)); } return 0; }