Many friends will ask how RTSP through the RTMP protocol push to the server, just a while ago developed this feature written here, and you share.
The first thing I want to say is that ffmpeg can achieve this function. The FFMPEG supports the RTSP protocol and also supports RTMP. In this case, RTSP is the input,
RTMP is the output, FFmpeg realizes the function of transcoding. The following can be a general idea flowchart.
Figure 1
1: After acquiring both RTSP streams, the Demux obtains the ES stream packet and finally encapsulates the ES stream into rtmp format and sends
To the service side.
The basic idea is complete, below the code.
One: Initialize the FFmpeg library
void Init () { av_register_all (); Avfilter_register_all (); Avformat_network_init (); Av_log_set_level (Av_log_error);}
Two. Open rtmp video stream
intOpeninput (Char*fileName) {Context=Avformat_alloc_context (); intret = Avformat_open_input (&context, FileName, nullptr,nullptr); if(Ret <0) { returnret; } ret=Avformat_find_stream_info (CONTEXT,NULLPTR); Auto Codeccontext= context->streams[0]->codec; RET= Avcodec_open2 (Codeccontext, Avcodec_find_decoder (codeccontext->codec_id), nullptr); returnret;}
A return value of less than 0 indicates that the stream failed to open.
Three. Create an output stream
intOpenoutput (Char*fileName) { intRET =0; RET= Avformat_alloc_output_context2 (&outputcontext, nullptr,"flv", FileName); if(Ret <0) { GotoError; } ret= Avio_open2 (&outputContext->pb, FileName, Avio_flag_read_write,nullptr, nullptr); if(Ret <0) { GotoError; } for(inti =0; I < context->nb_streams; i++) {Avstream* Stream =Avformat_new_stream (Outputcontext, nullptr); ret= Avcodec_copy_context (Stream->codec, context->streams[i]->codec); if(Ret <0) { GotoError; }} RET=Avformat_write_header (Outputcontext, nullptr); if(Ret <0) { GotoError; } returnret; Error:if(outputcontext) { for(inti =0; I < outputcontext->nb_streams; i++) {avcodec_close (Outputcontext->streams[i]->codec); } avformat_close_input (&outputcontext); } returnret;}
The return value is less than 0, creating the output stream failed to send the video stream in rtmp format be sure to initialize the output context in FLV format.
Four. Read packet
Shared_ptr<avpacket>Readpacketfromsource () {shared_ptr<AVPacket> Packet (static_cast<avpacket*> (Av_malloc (sizeof(Avpacket)), [&] (Avpacket *p) {av_free_packet (P); Av_freep (&( p);}); Av_init_packet (packet.Get()); intRET = av_read_frame (context, packet.Get()); if(Ret >=0) { returnpacket; } Else { returnnullptr; }}
Five. Write packet to the server
Av_interleaved_write_frame (Outputcontext, Packet.get ());
Six. Simple Demo
int _tmain (int argc, _tchar* argv[]) {string fileinput= "Rtsp://admin:[email protected]/media/video1/multicast"; string Fileoutput= "Rtmp://127.0.0.1/live/mystream"; Init (); if (Openinput (char *) FILEINPUT.C_STR ()) < 0) {cout << " Open file Input failed! "<< endl;this_thread::sleep_for (chrono::seconds); return 0;} if (Openoutput (char *) FILEOUTPUT.C_STR ()) < 0) {cout << "Open file Output failed!" << endl;this_thread:: Sleep_for (Chrono::seconds ()); return 0;} Auto Timebase = av_q2d (context->streams[0]->time_base); while (true) {Auto packet = Readpacketfromsource (); if ( packet) {int ret = Av_interleaved_write_frame (Outputcontext, Packet.get ());} else{cout << "Write Packet end!" << Endl; Break;}} Closeinput (); Closeoutput (); cout << "transcode file end!" << endl;this_thread::sleep_for (Chrono::seconds (+)); return 0;}
Seven. Summary:
After testing, the network rtmp live time delay within 1 seconds, the public network delay in 3, 4 seconds or so.
RTSP live stream is pushed to the server via rtmp