Simplest LIBRTMP-based example: Publish (FLV is released via RTMP)

Source: Internet
Author: User
Tags fread sleep socket flv file

=====================================================

The simplest example series based on Librtmp is a list of articles:

Simplest LIBRTMP-based example: Receive (rtmp saved as FLV)

Simplest LIBRTMP-based example: Publish (FLV is released via RTMP)

Simplest LIBRTMP-based example: release of H. (H. rtmp Post)

=====================================================

This document records a program that publishes streaming media based on librtmp: simplest librtmp Send FLV. The program can publish local FLV files to the rtmp streaming media server.   Is the simplest example of streaming media publishing based on Librtmp. Flowchart
There are two types of api:rtmp_sendpacket () and Rtmp_write () that can be used to publish RTMP streams using Librtmp. The function execution flowchart when using Rtmp_sendpacket () to publish the stream is shown in the following figure. There is little difference in the function execution flowchart when using Rtmp_write () to publish the stream.

The functions of the key functions in the

Flowchart are listed as follows: Initsockets (): Initialize socket
Rtmp_alloc (): Allocates memory for the structure "RTMP".
Rtmp_init (): Initializes a member variable in the structure "RTMP".
Rtmp_setupurl (): Sets the URL of the input RTMP connection.
Rtmp_enablewrite (): Must be used when publishing a stream. Represents the receive stream if not used.
Rtmp_connect (): Establish an RTMP connection to create a netconnection in the RTMP protocol specification.
Rtmp_connectstream (): Creates a netstream in the RTMP protocol specification.
Delay: The delay during release of the stream to ensure that data is sent at normal playback speed.
Rtmp_sendpacket (): Sends an RTMP data rtmppacket.
Rtmp_close (): Turn off RTMP connections.
Rtmp_free (): Releases the structure "RTMP".
Cleanupsockets (): Closes the socket. The
 
source code source code contains the source code for publishing streaming media using two API functions Rtmp_sendpacket () and Rtmp_write (), as shown below.

/** * Simplest librtmp Send FLV * * Lei Hua, Zhang Hui * leixiaohua1020@126.com * zhanghuicuc@gmail.com * Communication University/Digital TV Technology * COMMU Nication University of China/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This program is used to push an FLV format av file using rtmp
 Sent to rtmp streaming media server.
 * This program can send the local FLV file to NET Server as a rtmp live stream.
*/#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #ifndef WIN32 #include <unistd.h> #endif #include "librtmp/rtmp_sys.h" #include "librtmp/log.h" #define HTON16 (x) ((X&GT;&G T;8&AMP;0XFF) |
(X&LT;&LT;8&AMP;0XFF00)) #define HTON24 (x) ((X&GT;&GT;16&AMP;0XFF) | ( x<<16&0xff0000) |
(X&AMP;0XFF00)) #define HTON32 (x) ((X&GT;&GT;24&AMP;0XFF) | ( X&GT;&GT;8&AMP;0XFF00) |\ (x<<8&0xff0000) |
(x<<24&0xff000000)) #define HTONTIME (x) ((X&GT;&GT;16&AMP;0XFF) | ( x<<16&0xff0000) | (X&AMP;0XFF00) |
 
