linux 下librtmp源码,linux下基于libRTMP的接收流媒体的程序

看了雷博的一篇关于rtmp的文章,学习记录以作备忘。

使用librtmp接收RTMP流的函数执行流程图如下图:

c3948bb8f497be00882d4f3c06517ead.png

流程图中关键函数的作用如下所列:

InitSockets():初始化Socket

RTMP_Alloc():为结构体“RTMP”分配内存。

RTMP_Init():初始化结构体“RTMP”中的成员变量。

RTMP_SetupURL():设置输入的RTMP连接的URL。

RTMP_Connect():建立RTMP连接,创建一个RTMP协议规范中的NetConnection。

RTMP_ConnectStream():创建一个RTMP协议规范中的NetStream。

RTMP_Read():从服务器读取数据。

RTMP_Close():关闭RTMP连接。

RTMP_Free():释放结构体“RTMP”。

CleanupSockets():关闭Socket。

其中NetStream和NetConnection是RTMP协议规范中的两个逻辑结构。NetStream建立在NetConnection之上。一个NetConnection可以包含多个NetStream。它们之间的关系如下图所示:

7628a99df10a5614145a56fd3140c17a.png

源代码rtmp2flv.c:

#include #include #include "librtmp/rtmp_sys.h"

#include "librtmp/log.h"

#include "librtmp/rtmp.h"

int InitSockets()

{

#if 0

WORD version;

WSADATA wsaData;

version = MAKEWORD(1, 1);

return (WSAStartup(version, &wsaData) == 0);

#endif

}

void CleanupSockets()

{

#if 0

WSACleanup();

#endif

}

int main(int argc, char* argv[])

{

InitSockets();

double duration=-1;

int nRead;

//is live stream ?

char bLiveStream=1;

int bufsize=1024*1024*10;

char *buf=(char*)malloc(bufsize);

memset(buf,0,bufsize);

long countbufsize=0;

FILE *fp=fopen("receive.flv","wb");

if (!fp){

RTMP_LogPrintf("Open File Error.\n");

CleanupSockets();

return -1;

}

/* set log level */

//RTMP_LogLevel loglvl=RTMP_LOGDEBUG;

//RTMP_LogSetLevel(loglvl);

RTMP *rtmp=RTMP_Alloc();

RTMP_Init(rtmp);

//set connection timeout,default 30s

rtmp->Link.timeout=10;

// HKS's live URL

if(!RTMP_SetupURL(rtmp,"rtmp://live.hkstv.hk.lxdns.com/live/hks"))

{

RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");

RTMP_Free(rtmp);

CleanupSockets();

return -1;

}

if (bLiveStream){

rtmp->Link.lFlags|=RTMP_LF_LIVE;

}

//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;

}

while(nRead=RTMP_Read(rtmp,buf,bufsize)){

fwrite(buf,1,nRead,fp);

countbufsize+=nRead;

RTMP_LogPrintf("Receive: %5dByte, Total: %5.2fkB\n",nRead,countbufsize*1.0/1024);

}

if(fp)

fclose(fp);

if(buf){

free(buf);

}

if(rtmp){

RTMP_Close(rtmp);

RTMP_Free(rtmp);

CleanupSockets();

rtmp=NULL;

}

return 0;

}

这里面包含rtmp的几个头文件,需要借助librtmp的库,可以随意在网上下个,我找了雷神的那个:

http://download.csdn.net/download/leixiaohua1020/8291757我只拷贝了librtmp,和顶层的Makefile,Makefile做了一点点修改来编译rtmp2flv.c

Makefile:

VERSION=v2.3

prefix=/usr/local

CC=$(CROSS_COMPILE)gcc

LD=$(CROSS_COMPILE)ld

SYS=posix

#SYS=mingw

CRYPTO=OPENSSL

#CRYPTO=POLARSSL

#CRYPTO=GNUTLS

LIB_GNUTLS=-lgnutls -lgcrypt

LIB_OPENSSL=-lssl -lcrypto

