rtmpdump 实现flv视频数据的rtmp推流功能

rtmpdump 是一个可以通过RTMP协议上推和下载流媒体的工具.

1、rtmpdump的编译

下载rtmpdump
http://download.csdn.net/detail/ternence_hsu/9766021 
(请不要再使用v2.3的版本,建议使用rtmpdump2.4的版本,v2.3版本中有几个bug在里面)
编译
解压后直接make
(编译之前需要先安装openssl,apt-get install openssl;apt-get install libssl-dev)
应用
如:./rtmpdump -r rtmp://172.16.1.65:1935/vod/mp4:sample.mp4 -v -o test.flv
    ./rtmpdump -r "rtmp://live.hkstv.hk.lxdns.com/live/hks" -o test1.flv -q
   
      -r url参数
      -v 是否为直播 
      -o 保存的文件

2、rtmpdump 实现 flv视频数据的rtmp推流功能

Makefle

[plain]  view plain  copy
  1. #!/bin/sh  
  2. INCLUDE = /ternence/test/rtmpdump/  
  3. LIB_DIR = /ternence/test/rtmpdump/librtmp/  
  4. LDFLAGS = -lrtmp  
  5.   
  6. SRC=rtmp_send.c  
  7.   
  8. all:$(SRC)  
  9.     gcc -g -Wall $(SRC) -o target -I $(INCLUDE) -L $(LIB_DIR)  $(LDFLAGS)  

