linux系统RTMPdump(libRTMP) 通过RTMP 发布FLV数据

 

  要使用RTMP发布FLV数据,首先需要清楚FLV的封装格式。可以查看:FLV视频封装格式详解   在运行本实例之前,需要先建立好RTMP服务器,并且建立好RTMPdump编译和运行的环境。  可以参考:

    nginx 搭建rtmp流媒体服务器

    linux 编译安装TRMPdump(libRTMP)

rtmp的具体操作接口,libRTMP库已经封装好了,可以直接调用。

RTMPPushFlv.cpp

/*============================================================================= 
 *     FileName: RTMPPushFlv.cpp 
 *         Desc: 
 *       Author: licaibiao 
 *   LastChange: 2017-05-3  
 * =============================================================================*/ 

#include "RTMPPushFlv.h"
#include "sockInit.h"
RTMPPushFlv::RTMPPushFlv(const string url) {
	// TODO Auto-generated constructor stub
	rtmpUrl=url;
	fp=NULL;
	 start_time = 0;
	 now_time = 0;

	 pre_frame_time = 0;
	 lasttime = 0;
	 b_next_is_key = 1;
	 pre_tag_size = 0;

	 type = 0;
	 datalength = 0;
	 timestamp = 0;

	 rtmp = RTMP_Alloc();
}

RTMPPushFlv::~RTMPPushFlv() {
	// TODO Auto-generated destructor stub
	if (fp != NULL) {
		fclose(fp);
		fp = NULL;
	}
	CleanupSockets();
	if (rtmp != NULL) {
		RTMP_Close(rtmp);
		RTMP_Free(rtmp);
		rtmp = NULL;
	}
	if (p_file_buf != NULL) {
		free(p_file_buf);
		p_file_buf = NULL;
	}
}

int RTMPPushFlv::init(const string filename){
	inFile=filename;
	 fp = fopen(inFile.c_str(), "rb");
	if (NULL == fp) {
		log_err("Open File Error");
		return -1;
	}
	InitSockets();
	RTMP_Init(rtmp);
	//set connection timeout,default 30s
	rtmp->Link.timeout = 5;
	if (!RTMP_SetupURL(rtmp, const_cast<char*>(rtmpUrl.c_str()))) {
		RTMP_Log(RTMP_LOGERROR, "SetupURL Err\n");
		//RTMP_Free(rtmp);
		return -1;
	}
	RTMP_EnableWrite(rtmp);
	if (!RTMP_Connect(rtmp, NULL)) {
		RTMP_Log(RTMP_LOGERROR, "Connect Err\n");
		//RTMP_Free(rtmp);
		return -1;
	}

	if (!RTMP_ConnectStream(rtmp, 0)) {
		RTMP_Log(RTMP_LOGERROR, "ConnectStream Err\n");
		//RTMP_Close(rtmp);
		//RTMP_Free(rtmp);
		return -1;
	}


	//jump over FLV Header
	fseek(fp, 9, SEEK_SET);
	//jump over previousTagSizen
	fseek(fp, 4, SEEK_CUR);
	return 0;
}

void RTMPPushFlv::run(){
	worker();
}
void RTMPPushFlv::worker(){
	log_info("Start to send data ...");
	start_time = RTMP_GetTime();
	while (1) {
		if ((((now_time = RTMP_GetTime()) - start_time)
				< (pre_frame_time)) && b_next_is_key) {
			//wait for 1 sec if the send process is too fast
			//this mechanism is not very good,need some improvement
			if (pre_frame_time > lasttime) {
				RTMP_LogPrintf("TimeStamp:%8lu ms\n", pre_frame_time);
				lasttime = pre_frame_time;
			}
			sleep(1);
			continue;
		}

		//jump over type
		fseek(fp, 1, SEEK_CUR);
		if (!ReadU24(&datalength, fp)) {
			break;
		}
		if (!ReadTime(×tamp, fp)) {
			break;
		}
		//jump back
		fseek(fp, -8, SEEK_CUR);

		p_file_buf = (char *) malloc(11 + datalength + 4);
		memset(p_file_buf, 0, 11 + datalength + 4);
		if (fread(p_file_buf, 1, 11 + datalength + 4, fp) != (11 + datalength + 4)) {
			break;
		}

		pre_frame_time = timestamp;

		if (!RTMP_IsConnected(rtmp)) {
			RTMP_Log(RTMP_LOGERROR, "rtmp is not connect\n");
			break;
		}
		if (!RTMP_Write(rtmp, p_file_buf, 11 + datalength + 4)) {
			RTMP_Log(RTMP_LOGERROR, "Rtmp Write Error\n");
			break;
		}

		free(p_file_buf);
		p_file_buf = NULL;

		if (!PeekU8(&type, fp)) {
			break;
		}
		if (0x09 == type) {        //video
			if (fseek(fp, 11, SEEK_CUR) != 0) {
				break;
			}
			if (!PeekU8(&type, fp)) {
				break;
			}
			if (type == 0x17) {    //flv key frame
				b_next_is_key = 1;
			} else {
				b_next_is_key = 0;
			}
			fseek(fp, -11, SEEK_CUR);
		}
	}
	log_info("Send Data Over");
}
void RTMPPushFlv::doPush(){
	this->start();
}

    注意  if (0x09 == type) 这里,表示发送的是视频数据。在视频数据的第一个字节里,存储的是视频的信息。再下面的 (type == 0x17) 是为了查找key frame (for AVC, a seekable frame)  ,主要目的是通过该帧来进行同步。

    在将数据推送到服务器之前,应该先启动客户端请求,这样就不会丢失FLV的一些信息。

    在流媒体播放器中,请求RTMP流数据:rtmp://192.168.0.5:1935/live  然后再运行上面程序,效果如下:

  

    完整工程:RTMPdump(libRTMP) 通过RTMP 发布FLV数据