(x&0xff000000))
   /*read 1 byte*/int ReadU8 (uint32_t *u8,file*fp) {      if (Fread (U8,1,1,FP)!=1) return 0;
return 1;
         }/*read 2 byte*/int ReadU16 (uint32_t *u16,file*fp) {if (Fread (U16,2,1,FP)!=1) return 0;
         *u16=hton16 (*U16);
return 1;
         }/*read 3 byte*/int ReadU24 (uint32_t *u24,file*fp) {if (Fread (U24,3,1,FP)!=1) return 0;
         *u24=hton24 (*U24);
return 1;
         }/*read 4 byte*/int ReadU32 (uint32_t *u32,file*fp) {if (Fread (U32,4,1,FP)!=1) return 0;
         *u32=hton32 (*U32);
return 1;
                   }/*read 1 Byte,and loopback 1 byte at once*/int PeekU8 (uint32_t *u8,file*fp) {if (Fread (U8,1,1,FP)!=1)
         return 0;
         Fseek (fp,-1,seek_cur);
return 1;
                   }/*read 4 byte and convert to time format*/int readtime (uint32_t *utime,file*fp) {if (Fread (UTIME,4,1,FP)!=1)
         return 0;
         *utime=htontime (*utime);
return 1; } int Initsockets () {WORD version;
         Wsadata Wsadata;
         Version=makeword (2,2);
Return (WSAStartup (version, &wsadata) = = 0);
 
} void Cleanupsockets () {WSACleanup ();}                           
         Publish using Rtmp_sendpacket () int publish_using_packet () {RTMP *rtmp=null;
         Rtmppacket *packet=null;
         uint32_t start_time=0;
         uint32_t now_time=0;
         The timestamp of the previous frame long pre_frame_time=0;
         Long lasttime=0;
         int Bnextiskey=1;
        
         uint32_t pretagsize=0;                        
         Packet attributes uint32_t type=0;           
         uint32_t datalength=0;           
         uint32_t timestamp=0;                        
 
         uint32_t streamid=0;
         File*fp=null;
         Fp=fopen ("cuc_ieschool.flv", "RB");
                   if (!FP) {rtmp_logprintf ("Open File error.\n");
                   Cleanupsockets ();
   return-1;      }/* Set log level *///rtmp_loglevel loglvl=rtmp_logdebug;
                  
         Rtmp_logsetlevel (LOGLVL); if (!
                   Initsockets ()) {rtmp_logprintf ("Init Socket err\n");
         return-1;
         } rtmp=rtmp_alloc ();
         Rtmp_init (RTMP);                      
         Set Connection Timeout,default 30s rtmp->link.timeout=5; if (! Rtmp_setupurl (rtmp, "Rtmp://localhost/publishlive/livestream")) {Rtmp_log (Rtmp_logerror, "Setup
                   URL err\n ");
                   Rtmp_free (RTMP);
                   Cleanupsockets ();
         return-1;     
        
         }//if unable,the AMF command would be ' play ' instead of ' Publish ' Rtmp_enablewrite (RTMP); if (!
                   Rtmp_connect (Rtmp,null)) {Rtmp_log (Rtmp_logerror, "Connect err\n");
                   Rtmp_free (RTMP);
        Cleanupsockets ();           return-1; } if (!
                   Rtmp_connectstream (rtmp,0)) {Rtmp_log (Rtmp_logerror, "ConnectStream err\n");
                   Rtmp_close (RTMP);
                   Rtmp_free (RTMP);
                   Cleanupsockets ();
         return-1;
         } packet= (rtmppacket*) malloc (sizeof (rtmppacket));
         Rtmppacket_alloc (packet,1024*64);
 
         Rtmppacket_reset (packet);        
         Packet->m_hasabstimestamp = 0;
         Packet->m_nchannel = 0x04;
 
         Packet->m_ninfofield2 = rtmp->m_stream_id;
        
         rtmp_logprintf ("Start to send data ... \ n");     
         Jump over FLV Header fseek (fp,9,seek_set);   
         Jump over Previoustagsizen fseek (fp,4,seek_cur);
         Start_time=rtmp_gettime (); while (1) {if (((Now_time=rtmp_gettime ())-start_time) < (pre_f     rame_time)) && Bnextiskey) {   
                            Wait for 1 sec if the send process is too fast//this mechan
                                     ISM is not very good,need some improvement if (Pre_frame_time>lasttime) {
                                     rtmp_logprintf ("Timestamp:%8lu ms\n", pre_frame_time);
                            Lasttime=pre_frame_time;
                            } Sleep (1000);
                   Continue }//not quite the same as FLV spec if (!
                   ReadU8 (&AMP;TYPE,FP)) break; if (!
                   ReadU24 (&AMP;DATALENGTH,FP)) break; if (!
                   Readtime (XTAMP,FP)) break; if (!
 
                   ReadU24 (&AMP;STREAMID,FP)) break;
                            if (type!=0x08&&type!=0x09) {Jump to Non_audio and non_video frame,//jump over next previoustagsizen at the same time
                            Fseek (fp,datalength+4,seek_cur);
                   Continue
                            } if (Fread (PACKET-&GT;M_BODY,1,DATALENGTH,FP)!=datalength)
 
                   Break
                   Packet->m_headertype = Rtmp_packet_size_large;
                   Packet->m_ntimestamp = timestamp;
                   Packet->m_packettype = type;
                   Packet->m_nbodysize = datalength;
 
                   Pre_frame_time=timestamp; if (!
                            Rtmp_isconnected (rtmp)) {Rtmp_log (Rtmp_logerror, "rtmp is not connect\n");
                   Break } if (!
                            Rtmp_sendpacket (rtmp,packet,0)) {Rtmp_log (Rtmp_logerror, "Send error\n");
    Break               } if (!
                           
                   ReadU32 (&AMP;PRETAGSIZE,FP)) break; if (!
                   PeekU8 (&AMP;TYPE,FP)) break;
                            if (type==0x09) {if (fseek (fp,11,seek_cur)!=0) break; if (!
                            PeekU8 (&AMP;TYPE,FP)) {break;
                            } if (type==0x17) Bnextiskey=1;
 
                            else bnextiskey=0;
                   Fseek (fp,-11,seek_cur);
        
         }} rtmp_logprintf ("\nsend Data over\n");
 
         if (FP) fclose (FP);        
                   if (rtmp!=null) {rtmp_close (rtmp); 
                   Rtmp_free (RTMP); Rtmp=nulL    
                   } if (Packet!=null) {rtmppacket_free (packet);
                   Free (packet);
         Packet=null;
         } cleanupsockets ();