rtmp_send.c

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <stdint.h>  
  5. #ifndef WIN32  
  6. #include <unistd.h>  
  7. #endif  
  8.   
  9. #include "librtmp/rtmp_sys.h"  
  10. #include "librtmp/log.h"  
  11.    
  12. #define HTON16(x)  ((x>>8&0xff)|(x<<8&0xff00))  
  13. #define HTON24(x)  ((x>>16&0xff)|(x<<16&0xff0000)|(x&0xff00))  
  14. #define HTON32(x)  ((x>>24&0xff)|(x>>8&0xff00)|\  
  15.          (x<<8&0xff0000)|(x<<24&0xff000000))  
  16. #define HTONTIME(x) ((x>>16&0xff)|(x<<16&0xff0000)|(x&0xff00)|(x&0xff000000))  
  17.   
  18. #define RTMP_SERVER_URL     "rtmp://172.16.1.65:1935/test1/myStream"  
  19. #define LOCAL_FILE          "test.flv"  
  20.   
  21. /*read 1 byte*/  
  22. int ReadU8(uint32_t *u8,FILE*fp){  
  23.          if(fread(u8,1,1,fp)!=1)  
  24.                    return 0;  
  25.          return 1;  
  26. }  
  27. /*read 2 byte*/  
  28. int ReadU16(uint32_t *u16,FILE*fp){  
  29.          if(fread(u16,2,1,fp)!=1)  
  30.                    return 0;  
  31.          *u16=HTON16(*u16);  
  32.          return 1;  
  33. }  
  34. /*read 3 byte*/  
  35. int ReadU24(uint32_t *u24,FILE*fp){  
  36.          if(fread(u24,3,1,fp)!=1)  
  37.                    return 0;  
  38.          *u24=HTON24(*u24);  
  39.          return 1;  
  40. }  
  41. /*read 4 byte*/  
  42. int ReadU32(uint32_t *u32,FILE*fp){  
  43.          if(fread(u32,4,1,fp)!=1)  
  44.                    return 0;  
  45.          *u32=HTON32(*u32);  
  46.          return 1;  
  47. }  
  48. /*read 1 byte,and loopback 1 byte at once*/  
  49. int PeekU8(uint32_t *u8,FILE*fp){  
  50.          if(fread(u8,1,1,fp)!=1)  
  51.                    return 0;  
  52.          fseek(fp,-1,SEEK_CUR);  
  53.          return 1;  
  54. }  
  55. /*read 4 byte and convert to time format*/  
  56. int ReadTime(uint32_t *utime,FILE*fp){  
  57.          if(fread(utime,4,1,fp)!=1)  
  58.                    return 0;  
  59.          *utime=HTONTIME(*utime);  
  60.          return 1;  
  61. }  
  62.    
  63.   
  64. int InitSockets()  
  65. {  
  66.     /* 
  67.          WORD version; 
  68.          WSADATA wsaData; 
  69.          version=MAKEWORD(2,2); 
  70.          return (WSAStartup(version, &wsaData) == 0); 
  71.          */  
  72.         return 1;  
  73. }  
  74.    
  75. void CleanupSockets()  
  76. {  
  77.         // WSACleanup();  
  78.         return;  
  79. }  
  80.    
  81. //Publish using RTMP_SendPacket()  
  82. int publish_using_packet(){  
  83.          RTMP *rtmp=NULL;                             
  84.          RTMPPacket *packet=NULL;  
  85.          uint32_t start_time=0;  
  86.          uint32_t now_time=0;  
  87.          uint32_t add_time_times=0;  
  88.          //the timestamp of the previous frame  
  89.          long pre_frame_time=0;  
  90.          long lasttime=0;  
  91.          //int bNextIsKey=1;  
  92.          uint32_t preTagsize=0;  
  93.           
  94.          //packet attributes  
  95.          uint32_t type=0;                         
  96.          uint32_t datalength=0;             
  97.          uint32_t timestamp=0;             
  98.          uint32_t streamid=0;                          
  99.    
  100.          FILE*fp=NULL;  
  101.          fp=fopen(LOCAL_FILE,"rb");  
  102.          if (!fp){  
  103.                    RTMP_LogPrintf("Open File Error.\n");  
  104.                    CleanupSockets();  
  105.                    return -1;  
  106.          }  
  107.            
  108.          /* set log level */  
  109.          //RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
  110.          //RTMP_LogSetLevel(loglvl);  
  111.   
  112.          if (!InitSockets()){  
  113.                    RTMP_LogPrintf("Init Socket Err\n");  
  114.                    return -1;  
  115.          }  
  116.    
  117.          rtmp=RTMP_Alloc();  
  118.          RTMP_Init(rtmp);  
  119.          //set connection timeout,default 30s  
  120.          rtmp->Link.timeout=5;                        
  121.          if(!RTMP_SetupURL(rtmp,RTMP_SERVER_URL))  
  122.          {  
  123.                    RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
  124.                    RTMP_Free(rtmp);  
  125.                    CleanupSockets();  
  126.                    return -1;  
  127.          }  
  128.           
  129.          //if unable,the AMF command would be 'play' instead of 'publish'  
  130.          RTMP_EnableWrite(rtmp);       
  131.           
  132.          if (!RTMP_Connect(rtmp,NULL)){  
  133.                    RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
  134.                    RTMP_Free(rtmp);  
  135.                    CleanupSockets();  
  136.                    return -1;  
  137.          }  
  138.           
  139.          if (!RTMP_ConnectStream(rtmp,0)){  
  140.                    RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
  141.                    RTMP_Close(rtmp);  
  142.                    RTMP_Free(rtmp);  
  143.                    CleanupSockets();  
  144.                    return -1;  
  145.          }  
  146.    
  147.          packet=(RTMPPacket*)malloc(sizeof(RTMPPacket));  
  148.          RTMPPacket_Alloc(packet,1024*1500);  
  149.          RTMPPacket_Reset(packet);  
  150.    
  151.          packet->m_hasAbsTimestamp = 0;          
  152.          packet->m_nChannel = 0x04;  
  153.          packet->m_nInfoField2 = rtmp->m_stream_id;  
  154.           
  155.         while(1) {  
  156.    
  157.          RTMP_LogPrintf("Start to send data ...\n");  
  158.            
  159.          fp=fopen(LOCAL_FILE,"rb");  
  160.          if (!fp){  
  161.                    RTMP_LogPrintf("Open File Error.\n");  
  162.                    CleanupSockets();  
  163.                    return -1;  
  164.          }  
  165.           
  166.          //jump over FLV Header  
  167.          fseek(fp,9,SEEK_SET);  
  168.          //jump over previousTagSizen  
  169.          fseek(fp,4,SEEK_CUR);     
  170.            
  171.          start_time=RTMP_GetTime();  
  172.          lasttime = 0;  
  173.          pre_frame_time = 0;  
  174.          RTMP_LogPrintf("add_time_times:%8u ms\n",add_time_times);  
  175.   
  176.          while(1)  
  177.          {  
  178.                    //if((((now_time=RTMP_GetTime())-start_time) < (pre_frame_time)) && bNextIsKey){          
  179.                    if(((now_time=RTMP_GetTime())-start_time) < (pre_frame_time)){          
  180.                             //wait for 1 sec if the send process is too fast  
  181.                             //this mechanism is not very good,need some improvement  
  182.                             if(pre_frame_time>lasttime){  
  183.                                      RTMP_LogPrintf("TimeStamp:%8lu ms\n",pre_frame_time);  
  184.                                      lasttime=pre_frame_time;  
  185.                             }  
  186.                             usleep(10000); // 10ms  
  187.                             continue;  
  188.                    }  
  189.                     
  190.                    //not quite the same as FLV spec  
  191.                    if(!ReadU8(&type,fp))  
  192.                    {  
  193.                         break;  
  194.                         printf("line:%d\n",__LINE__);  
  195.                    }                         
  196.   
  197.                    if(!ReadU24(&datalength,fp))  
  198.                    {  
  199.                         break;  
  200.                         printf("line:%d\n",__LINE__);  
  201.                    }      
  202.                    if(!ReadTime(×tamp,fp))  
  203.                    {  
  204.                         break;  
  205.                         printf("line:%d\n",__LINE__);  
  206.                    }      
  207.                    if(!ReadU24(&streamid,fp))  
  208.                    {  
  209.                         break;  
  210.                         printf("line:%d\n",__LINE__);  
  211.                    }      
  212.    
  213.                    if (type!=0x08&&type!=0x09){  
  214.                             //jump over non_audio and non_video frame,  
  215.                             //jump over next previousTagSizen at the same time  
  216.                             fseek(fp,datalength+4,SEEK_CUR);  
  217.                             continue;  
  218.                    }  
  219.                     
  220.                    if(fread(packet->m_body,1,datalength,fp)!=datalength)  
  221.                    {  
  222.                         break;  
  223.                         printf("line:%d\n",__LINE__);  
  224.                    }      
  225.   
  226.                    packet->m_headerType = RTMP_PACKET_SIZE_LARGE;  
  227.                    packet->m_nTimeStamp = timestamp + add_time_times;  
  228.                    packet->m_packetType = type;  
  229.                    packet->m_nBodySize  = datalength;  
  230.                    pre_frame_time=timestamp;  
  231.    
  232.                    if (!RTMP_IsConnected(rtmp)){  
  233.                             RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
  234.                             printf("line:%d\n",__LINE__);  
  235.                             break;  
  236.                    }  
  237.                    if (!RTMP_SendPacket(rtmp,packet,0)){  
  238.                             RTMP_Log(RTMP_LOGERROR,"Send Error\n");  
  239.                             printf("line:%d\n",__LINE__);  
  240.                             break;  
  241.                    }  
  242.    
  243.                    if(!ReadU32(&preTagsize,fp))  
  244.                    {  
  245.                         break;  
  246.                         printf("line:%d\n",__LINE__);  
  247.                    }      
  248.                              
  249.                    if(!PeekU8(&type,fp))  
  250.                    {  
  251.                         break;  
  252.                         printf("line:%d\n",__LINE__);  
  253.                    }      
  254.                    if(type==0x09){  
  255.                             if(fseek(fp,11,SEEK_CUR)!=0)  
  256.                                      break;  
  257.                             if(!PeekU8(&type,fp)){  
  258.                                      break;  
  259.                             }  
  260.                             /* 
  261.                             if(type==0x17) 
  262.                                      bNextIsKey=1; 
  263.                             else 
  264.                                      bNextIsKey=0; 
  265.                             */  
  266.                             fseek(fp,-11,SEEK_CUR);  
  267.                    }  
  268.          }   
  269.    
  270.          RTMP_LogPrintf("\nSend Data Over\n");  
  271.            
  272.          add_time_times += 237080;  
  273.           
  274.          if(fp)  
  275.             fclose(fp);  
  276.         }  
  277.                  
  278.          if (rtmp!=NULL){  
  279.                    RTMP_Close(rtmp);          
  280.                    RTMP_Free(rtmp);   
  281.                    rtmp=NULL;  
  282.          }  
  283.          if (packet!=NULL){  
  284.                    RTMPPacket_Free(packet);      
  285.                    free(packet);  
  286.                    packet=NULL;  
  287.          }  
  288.    
  289.          CleanupSockets();  
  290.          return 0;  
  291. }  
  292.    
  293. //Publish using RTMP_Write()  
  294. int publish_using_write(){  
  295.          uint32_t start_time=0;  
  296.          uint32_t now_time=0;  
  297.          uint32_t pre_frame_time=0;  
  298.          uint32_t lasttime=0;  
  299.          int bNextIsKey=0;  
  300.          char* pFileBuf=NULL;  
  301.    
  302.          //read from tag header  
  303.          uint32_t type=0;  
  304.          uint32_t datalength=0;  
  305.          uint32_t timestamp=0;  
  306.    
  307.          RTMP *rtmp=NULL;                             
  308.           
  309.          FILE*fp=NULL;  
  310.          fp=fopen(LOCAL_FILE,"rb");  
  311.          if (!fp){  
  312.                    RTMP_LogPrintf("Open File Error.\n");  
  313.                    CleanupSockets();  
  314.                    return -1;  
  315.          }  
  316.    
  317.          /* set log level */  
  318.          //RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
  319.          //RTMP_LogSetLevel(loglvl);  
  320.                     
  321.          if (!InitSockets()){  
  322.                   RTMP_LogPrintf("Init Socket Err\n");  
  323.                    return -1;  
  324.          }  
  325.    
  326.          rtmp=RTMP_Alloc();  
  327.          RTMP_Init(rtmp);  
  328.          //set connection timeout,default 30s  
  329.          rtmp->Link.timeout=5;                        
  330.          if(!RTMP_SetupURL(rtmp,RTMP_SERVER_URL))  
  331.          {  
  332.                    RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
  333.                    RTMP_Free(rtmp);  
  334.                    CleanupSockets();  
  335.                    return -1;  
  336.          }  
  337.    
  338.          RTMP_EnableWrite(rtmp);  
  339.          //1hour  
  340.          RTMP_SetBufferMS(rtmp, 3600*1000);           
  341.          if (!RTMP_Connect(rtmp,NULL)){  
  342.                    RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
  343.                    RTMP_Free(rtmp);  
  344.                    CleanupSockets();  
  345.                    return -1;  
  346.          }  
  347.           
  348.          if (!RTMP_ConnectStream(rtmp,0)){  
  349.                    RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
  350.                    RTMP_Close(rtmp);  
  351.                    RTMP_Free(rtmp);  
  352.                    CleanupSockets();  
  353.                    return -1;  
  354.          }  
  355.    
  356.          printf("Start to send data ...\n");  
  357.           
  358.          //jump over FLV Header  
  359.          fseek(fp,9,SEEK_SET);       
  360.          //jump over previousTagSizen  
  361.          fseek(fp,4,SEEK_CUR);     
  362.          start_time=RTMP_GetTime();  
  363.          while(1)  
  364.          {  
  365.                    if((((now_time=RTMP_GetTime())-start_time)  
  366.                               <(pre_frame_time)) && bNextIsKey){          
  367.                             //wait for 1 sec if the send process is too fast  
  368.                             //this mechanism is not very good,need some improvement  
  369.                             if(pre_frame_time>lasttime){  
  370.                                      RTMP_LogPrintf("TimeStamp:%8u ms\n",pre_frame_time);  
  371.                                      lasttime=pre_frame_time;  
  372.                             }  
  373.                             sleep(1);  
  374.                             continue;  
  375.                    }  
  376.                     
  377.                    //jump over type  
  378.                    fseek(fp,1,SEEK_CUR);     
  379.                    if(!ReadU24(&datalength,fp))  
  380.                             break;  
  381.                    if(!ReadTime(×tamp,fp))  
  382.                             break;  
  383.                    //jump back  
  384.                    fseek(fp,-8,SEEK_CUR);    
  385.                     
  386.                    pFileBuf=(char*)malloc(11+datalength+4);  
  387.                    memset(pFileBuf,0,11+datalength+4);  
  388.                    if(fread(pFileBuf,1,11+datalength+4,fp)!=(11+datalength+4))  
  389.                             break;  
  390.                     
  391.                    pre_frame_time=timestamp;  
  392.                     
  393.                    if (!RTMP_IsConnected(rtmp)){  
  394.                             RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
  395.                             break;  
  396.                    }  
  397.                    if (!RTMP_Write(rtmp,pFileBuf,11+datalength+4)){  
  398.                             RTMP_Log(RTMP_LOGERROR,"Rtmp Write Error\n");  
  399.                             break;  
  400.                    }  
  401.                     
  402.                    free(pFileBuf);  
  403.                    pFileBuf=NULL;  
  404.    
  405.                    if(!PeekU8(&type,fp))  
  406.                             break;  
  407.                    if(type==0x09){  
  408.                             if(fseek(fp,11,SEEK_CUR)!=0)  
  409.                                      break;  
  410.                             if(!PeekU8(&type,fp)){  
  411.                                      break;  
  412.                             }  
  413.                             if(type==0x17)  
  414.                                      bNextIsKey=1;  
  415.                             else  
  416.                                      bNextIsKey=0;  
  417.                             fseek(fp,-11,SEEK_CUR);  
  418.                    }  
  419.          }  
  420.    
  421.          RTMP_LogPrintf("\nSend Data Over\n");  
  422.           
  423.          if(fp)  
  424.                    fclose(fp);  
  425.    
  426.          if (rtmp!=NULL){  
  427.                    RTMP_Close(rtmp);          
  428.                    RTMP_Free(rtmp);  
  429.                    rtmp=NULL;  
  430.          }  
  431.    
  432.          if(pFileBuf){  
  433.                    free(pFileBuf);  
  434.                    pFileBuf=NULL;  
  435.          }  
  436.    
  437.          CleanupSockets();  
  438.          return 0;  
  439. }  
  440.    
  441. int main(int argc, char* argv[]){  
  442.          //2 Methods:  
  443.          publish_using_packet();  
  444.          //publish_using_write();  
  445.          return 0;  
  446. }  

源码的下载地址:

http://download.csdn.net/detail/ternence_hsu/9766189

猜你喜欢

转载自blog.csdn.net/sunxiaopengsun/article/details/80269157