### 回答1: rtmpdump是一个开源的命令行工具,用于从流媒体服务器上下载或录制RTMP流(Real-Time Messaging Protocol)。vc工程是指使用VC++编写的工程项目。将两者结合起来,意味着在VC++环境下使用rtmpdump工具进行流媒体下载或录制。 要在VC++中使用rtmpdump工具,首先需要下载并安装rtmpdump源代码。然后在VC++项目中添加rtmpdump的相关文件,并在代码中引用相关的头文件。接下来,就可以使用rtmpdump提供的函数来实现对RTMP流的下载或录制。 具体而言,可以使用rtmpdumprtmpdump()函数指定要下载或录制的RTMP流的URL,并设置保存的文件路径。通过调用该函数,rtmpdump将连接到流媒体服务器并获取流媒体数据,并将其写入指定的文件中。在下载或录制过程中,还可以使用rtmpdump的其他函数来处理数据流,例如解密、分段等操作。 在VC++中使用rtmpdump工程可以为流媒体下载或录制提供更灵活和定制化的功能。通过使用VC++的编程特性,可以进行更高级的数据处理和界面设计,实现更复杂的功能需求。同时,rtmpdump的开源性质也使得用户能够根据自己的需求对其进行修改和扩展。 总之,通过在VC++中使用rtmpdump工程,可以方便地实现对RTMP流的下载或录制,并根据需要进行定制化的功能扩展。这为开发者提供了更大的灵活性和自由度,以满足不同的流媒体处理需求。 ### 回答2: rtmpdump是一款用于从RTMP流媒体服务器下载或录制音频/视频内容的开源工具。vc工程是指使用Visual C++编程语言和开发环境创建的软件项目。 要创建一个rtmpdump的vc工程,首先需要下载rtmpdump的源代码,然后使用Visual C++打开相应的工程文件。接下来需要配置工程的编译环境,确保所需的头文件和库文件路径正确。 在工程中,会有一些源代码文件,这些文件负责实现rtmpdump的各种功能,例如建立与RTMP服务器的连接、发送请求、接收数据数据解析等等。这些文件会被编译成可执行的二进制文件。 在编译期间可能会遇到一些依赖项问题,例如需要额外链接一些库文件以支持某些功能。开发人员需要根据编译过程中的错误信息,对工程进行适当的配置和调整,以确保成功编译。 一旦vc工程成功编译完成,就可以生成一个可执行文件,该文件可以在命令行中运行。通过指定RTMP服务器的URL和相关参数,可以让rtmpdump工具连接到服务器并下载或录制所需的音频/视频内容。 总的来说,创建一个rtmpdump的vc工程需要下载源代码、配置编译环境、解决依赖项问题,并根据需要添加自定义功能。通过编译和运行工程生成的可执行文件,就能实现从RTMP流媒体服务器下载或录制音频/视频内容的操作。 ### 回答3: rtmpdump是一个用于下载和保存RTMP流的工具。它提供了用于处理RTMP协议的源代码,可以自定义编译和构建,获得一个可以在不同平台上运行的RTMP下载工具。 RTMP是一种用于流媒体传输的协议,它是Adobe公司开发的一种实时通信协议,常用于视频直播、在线游戏和音频通信等领域。rtmpdump工具可以连接到RTMP服务器,读取和接收RTMP流,并将其保存为本地文件。 vc工程是指使用Visual C++编译器创建的工程。通过将rtmpdump的源代码加入到Visual C++工程中,我们可以使用VC++的功能和特性来构建和调试rtmpdump工具。这样,我们就可以根据自己的需求进行修改和定制,使其能够更好地满足我们的需求。 在vc工程中,我们可以使用rtmpdump的源代码来构建一个命令行界面的工具,以便用户可以通过命令行输入相关参数来下载RTMP流。我们可以利用Visual C++的调试功能来排查和修复可能存在的问题,提高工具的稳定性和性能。 除了在vc工程中进行开发和调试,rtmpdump还可以在不同的平台上进行编译和构建,如Linux、Mac和Android等。这使得rtmpdump工具具有更广泛的适用性和可移植性。 总结来说,rtmpdump vc工程是指使用Visual C++编译器创建的工程,并集成了rtmpdump的源代码,使其能够在Windows平台上运行和定制化,从而实现对RTMP流进行下载和保存的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li_wen01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值