=====================================================

最简单的基于libRTMP的示例系列文章列表:

最简单的基于librtmp的示例:接收(RTMP保存为FLV)

最简单的基于librtmp的示例:发布(FLV通过RTMP发布)

最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)

=====================================================

本文记录一个基于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。它们之间的关系如下图所示。

源代码

/**
 * Simplest Librtmp Receive
 *
 * 雷霄骅,张晖
 * leixiaohua1020@126.com
 * zhanghuicuc@gmail.com
 * 中国传媒大学/数字电视技术
 * Communication University of China / Digital TV Technology
 * http://blog.csdn.net/leixiaohua1020
 *
 * 本程序用于接收RTMP流媒体并在本地保存成FLV格式的文件。
 * This program can receive rtmp live stream and save it as local flv file.
 */
#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;
	//is live stream ?
	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;
	}

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

运行结果

程序运行后,会将URL为“rtmp://live.hkstv.hk.lxdns.com/live/hks”的直播流(实际上是香港卫视)在本地保存为“receive.flv”。保存后的文件使用播放器就可以观看。

下载

Simplest LibRTMP Example
 

项目主页

SourceForge:https://sourceforge.net/projects/simplestlibrtmpexample/

Github:https://github.com/leixiaohua1020/simplest_librtmp_example

开源中国:http://git.oschina.net/leixiaohua1020/simplest_librtmp_example

CSDN下载:http://download.csdn.net/detail/leixiaohua1020/8291757
 
本工程包含了LibRTMP的使用示例,包含如下子工程:
simplest_librtmp_receive: 接收RTMP流媒体并在本地保存成FLV格式的文件。
simplest_librtmp_send_flv: 将FLV格式的视音频文件使用RTMP推送至RTMP流媒体服务器。
simplest_librtmp_send264: 将内存中的H.264数据推送至RTMP流媒体服务器。

最简单的基于librtmp的示例:接收(RTMP保存为FLV)的更多相关文章

  1. 最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)

    ===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...

  2. 最简单的基于librtmp的示例:发布(FLV通过RTMP发布)

    ===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...

  3. 最简单的基于DirectShow的示例:获取Filter信息

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  4. 最简单的基于DirectShow的示例:视频播放器自定义版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  5. 最简单的基于DirectShow的示例:视频播放器图形界面版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  6. 最简单的基于DirectShow的示例:视频播放器

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  7. 一个简单的基于epoll的udp接收

    --- 1 #include <iostream> 2 #include <sys/epoll.h> 3 #include <fcntl.h> 4 #include ...

  8. 最简单的基于Flash的流媒体示例:RTMP推送和接收(ActionScript)

    ===================================================== Flash流媒体文章列表: 最简单的基于Flash的流媒体示例:RTMP推送和接收(Acti ...

  9. 转:最简单的基于 DirectShow 的视频播放器

    50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...

随机推荐

  1. 【LA 3027 Corporative Network】

    ·一些很可爱的询问和修改,放松地去用并查集解决. ·英文题,述大意: 输入n(5<=n<=20000)表示树有n个节点,并且会EOF结束地读入不超过 20000个操作,一共有两种:    ...

  2. UVA 3713 Astronauts

    The Bandulu Space Agency (BSA) has plans for the following three space missions: • Mission A: Landin ...

  3. .net4.0设计模式(一)使用Lazy的单例模式

    延迟加载,亦称延迟实例化,延迟初始化等, 主要表达的思想是,把对象的创建将会延迟到使用时创建,而不是在对象实例化时创建对象,即用时才加载.这种方式有助于提高于应用程序的性能,避免浪费计算,节省内存的使 ...

  4. fatal error LNK1104: 无法打开文件“lua51.lib”

    今天学习C++与Lua通信,遇到了问题:fatal error LNK1104: 无法打开文件"lua51.lib" 开发环境: VS2012 cocos版本:cocos2d-x- ...

  5. Cisco动态路由配置

    前言: 学完静态路由配置,该学动态路由.所以 学习完后来做终结. 准备: PC:192.168.1.10 R1:fa0/0 192.168.1.1 fa0/1 1.1.12.1 R2: fa0/0 1 ...

  6. flask jQuery ajax 上传文件

    1.html 代码 <div> <form id="uploadForm" enctype="multipart/form-data" > ...

  7. String,StringBuilder,StringBuffer三者的区别

    参考   String,StringBuilder,StringBuffer三者的区别 这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面. 1.运行速度 首先说运行速度,或者说是执行速 ...

  8. html下载excel模板

    只需要href等于模板存放的路径即可 <a href="../../TempLate/Attitude.xlsx" class="easyui-linkbutton ...

  9. sessionStorage 、localStorage 和 cookie

    localStorage 和 sessionStorage HTML5 提供了两种在客户端存储数据的新方法:localStorage 和 sessionStorage: 两者都是仅在客户端(即浏览器) ...

  10. 判断当前设备是移动端或者PC端

    <script> function browserRedirect() { var sUserAgent = navigator.userAgent.toLowerCase(); var ...