本文记录一个基于libRTMP的接收流媒体的程序:Simplest libRTMP Receive。该程序可以将RTMP流保存成本地FLV文件。实际上本文记录的程序就是一个“精简”过的RTMPDump。RTMPDump功能比较多,因而其代码比较复杂导致很多初学者不知从何下手。而本文记录的这个程序只保留了RTMPDump中最核心的函数,更加方便新手入门学习libRTMP。
流程图
使用librtmp接收RTMP流的函数执行流程图如下图所示。
流程图中关键函数的作用如下所列:
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。它们之间的关系如下图所示。
源代码
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include "librtmp/rtmp_sys.h"
- #include "librtmp/log.h"
-
- int InitSockets()
- {
- WORD version;
- WSADATA wsaData;
- version = MAKEWORD(1, 1);
- return (WSAStartup(version, &wsaData) == 0);
- }
-
- void CleanupSockets()
- {
- WSACleanup();
- }
-
- int main(int argc, char* argv[])
- {
- InitSockets();
-
- double duration=-1;
- int nRead;
-
- bool bLiveStream=true;
-
-
- 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;
- }
-
-
-
-
-
- RTMP *rtmp=RTMP_Alloc();
- RTMP_Init(rtmp);
-
- rtmp->Link.timeout=10;
-
- 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;
- }
-
-
- 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;
- }
运行结果
程序运行后,会将URL为“rtmp://live.hkstv.hk.lxdns.com/live/hks”的直播流(实际上是香港卫视)在本地保存为“receive.flv”。保存后的文件使用播放器就可以观看。
本文记录一个基于libRTMP的接收流媒体的程序:Simplest libRTMP Receive。该程序可以将RTMP流保存成本地FLV文件。实际上本文记录的程序就是一个“精简”过的RTMPDump。RTMPDump功能比较多,因而其代码比较复杂导致很多初学者不知从何下手。而本文记录的这个程序只保留了RTMPDump中最核心的函数,更加方便新手入门学习libRTMP。
流程图
使用librtmp接收RTMP流的函数执行流程图如下图所示。
流程图中关键函数的作用如下所列:
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。它们之间的关系如下图所示。
源代码
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include "librtmp/rtmp_sys.h"
- #include "librtmp/log.h"
-
- int InitSockets()
- {
- WORD version;
- WSADATA wsaData;
- version = MAKEWORD(1, 1);
- return (WSAStartup(version, &wsaData) == 0);
- }
-
- void CleanupSockets()
- {
- WSACleanup();
- }
-
- int main(int argc, char* argv[])
- {
- InitSockets();
-
- double duration=-1;
- int nRead;
-
- bool bLiveStream=true;
-
-
- 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;
- }
-
-
-
-
-
- RTMP *rtmp=RTMP_Alloc();
- RTMP_Init(rtmp);
-
- rtmp->Link.timeout=10;
-
- 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;
- }
-
-
- 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;
- }
运行结果
程序运行后,会将URL为“rtmp://live.hkstv.hk.lxdns.com/live/hks”的直播流(实际上是香港卫视)在本地保存为“receive.flv”。保存后的文件使用播放器就可以观看。
但在实际过程中连接rtmp服务器请求视频流时只能获取到I帧,无法获取P帧,B帧,从而导致视频不流畅,关于无法获取到P帧、B帧数据包与rtmp服务器有关。连接crtmpserver服务器获取视频流时只能获取到I帧,无法获取P帧,B帧;而连接香港卫视的直播流对应的rtmp服务器时,就可以获取到P帧。无论那个rtmp服务器通过RTMP_Read可以获取I帧、P帧等。下次重点介绍使用RTMP_Read获取视频流和音频流。
本文记录一个基于libRTMP的接收流媒体的程序:Simplest libRTMP Receive。该程序可以将RTMP流保存成本地FLV文件。实际上本文记录的程序就是一个“精简”过的RTMPDump。RTMPDump功能比较多,因而其代码比较复杂导致很多初学者不知从何下手。而本文记录的这个程序只保留了RTMPDump中最核心的函数,更加方便新手入门学习libRTMP。
流程图
使用librtmp接收RTMP流的函数执行流程图如下图所示。
流程图中关键函数的作用如下所列:
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。它们之间的关系如下图所示。
源代码
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include "librtmp/rtmp_sys.h"
- #include "librtmp/log.h"
-
- int InitSockets()
- {
- WORD version;
- WSADATA wsaData;
- version = MAKEWORD(1, 1);
- return (WSAStartup(version, &wsaData) == 0);
- }
-
- void CleanupSockets()
- {
- WSACleanup();
- }
-
- int main(int argc, char* argv[])
- {
- InitSockets();
-
- double duration=-1;
- int nRead;
-
- bool bLiveStream=true;
-
-
- 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;
- }
-
-
-
-
-
- RTMP *rtmp=RTMP_Alloc();
- RTMP_Init(rtmp);
-
- rtmp->Link.timeout=10;
-
- 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;
- }
-
-
- 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;
- }
运行结果
程序运行后,会将URL为“rtmp://live.hkstv.hk.lxdns.com/live/hks”的直播流(实际上是香港卫视)在本地保存为“receive.flv”。保存后的文件使用播放器就可以观看。