To publish FLV data using RTMP, you first need to be aware of the FLV encapsulation format. can view: FLV video Encapsulation Format before you run this instance, you need to build a rtmp server and build an environment where Rtmpdump compiles and runs. can refer to:
Nginx build rtmp Streaming Media server
Linux compilation Installation Trmpdump (LIBRTMP)
Rtmp specific operation interface, the LIBRTMP library has been encapsulated, you can call directly.
RTMPPushFlv.cpp
/*============================================================================= * FileName:RTMPPushFlv.cpp * DESC: * Author:licaibiao * lastchange:2017-05-3 * =================================================== ==========================*/#include "RTMPPushFlv.h" #include "sockInit.h" rtmppushflv::rtmppushflv (const string URL
) {//TODO auto-generated constructor stub rtmpurl=url;
Fp=null;
start_time = 0;
Now_time = 0;
Pre_frame_time = 0;
Lasttime = 0;
B_next_is_key = 1;
pre_tag_size = 0;
Type = 0;
datalength = 0;
timestamp = 0;
rtmp = Rtmp_alloc ();
} rtmppushflv::~rtmppushflv () {//TODO auto-generated destructor stub if (FP!= NULL) {fclose (FP);
fp = NULL;
} cleanupsockets ();
if (rtmp!= NULL) {rtmp_close (rtmp);
Rtmp_free (RTMP);
rtmp = NULL;
} if (P_file_buf!= NULL) {free (P_FILE_BUF);
P_file_buf = NULL;
} int Rtmppushflv::init (const string filename) {infile=filename; fp = fopen (infile.c_str(), "RB");
if (NULL = fp) {log_err ("Open File Error");
return-1;
} initsockets ();
Rtmp_init (RTMP);
Set Connection Timeout,default 30s rtmp->link.timeout = 5; if (!
Rtmp_setupurl (RTMP, const_cast<char*> (Rtmpurl.c_str ()))) {Rtmp_log (Rtmp_logerror, "Setupurl Err\n");
Rtmp_free (RTMP);
return-1;
} rtmp_enablewrite (RTMP); if (!
Rtmp_connect (RTMP, NULL)) {Rtmp_log (Rtmp_logerror, "Connect err\n");
Rtmp_free (RTMP);
return-1; } if (!
Rtmp_connectstream (RTMP, 0)) {rtmp_log (Rtmp_logerror, "ConnectStream err\n");
Rtmp_close (RTMP);
Rtmp_free (RTMP);
return-1;
//jump over FLV Header fseek (FP, 9, Seek_set);
Jump over Previoustagsizen fseek (FP, 4, seek_cur);
return 0;
} void Rtmppushflv::run () {Worker ();} void Rtmppushflv::worker () {log_info ("Start to send data ...");
Start_time = Rtmp_gettime (); while (1) {if (((Now_time = Rtmp_gettime ())-Start_time) < (pre_frame_time)) && B_next_is_key) {// Wait for 1 sec If the send process is too fast//this mechanism are not very good,need some improvement if (Pre_frame_time &G T
Lasttime) {rtmp_logprintf ("Timestamp:%8lu ms\n", pre_frame_time);
Lasttime = Pre_frame_time;
Sleep (1);
Continue
//jump over Type fseek (FP, 1, seek_cur); if (!
ReadU24 (&datalength, FP)) {break; } if (!
Readtime (Xtamp, FP)) {break;
//jump back Fseek (FP,-8, seek_cur);
P_FILE_BUF = (char *) malloc (one + datalength + 4);
memset (p_file_buf, 0, one + datalength + 4);
if (Fread (P_FILE_BUF, 1, one + datalength + 4, FP)!= (one + datalength + 4)) {break;
} pre_frame_time = timestamp; if (!
Rtmp_isconnected (RTMP)) {Rtmp_log (Rtmp_logerror, "RTMP is not connect\n");
Break } if (!
Rtmp_write (RTMP, p_file_buf, one + datalength + 4)) {Rtmp_log (Rtmp_logerror, "RTMP Write error\n");
Break
Free (P_FILE_BUF);
P_file_buf = NULL; if (!
PeekU8 (&type, FP)) {break; } if (0x09 = type) {//video if (fseek (FP, seek_cur)!= 0) {break; } if (!
PeekU8 (&type, FP)) {break;
} if (type = = 0x17) {//flv key frame B_next_is_key = 1;
else {b_next_is_key = 0;
Fseek (FP, -11, seek_cur);
} log_info ("Send Data over"); } void rtmppushflv::d opush () {This->start ();}
Note that if (0x09 = = type) Here, the video data is sent. In the first byte of the video data, the information is stored in the video. The following (type = = 0x17) is to find the key frame (for AVC, a seekable frame), the main purpose of which is to synchronize through the frame.
Before you push data to a server, you should start a client request so that you do not lose some information about FLV.
In streaming media player, request rtmp stream data: rtmp://192.168.0.5:1935/live and then run the above program, the effect is as follows:
Full project: Rtmpdump (LIBRTMP) publishes FLV data via rtmp