最简单的基于librtmp的示例:接收(RTMP保存为FLV)
=====================================================
最简单的基于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)的更多相关文章
- 最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)
		
===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...
 - 最简单的基于librtmp的示例:发布(FLV通过RTMP发布)
		
===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...
 - 最简单的基于DirectShow的示例:获取Filter信息
		
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
 - 最简单的基于DirectShow的示例:视频播放器自定义版
		
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
 - 最简单的基于DirectShow的示例:视频播放器图形界面版
		
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
 - 最简单的基于DirectShow的示例:视频播放器
		
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
 - 一个简单的基于epoll的udp接收
		
--- 1 #include <iostream> 2 #include <sys/epoll.h> 3 #include <fcntl.h> 4 #include ...
 - 最简单的基于Flash的流媒体示例:RTMP推送和接收(ActionScript)
		
===================================================== Flash流媒体文章列表: 最简单的基于Flash的流媒体示例:RTMP推送和接收(Acti ...
 - 转:最简单的基于 DirectShow 的视频播放器
		
50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...
 
随机推荐
- [Noi2013]矩阵游戏
			
来自FallDream的博客,未经允许,请勿转载,谢谢. 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i ...
 - [BZOJ]1047 理想的正方形(HAOI2007)
			
真·水题.小C本来是不想贴出来的,但是有一股来自东方的神秘力量催促小C发出来. Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和 ...
 - WebStorm配置node.js调试
			
最近因为工作关系,一直在做node.js的开发,学习了koa框架,orm框架sequelize,以及swagger文档的配置.但是,最近因为swagger文档使用了es6的修饰器那么个东西(在java ...
 - PHP内核之旅-1.生命周期
			
1.SAPI接口 PHP具体应用的编程接口. 2.开始和结束 PHP开始执行以后会经过两个主要的阶段: 处理请求之前的开始阶段和请求之后的结束阶段. 1.1开始阶段: 1.1.1 模块初始化阶段(MI ...
 - C语言程序第二次作业
			
(一)改错题 1.输出带框文字:在屏幕上输出以下3行信息. ************* Welcome ************* 源程序 include int mian() { printf(&q ...
 - TensorFlow-Bitcoin-Robot:Tensorflow 比特币交易机器人
			
简介 一个比特币交易机器人基于 Tensorflow LSTM 模型,仅供娱乐. A Bitcoin trade robot based on Tensorflow LSTM model.Just f ...
 - 关于 printf scanf getchar
			
float默认小数6位 右对齐.-m 左对齐 在调用printf函数输出数据时,当数据的实际位宽大于printf函数中的指定位宽时,将按照数据的实际位宽输出数据. .n表精度 输出%符号 注意点 #i ...
 - css文本超出省略号
			
终于完成了项目了,今天我就分享自己在项目中比较实用的一些功能的实现,第一个就是纯css文本超出省略号 /* 文本单行超出省略号 */ .textels { overflow: hidden; text ...
 - 转:linux/unix命令行终端的光标及字符控制快捷键
			
from:http://linux.chinaunix.net/techdoc/system/2007/11/23/973027.shtml 在使用linux/unix的命令行终端时,有时候会碰到键盘 ...
 - Node.js 多进程
			
我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能. 每个子进程总是带有三个流对象:child.st ...