使用librtmp库发布直播流

转自:http://blog.163.com/zhujiatc@126/blog/static/183463820132135378895/

rtmp协议与flv封包格式基本相同(本来就是一家公司的嘛) 将flv文件解析出类型,时间戳,数据大小,数据区 对应写的rtmp包的位置进行发送即可
rtmpdump官网: http://rtmpdump.mplayerhq.hu/
这里是以flv文件做源,可以自己采集视频音频进行实时发送 库版本 2.4
下图,左边发送到服务器,右侧可正常观看(模拟的是实时流,发完该流也就结束了)

#include#include#include #include "librtmp/rtmp_sys.h" #include "librtmp/log.h"
#pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"lib/librtmp.lib")
#define HTON16(x)((x>>8&0xff)|(x<<8&0xff00)) #define HTON24(x)((x>>16&0xff)|(x<<16&0xff0000)|x&0xff00) #define HTON32(x)((x>>24&0xff)|(x>>8&0xff00)|\ (x<<8&0xff0000)|(x<<24&0xff000000))
bool Read8(int &i8,FILE*fp); bool Read16(int &i16,FILE*fp); bool Read24(int &i24,FILE*fp); bool Read32(int &i32,FILE*fp); bool Peek8(int &i8,FILE*fp); bool ReadTime(int &itime,FILE*fp);
//RTMP_XXX()返回0表示失败,1表示成功
RTMP*rtmp=NULL; //rtmp应用指针 RTMPPacket*packet=NULL; //rtmp包结构 char* rtmpurl="rtmp://127.0.0.1:1935/live/test"; //连接的URL char* flvfile="test.flv"; //读取的flv文件
bool ZINIT(); //初始化相关 void ZCLEAR(); //清除相关
int main() { if (!ZINIT()) { printf("init socket err\n"); return -1; } /初始化// // RTMP_debuglevel=RTMP_LOGINFO; //信息等级(0-6) 限 2.3版以前使用
RTMP_LogLevel lvl=RTMP_LOGINFO; RTMP_LogSetLevel(lvl); //设置信息等级 //RTMP_LogSetOutput(FILE*fp); //设置信息输出文件
rtmp=RTMP_Alloc(); //申请rtmp空间 RTMP_Init(rtmp); //初始化rtmp设置 rtmp->Link.timeout=5; //设置连接超时,单位秒,默认30秒 packet=new RTMPPacket(); //创建包 RTMPPacket_Alloc(packet,1024*64); //给packet分配数据空间, 要满足最长的帧,不知道可设大些 RTMPPacket_Reset(packet); //重置packet状态 连接// RTMP_SetupURL(rtmp,rtmpurl); //设置url RTMP_EnableWrite(rtmp); //设置可写状态 if (!RTMP_Connect(rtmp,NULL))//连接服务器 { printf("connect err\n"); ZCLEAR(); return -1; } if (!RTMP_ConnectStream(rtmp,0))//创建并发布流(取决于rtmp->Link.lFlags) { printf("ConnectStreamerr\n"); ZCLEAR(); return -1; } packet->m_hasAbsTimestamp = 0; //绝对时间戳 packet->m_nChannel = 0x04; //通道 packet->m_nInfoField2 = rtmp->m_stream_id;
FILE*fp=fopen(flvfile,"rb"); if (fp==NULL) { printf("open file:%s err\n",flvfile); ZCLEAR(); return -1; }
printf("rtmpurl:%s\nflvfile:%s\nsend data ...\n",rtmpurl,flvfile); 发送数据// fseek(fp,9,SEEK_SET); //跳过前9个字节 fseek(fp,4,SEEK_CUR); //跳过4字节长度 long start=clock()-1000; long perframetime=0; //上一帧时间戳 while(TRUE) { if((clock()-start){ Sleep(500); continue; } int type=0; //类型 int datalength=0; //数据长度 int time=0; //时间戳 int streamid=0; //流ID if(!Read8(type,fp)) break; if(!Read24(datalength,fp)) break; if(!ReadTime(time,fp)) break; if(!Read24(streamid,fp)) break;
if (type!=0x08&&type!=0x09) { fseek(fp,datalength+4,SEEK_CUR); continue; }
if(fread(packet->m_body,1,datalength,fp)!=datalength) break; packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet->m_nTimeStamp = time; packet->m_packetType=type; packet->m_nBodySize=datalength;
if (!RTMP_IsConnected(rtmp)) { printf("rtmp is not connect\n"); break; } if (!RTMP_SendPacket(rtmp,packet,0)) { printf("send err\n"); break; } int alldatalength=0; //该帧总长度 if(!Read32(alldatalength,fp)) break; perframetime=time; } printf("send data over\n"); fclose(fp); ZCLEAR(); return 0; }
bool ZINIT() { WORD version; WSADATA wsaData; version=MAKEWORD(2,2); if(WSAStartup(version,&wsaData)!=0) { return FALSE; } return TRUE; } void ZCLEAR() { //释放/ if (rtmp!=NULL) { RTMP_Close(rtmp); //断开连接 RTMP_Free(rtmp); //释放内存 rtmp=NULL; } if (packet!=NULL) { RTMPPacket_Free(packet); //释放内存 delete packet; packet=NULL; } /// WSACleanup(); }

bool Read8(int &i8,FILE*fp) { if(fread(&i8,1,1,fp)!=1) return false; return true; } bool Read16(int &i16,FILE*fp) { if(fread(&i16,2,1,fp)!=1) return false; i16=HTON16(i16); return true; } bool Read24(int &i24,FILE*fp) { if(fread(&i24,3,1,fp)!=1) return false; i24=HTON24(i24); return true; } bool Read32(int &i32,FILE*fp) { if(fread(&i32,4,1,fp)!=1) return false; i32=HTON32(i32); return true; } bool Peek8(int &i8,FILE*fp) { if(fread(&i8,1,1,fp)!=1) return false; fseek(fp,-1,SEEK_CUR); return true; } bool ReadTime(int &itime,FILE*fp) { int temp=0; if(fread(&temp,4,1,fp)!=1) return false; itime=HTON24(temp); itime|=(temp&0xff000000); return true; }

源码下载:(包含所需第三方库和播放器, 需自己开启rtmp服务器) http://vdisk.weibo.com/s/unhDlwQMVR3Fv
【使用librtmp库发布直播流】

    推荐阅读