rtmpdump在VS2019下的编译和使用

近期工作业务需要实现接收rtmp流媒体并保存到本地的功能。要实现这个功能,就得用到librtmp这个库,综合了网上看到的好几种方法并进行实际操作,成功地对rtmpdump进行了编译和使用,由于参考的方法叙述会较为简略,因此在这里详细记录编译和使用的过程,也希望能给大家提供帮助。

rtmpdump的编译

1.下载librtmp的源代码,我下的是rtmpdump-2.3
下载地址

2.下载zlib的源代码,我下的是1.2.11
下载地址

3.打开vs2019,创建一个静态库工程,该工程默认保存在C:\Users\xxx\source\repos目录下【这个目录因人而异,记住保存在什么地方就好】
在这里插入图片描述
在这里插入图片描述
4.打开Git Bash,在命令行中键入,名为rtmpdump的文件夹就会出现在C:\Users\xxx目录下。

git clone git://git.ffmpeg.org/rtmpdump

在这里插入图片描述
5.打开rtmpdump/librtmp文件夹,将所有的.h文件和.c文件复制到vs2019静态库工程librtmp所在的目录下。打开vs,分别把.h文件和.c文件载入到工程的头文件和源文件目录下。
在这里插入图片描述
以下是载入头文件的步骤,源文件同理。
在这里插入图片描述
由于没有下载openssl,所以需要在项目→属性→C/C++预处理器中,添加宏定义 NO_CRYPTO
在这里插入图片描述
6.此时编译会报错,是否忘记了向源文件添加“#include “pch.h””?
在这里插入图片描述
打开项目→属性→预编译头,选择不使用预编译头。
在这里插入图片描述
7.编译通过,但生成仍然有很多错误,接下来打开rtmp_sys.h文件进行修改。

原来的代码:

#ifdef _WIN32

#include <winsock2.h>
#include <ws2tcpip.h>

#ifdef _MSC_VER	/* MSVC */
#define snprintf _snprintf
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define vsnprintf _vsnprintf
#endif

#define GetSockError()	WSAGetLastError()
#define SetSockError(e)	WSASetLastError(e)
#define setsockopt(a,b,c,d,e)	(setsockopt)(a,b,c,(const char *)d,(int)e)
#define EWOULDBLOCK	WSAETIMEDOUT	/* we don't use nonblocking, but we do use timeouts */
#define sleep(n)	Sleep(n*1000)
#define msleep(n)	Sleep(n)
#define SET_RCVTIMEO(tv,s)	int tv = s*1000

改动后的代码:

#ifdef _WIN32

#include <winsock2.h>
#include <ws2tcpip.h>

/*改动部分*/
#if defined(_MSC_VER) && (_MSC_VER < 1900) /* MSVC */
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
#define strncasecmp strnicmp
#define strcasecmp stricmp

typedef __int64 off_t;
/*改动部分*/

#define GetSockError()	WSAGetLastError()
#define SetSockError(e)	WSASetLastError(e)
#define setsockopt(a,b,c,d,e)	(setsockopt)(a,b,c,(const char *)d,(int)e)
#define EWOULDBLOCK	WSAETIMEDOUT	/* we don't use nonblocking, but we do use timeouts */
#define sleep(n)	Sleep(n*1000)
#define msleep(n)	Sleep(n)
#define SET_RCVTIMEO(tv,s)	int tv = s*1000

接着打开rtmp.c文件,将下列语句注释掉

#ifdef _DEBUG
extern FILE *netstackdump;
extern FILE *netstackdump_read;
#endif

#ifdef _DEBUG
      fwrite(ptr, 1, nBytes, netstackdump_read);
#endif

#ifdef _DEBUG
  fwrite(buf, 1, len, netstackdump);
#endif

在项目→属性→C/C++预处理器→预处理定义中添加

_CRT_NONSTDC_NO_DEPRECATE
_CRT_SECURE_NO_WARNINGS
_WINSOCK_DEPRECATED_NO_WARNINGS

8.清理项目,重新生成,成功在Debug目录下得到静态库文件。
在这里插入图片描述

rtmpdump的使用