return 0;
         }//publish using Rtmp_write () int publish_using_write () {uint32_t start_time=0;
         uint32_t now_time=0;
         uint32_t pre_frame_time=0;
         uint32_t lasttime=0;
         int bnextiskey=0;
 
         char* Pfilebuf=null;
         Read from tag header uint32_t type=0;
         uint32_t datalength=0;
 
         uint32_t timestamp=0;                           
        
         RTMP *rtmp=null;
         File*fp=null;
         Fp=fopen ("cuc_ieschool.flv", "RB");
                   if (!FP) {rtmp_logprintf ("Open File error.\n");
                   Cleanupsockets ();
         return-1;
         }/* Set log level *///rtmp_loglevel loglvl=rtmp_logdebug;
                  Rtmp_logsetlevel (LOGLVL);
         if (!
                   Initsockets ()) {rtmp_logprintf ("Init Socket err\n");
         return-1;
         } rtmp=rtmp_alloc ();
         Rtmp_init (RTMP);                      
         Set Connection Timeout,default 30s rtmp->link.timeout=5; if (! Rtmp_setupurl (rtmp, "Rtmp://localhost/publishlive/livestream")) {Rtmp_log (Rtmp_logerror, "Setup
                   URL err\n ");
                   Rtmp_free (RTMP);
                   Cleanupsockets ();
         return-1;
         } rtmp_enablewrite (RTMP);         
         1hour rtmp_setbufferms (RTMP, 3600*1000); if (!
                   Rtmp_connect (Rtmp,null)) {Rtmp_log (Rtmp_logerror, "Connect err\n");
                   Rtmp_free (RTMP);
                   Cleanupsockets ();
         return-1; } if (!
                Rtmp_connectstream (rtmp,0)) {Rtmp_log (Rtmp_logerror, "ConnectStream err\n");   Rtmp_close (RTMP);
                   Rtmp_free (RTMP);
                   Cleanupsockets ();
         return-1;
        
         } printf ("Start to send data ... \ n");     
         Jump over FLV Header fseek (fp,9,seek_set);   
         Jump over Previoustagsizen fseek (fp,4,seek_cur);
         Start_time=rtmp_gettime (); while (1) {if (((Now_time=rtmp_gettime ())-start_time) < (pre_f
                            rame_time)) && Bnextiskey) {//wait for 1 sec If the-the send process is too fast This mechanism are not very good,need some improvement if (pre_fram
                                     E_time>lasttime) {rtmp_logprintf ("Timestamp:%8lu ms\n", pre_frame_time);
                            Lasttime=pre_frame_time;
             } Sleep (1000);               Continue   
                   }//jump over Type fseek (fp,1,seek_cur); if (!
                   ReadU24 (&AMP;DATALENGTH,FP)) break; if (!
                   Readtime (XTAMP,FP)) break;  
                  
                   Jump back fseek (fp,-8,seek_cur);
                   pfilebuf= (char*) malloc (11+datalength+4);
                   memset (PFILEBUF,0,11+DATALENGTH+4);
                  
                   if (Fread (PFILEBUF,1,11+DATALENGTH+4,FP)! = (11+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,pfilebuf,11+datalength+4)) {rtmp_lOG (rtmp_logerror, "RTMP Write error\n");
                   Break
                   } free (PFILEBUF);
 
                   Pfilebuf=null; if (!
                   PeekU8 (&AMP;TYPE,FP)) break;
                            if (type==0x09) {if (fseek (fp,11,seek_cur)!=0) break; if (!
                            PeekU8 (&AMP;TYPE,FP)) {break;
                            } if (type==0x17) Bnextiskey=1;
                            else bnextiskey=0;
                   Fseek (fp,-11,seek_cur);
        
         }} rtmp_logprintf ("\nsend Data over\n");
 
         if (FP) fclose (FP);        
                   if (rtmp!=null) {rtmp_close (rtmp); Rtmp_free (RTMP);
         Rtmp=null;
                   } if (Pfilebuf) {free (PFILEBUF);
         Pfilebuf=null;
         } cleanupsockets ();
return 0;
         } int main (int argc, char* argv[]) {//2 methods:publish_using_packet ();
         Publish_using_write ();
return 0; }


Run Results

After the program runs, the "cuc_ieschool.flv" file is published as a live stream to the URL of "Rtmp://localhost/publishlive/livestream". Modifying the file name and the URL of rtmp enables you to publish any FLV file to any rtmp URL.


Download simplest librtmp Example

Project Home

sourceforge:https://sourceforge.net/projects/simplestlibrtmpexample/

Github:https://github.com/leixiaohua1020/simplest_librtmp_example

Open source China: http://git.oschina.net/leixiaohua1020/simplest_librtmp_example


CSDN Download: http://download.csdn.net/detail/leixiaohua1020/8291757

This project contains examples of the use of librtmp, including the following sub-projects:
Simplest_librtmp_receive: Receive rtmp streaming and save files in FLV format locally.
SIMPLEST_LIBRTMP_SEND_FLV: The FLV format av file is pushed to the rtmp streaming media server using rtmp.
simplest_librtmp_send264: Pushes the in-memory data to the RTMP streaming media server.




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.