LIB_POLARSSL=-lpolarssl

CRYPTO_LIB=$(LIB_$(CRYPTO))

DEF_=-DNO_CRYPTO

CRYPTO_DEF=$(DEF_$(CRYPTO))

DEF=-DRTMPDUMP_VERSION=\"$(VERSION)\" $(CRYPTO_DEF) $(XDEF)

OPT=-O2

CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT)

LDFLAGS=-Wall $(XLDFLAGS)

bindir=$(prefix)/bin

sbindir=$(prefix)/sbin

mandir=$(prefix)/man

BINDIR=$(DESTDIR)$(bindir)

SBINDIR=$(DESTDIR)$(sbindir)

MANDIR=$(DESTDIR)$(mandir)

LIBS_posix=

LIBS_mingw=-lws2_32 -lwinmm -lgdi32

LIBS=$(CRYPTO_LIB) -lz $(LIBS_$(SYS)) $(XLIBS)

THREADLIB_posix=-lpthread

THREADLIB_mingw=

THREADLIB=$(THREADLIB_$(SYS))

SLIBS=$(THREADLIB) $(LIBS)

LIBRTMP=librtmp/librtmp.a

INCRTMP=librtmp/rtmp_sys.h librtmp/rtmp.h librtmp/log.h librtmp/amf.h

EXT_posix=

EXT_mingw=.exe

EXT=$(EXT_$(SYS))

all:$(LIBRTMP) progs

progs:rtmp2flv rtmpdump rtmpgw rtmpsrv rtmpsuck

install:progs

-mkdir -p $(BINDIR) $(SBINDIR) $(MANDIR)/man1 $(MANDIR)/man8

cp rtmpdump$(EXT) $(BINDIR)

cp rtmpgw$(EXT) rtmpsrv$(EXT) rtmpsuck$(EXT) $(SBINDIR)

cp rtmpdump.1 $(MANDIR)/man1

cp rtmpgw.8 $(MANDIR)/man8

@cd librtmp; $(MAKE) install

clean:

rm -f *.o rtmp2flv$(EXT) rtmpdump$(EXT) rtmpgw$(EXT) rtmpsrv$(EXT) rtmpsuck$(EXT)

@cd librtmp; $(MAKE) clean

FORCE:

$(LIBRTMP): FORCE

@cd librtmp; $(MAKE) all

# note: $^ is GNU Make's equivalent to BSD $>

# we use both since either make will ignore the one it doesn't recognize

rtmp2flv: rtmp2flv.o $(LIBRTMP)

$(CC) $(LDFLAGS) $^ $> -o $@$(EXT) $(LIBS)

rtmpdump: rtmpdump.o $(LIBRTMP)

$(CC) $(LDFLAGS) $^ $> -o $@$(EXT) $(LIBS)

rtmpsrv: rtmpsrv.o thread.o $(LIBRTMP)

$(CC) $(LDFLAGS) $^ $> -o $@$(EXT) $(SLIBS)

rtmpsuck: rtmpsuck.o thread.o $(LIBRTMP)

$(CC) $(LDFLAGS) $^ $> -o $@$(EXT) $(SLIBS)

rtmpgw: rtmpgw.o thread.o $(LIBRTMP)

$(CC) $(LDFLAGS) $^ $> -o $@$(EXT) $(SLIBS)

rtmp2flv.o: rtmp2flv.c $(INCRTMP) Makefile

rtmpgw.o: rtmpgw.c $(INCRTMP) Makefile

rtmpdump.o: rtmpdump.c $(INCRTMP) Makefile

rtmpsrv.o: rtmpsrv.c $(INCRTMP) Makefile

rtmpsuck.o: rtmpsuck.c $(INCRTMP) Makefile

thread.o: thread.c thread.h

3dbecaeeb3276ae97f27472b9188dd5e.png

./rtmp2flv运行程序

用smplayer receive.flv 来播放视频:

8ee1af97831bea89e9a5ad7c987d6ab5.png

感谢雷神!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值