1.建立一个testlibrtmp控制台工程,根据使用的编程语言进行选择,这里我选用的是C++控制台应用。
在这里插入图片描述
2.将rtmp.hamf.h文件添加到当前工程目录下,并添加到项目的头文件中。
在这里插入图片描述
3.将librtmp.lib文件添加到当前工程目录下,打开项目→属性→配置属性→链接器→常规,在附加库目录中添加librtmp.lib所在的路径。
在这里插入图片描述
打开项目→属性→配置属性→链接器→输入,在附加依赖项中添加librtmp.lib的文件名。
在这里插入图片描述
4.在控制台工程main函数所在的源文件中,添加以下代码。

注意!下面的语句一定要加上!!

#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include "rtmp.h"
#pragma comment(lib,"librtmp.lib")

testlibrtmp.cpp中的完整代码:

#include <iostream>
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include "rtmp.h"
#pragma comment(lib,"librtmp.lib")

int InitSockets()
{
	WORD version;
	WSADATA wsaData;
	version = MAKEWORD(1, 1);
	return (WSAStartup(version, &wsaData) == 0);
}

void CleanupSockets()
{
	WSACleanup();
}

int main()
{
	InitSockets();
	RTMP rtmp = { 0 };
	RTMP_Init(&rtmp);
	rtmp.Link.timeout = 25;//超时设置
	//由于crtmpserver是每个一段时间(默认8s)发送数据包,需大于发送间隔才行
	bool bLiveStream = true;//是否直播
	if (bLiveStream)
	{
		const char* str = "rtmp://58.200.131.2:1935/livetv/startv";
		RTMP_SetupURL(&rtmp, (char*)str);
		//设置直播标志
		rtmp.Link.lFlags |= RTMP_LF_LIVE;
	}
	else
	{
		const char* str = "rtmp://127.0.0.1:1935/vod/test.flv";
		RTMP_SetupURL(&rtmp, (char*)str);
	}
	RTMP_SetBufferMS(&rtmp, 3600 * 1000);//1hour
	if (!RTMP_Connect(&rtmp, NULL))
	{
		printf("Connect Server Err\n");
		WSACleanup();
		return -1;
	}
	if (!RTMP_ConnectStream(&rtmp, 0))
	{
		printf("Connect stream Err\n");
		RTMP_Close(&rtmp);
		WSACleanup();
		return -1;
	}
	int buffsize = 1024 * 1024 * 10;
	char* buff = (char*)malloc(buffsize);
	double duration = -1;
	int nRead;
	FILE* fp = fopen("aaa.flv", "wb");
	long  countbuffsize = 0;
	//它直接输出的就是FLV文件,包括FLV头,可对流按照flv格式解析就可提前音频,视频数据
	while (nRead = RTMP_Read(&rtmp, buff, buffsize))
	{
		fwrite(buff, 1, nRead, fp);
		if (!bLiveStream && duration < 0)
		{
			duration = RTMP_GetDuration(&rtmp);
			printf("duration:%f\n", duration);
		}
		countbuffsize += nRead;
		printf("\rdownland...:%0.2fkB", countbuffsize * 1.0 / 1024);
	}
	fclose(fp);
	free(buff);
	buff = NULL;
	RTMP_Close(&rtmp);
	WSACleanup();
	return 0;
}

5.运行程序,会得到下载并录制下来的flv文件。
在这里插入图片描述
6.点击播放,音画正常,成功。在这里插入图片描述

【参考出处】
librtmp在windows下的编译和使用
使用VS2008 在windows环境 编译Rtmpdump
rtmpdump在vs2015下的编译
VS引用第三方静态库的方法总结
Visual Studio 2017 项目中引用lib静态库
librtmp windows编译提示“无法解析的外部符号 _netstackdump”错误
“error C4996: ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead” 解决方法

【源码下载】
rtmpdump【包含编译librtmp.lib所需的所有头文件和源文件】
librtmp【包含编译好的librtmp.lib以及通过编译头文件和源文件】
testlibrtmp【包含用于测试将rtmp流媒体保存到本地的可执行文件】

注意:要正确使用以上的代码,一定要记得在vs的预处理器中添加上文提到的宏定义,否则将会报错。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值