linux 下librtmp源码,linux下基于libRTMP的接收流媒体的程序
看了雷博的一篇關(guān)于rtmp的文章,學(xué)習(xí)記錄以作備忘。
使用librtmp接收RTMP流的函數(shù)執(zhí)行流程圖如下圖:
流程圖中關(guān)鍵函數(shù)的作用如下所列:
InitSockets():初始化Socket
RTMP_Alloc():為結(jié)構(gòu)體“RTMP”分配內(nèi)存。
RTMP_Init():初始化結(jié)構(gòu)體“RTMP”中的成員變量。
RTMP_SetupURL():設(shè)置輸入的RTMP連接的URL。
RTMP_Connect():建立RTMP連接,創(chuàng)建一個(gè)RTMP協(xié)議規(guī)范中的NetConnection。
RTMP_ConnectStream():創(chuàng)建一個(gè)RTMP協(xié)議規(guī)范中的NetStream。
RTMP_Read():從服務(wù)器讀取數(shù)據(jù)。
RTMP_Close():關(guān)閉RTMP連接。
RTMP_Free():釋放結(jié)構(gòu)體“RTMP”。
CleanupSockets():關(guān)閉Socket。
其中NetStream和NetConnection是RTMP協(xié)議規(guī)范中的兩個(gè)邏輯結(jié)構(gòu)。NetStream建立在NetConnection之上。一個(gè)NetConnection可以包含多個(gè)NetStream。它們之間的關(guān)系如下圖所示:
源代碼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的幾個(gè)頭文件,需要借助librtmp的庫,可以隨意在網(wǎng)上下個(gè),我找了雷神的那個(gè):
http://download.csdn.net/download/leixiaohua1020/8291757我只拷貝了librtmp,和頂層的Makefile,Makefile做了一點(diǎn)點(diǎn)修改來編譯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
./rtmp2flv運(yùn)行程序
用smplayer receive.flv 來播放視頻:
感謝雷神!
總結(jié)
以上是生活随笔為你收集整理的linux 下librtmp源码,linux下基于libRTMP的接收流媒体的程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机视觉中的对象跟踪(完整指南)
- 下一篇: Linux之执行一个可执行文件